diff --git a/agent/reports/ticket_by_client_v2.php b/agent/reports/ticket_by_client_v2.php new file mode 100644 index 00000000..25e5c864 --- /dev/null +++ b/agent/reports/ticket_by_client_v2.php @@ -0,0 +1,279 @@ + 24h by using hours > 24) + */ +function secondsToHmsString($seconds) { + $seconds = (int) max(0, $seconds); + $hours = intdiv($seconds, 3600); + $minutes = intdiv($seconds % 3600, 60); + $secs = $seconds % 60; + return sprintf('%02d:%02d:%02d', $hours, $minutes, $secs); +} + +/** + * 15-minute round up, return decimal hours in 0.25 increments + * Examples: + * 1 min => 0.25 + * 16 min => 0.50 + * 61 min => 1.25 + */ +function secondsToQuarterHourDecimal($seconds) { + $seconds = (int) max(0, $seconds); + if ($seconds === 0) return 0.00; + + $quarters = (int) ceil($seconds / 900); // 900 seconds = 15 minutes + return $quarters * 0.25; +} + +$year = isset($_GET['year']) ? (int) $_GET['year'] : (int) date('Y'); +$month = isset($_GET['month']) ? (int) $_GET['month'] : (int) date('m'); +if ($month < 1 || $month > 12) $month = (int) date('m'); + +$billable_only = (isset($_GET['billable_only']) && (int) $_GET['billable_only'] === 1) ? 1 : 0; + +// Used for Year dropdown +$sql_ticket_years = mysqli_query($mysqli, "SELECT DISTINCT YEAR(ticket_created_at) AS ticket_year FROM tickets ORDER BY ticket_year DESC"); + +// Billable filter (adjust field name if yours differs) +$billable_sql = $billable_only ? " AND t.ticket_billable = 1 " : ""; + +/** + * IMPORTANT: + * This sums time worked ONLY for replies within the selected month/year + * by filtering on tr.ticket_reply_created_at. + * If your column name differs, replace ticket_reply_created_at accordingly. + */ +$stmt = $mysqli->prepare(" + SELECT + c.client_id, + c.client_name, + t.ticket_id, + t.ticket_prefix, + t.ticket_number, + t.ticket_subject, + SEC_TO_TIME(COALESCE(SUM(TIME_TO_SEC(tr.ticket_reply_time_worked)), 0)) AS ticket_time_hms, + COALESCE(SUM(TIME_TO_SEC(tr.ticket_reply_time_worked)), 0) AS ticket_time_seconds + FROM tickets t + INNER JOIN clients c + ON c.client_id = t.ticket_client_id + LEFT JOIN ticket_replies tr + ON tr.ticket_reply_ticket_id = t.ticket_id + AND tr.ticket_reply_time_worked IS NOT NULL + AND YEAR(tr.ticket_reply_created_at) = ? + AND MONTH(tr.ticket_reply_created_at) = ? + WHERE c.client_archived_at IS NULL + $billable_sql + GROUP BY t.ticket_id + HAVING ticket_time_seconds > 0 + ORDER BY c.client_name ASC, t.ticket_number ASC, t.ticket_id ASC +"); +$stmt->bind_param("ii", $year, $month); +$stmt->execute(); +$result = $stmt->get_result(); + +?> + +
+
+

+ + Ticket By Client () + + Billable Only + +

+
+ +
+
+ +
+ + +
+
+
+ + +
+ +
+ + +
+ +
+
+ + > + +
+
+ +
+ +
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TicketTime WorkedBillable (hrs)
+ Total for ( tickets) +
No tickets with time worked found for this month.
+ Total for ( tickets) +
+ Grand Total ( tickets) +
+ + + Billed hours are calculated per ticket by rounding that ticket’s worked time up to the nearest 15 minutes (0.25 hours). + +
+
+ +