0, CASE WHEN ticket_first_response_at IS NULL THEN ticket_response_due_at ELSE ticket_resolution_due_at END, NULL), '9999-12-31'))"; $sort_sql = [ 'ticket_number' => "ticket_number $order", 'ticket_subject' => "ticket_subject $order, ticket_number DESC", 'client_name' => "client_name $order, ticket_number DESC", 'contact_name' => "contact_name $order, ticket_number DESC", 'ticket_billable' => "ticket_invoice_id > 0 $order, ticket_billable $order, ticket_number DESC", 'ticket_priority' => "CASE ticket_priority WHEN 'Urgent' THEN 0 WHEN 'High' THEN 1 WHEN 'Medium' THEN 2 WHEN 'Low' THEN 3 ELSE 4 END $order, ticket_number DESC", 'ticket_status' => "ticket_status_order $order, ticket_status $order, ticket_number DESC", 'user_name' => "ticket_assigned_to = 0 $order, user_name $order, ticket_number DESC", 'ticket_updated_at' => "COALESCE(ticket_updated_at, ticket_created_at) $order", 'ticket_created_at' => "ticket_created_at $order", 'ticket_sla' => "(NOT " . TICKET_OPEN_SQL . " OR (ticket_due_at IS NULL AND ticket_sla_id = 0)) ASC, CASE WHEN (ticket_sla_id > 0 AND $ticket_stage_sql = 2) OR ticket_due_at < NOW() THEN 0 WHEN COALESCE(ticket_status_pauses_sla, 0) = 1 THEN 3 WHEN ticket_sla_id > 0 AND $ticket_stage_sql = 1 THEN 1 ELSE 2 END $order, $ticket_next_due_sql $order, ticket_number DESC", ]; if (!isset($sort_sql[$sort])) { $sort = 'ticket_number'; } $sql = mysqli_query($mysqli, "SELECT SQL_CALC_FOUND_ROWS $ticket_select_columns FROM tickets $ticket_joins $ticket_where ORDER BY {$sort_sql[$sort]} LIMIT $record_from, $record_to" ); $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); // The page first, then the last reply and the tasks for all of it in two queries $tickets = []; while ($row = mysqli_fetch_assoc($sql)) { $tickets[intval($row['ticket_id'])] = $row; } $last_replies = ticketLastReplies(array_keys($tickets)); $tickets_tags = tagsForRecords('ticket', array_keys($tickets)); $task_counts = ticketTaskCounts(array_keys($tickets)); // A Due column only when there is something to put in it $show_due = $sla_in_use || mysqli_num_rows(mysqli_query($mysqli, "SELECT 1 FROM tickets WHERE ticket_due_at IS NOT NULL AND ticket_closed_at IS NULL LIMIT 1")); $sort_link = function ($column, $label, $class = '') use ($url_query_strings_sort, $sort, $disp, $order_icon) { return '' . $label . ($sort === $column ? " $order_icon" : '') . ''; }; ?>
text-nowrap table-light"> $row) { $row_client_id = intval($row['ticket_client_id']); $reference = escapeHtml(ticketReference($row)); $subject = escapeHtml($row['ticket_subject']); $url = escapeHtml(ticketUrl($ticket_id, $row_client_id)); $is_open = ticketIsOpen($row); $is_closed = !empty($row['ticket_closed_at']); $mine = intval($row['ticket_assigned_to']) === intval($session_user_id); $move = ticketWhoseMove($row); $sla = ticketSlaState($row); $due = ticketDueState($row); $attention = $is_open ? ticketAttention($sla, $due) : ''; $schedule = $row['ticket_schedule']; $scheduled_today = $schedule && substr($schedule, 0, 10) === date('Y-m-d'); $ticket_invoice_id = intval($row['ticket_invoice_id']); $ticket_quote_id = intval($row['ticket_quote_id']); $row_title = ['danger' => $sla['key'] === 'breached' ? 'SLA breached' : 'Past its due date', 'warning' => $sla['key'] === 'at_risk' ? 'SLA at risk' : 'Due within a day'][$attention] ?? ''; ?> ">
/
>
') ?>
Internal
-
With client
' . $due_html . '' : '-' ?> Invoiced Quoted
'tickets', 'icon' => 'fa-life-ring', 'filtered' => $q !== '' || $active_filters || $assigned_filter !== '' || $client_filter, 'views' => ['show', 'view'], 'view' => $show === 'open' ? ['title' => 'No open tickets', 'text' => 'Nothing is waiting to be worked on.', 'icon' => 'fa-check'] : emptyStatePill($shows, $show), 'text' => 'Tickets come in by email and from the client portal, or add one here.', 'actions' => $can_edit ? [['label' => 'New Ticket', 'modal' => "modals/ticket/ticket_add.php?$client_url", 'size' => 'lg']] : [], ]; require_once "../includes/filter_footer.php"; ?>