mirror of
https://github.com/itflow-org/itflow
synced 2026-08-05 07:07:14 +00:00
Add optional ticket SLAs
Response/resolution targets stamped at creation from per-client/priority assignments, business-hours due date math, warn/breach alert stages via cron/ticket_sla.php, ticket list coloring, per-ticket SLA override, admin page for plans/assignments/business hours. DB update 2.5.0. No behavior change unless SLAs are assigned. Bulk reply now only counts Public replies as first response.
This commit is contained in:
70
agent/modals/ticket/ticket_sla.php
Normal file
70
agent/modals/ticket/ticket_sla.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
enforceUserPermission('module_support', 2);
|
||||
|
||||
$ticket_id = intval($_GET['id']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM tickets
|
||||
LEFT JOIN clients ON client_id = ticket_client_id
|
||||
WHERE ticket_id = $ticket_id
|
||||
LIMIT 1"
|
||||
);
|
||||
|
||||
$row = mysqli_fetch_assoc($sql);
|
||||
$ticket_prefix = escapeHtml($row['ticket_prefix']);
|
||||
$ticket_number = intval($row['ticket_number']);
|
||||
$ticket_sla_id = intval($row['ticket_sla_id']);
|
||||
$client_id = intval($row['ticket_client_id']);
|
||||
|
||||
if ($client_id) {
|
||||
enforceClientAccess();
|
||||
}
|
||||
|
||||
$sql_slas = mysqli_query($mysqli, "SELECT sla_id, sla_name FROM slas WHERE sla_archived_at IS NULL ORDER BY sla_name ASC");
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-stopwatch mr-2"></i>Editing SLA: <strong><?= "$ticket_prefix$ticket_number" ?></strong></h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||
<input type="hidden" name="ticket_id" value="<?= $ticket_id ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>SLA</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-stopwatch"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="sla_id" required>
|
||||
<option value="0" <?php if ($ticket_sla_id == 0) { echo "selected"; } ?>>None</option>
|
||||
<?php while ($sla_row = mysqli_fetch_assoc($sql_slas)) { ?>
|
||||
<option value="<?= intval($sla_row['sla_id']) ?>" <?php if ($ticket_sla_id == intval($sla_row['sla_id'])) { echo "selected"; } ?>><?= escapeHtml($sla_row['sla_name']) ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
<small class="text-muted">Response and resolution targets are recalculated from the ticket's creation time.</small>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="edit_ticket_sla" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
@@ -844,6 +844,7 @@ if (isset($_POST['bulk_add_client_ticket'])) {
|
||||
mysqli_query($mysqli, "INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_category = $category_id, ticket_subject = '$subject', ticket_details = '$details', ticket_priority = '$priority', ticket_billable = $billable, ticket_status = $ticket_status, ticket_created_by = $session_user_id, ticket_assigned_to = $assigned_to, ticket_url_key = '$url_key', ticket_client_id = $client_id, ticket_project_id = $project_id");
|
||||
|
||||
$ticket_id = mysqli_insert_id($mysqli);
|
||||
applyTicketSla($ticket_id);
|
||||
|
||||
// Add Tasks
|
||||
if (!empty($_POST['tasks'])) {
|
||||
|
||||
@@ -70,6 +70,7 @@ if (isset($_POST['add_project'])) {
|
||||
mysqli_query($mysqli, "INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_subject = '$ticket_template_subject', ticket_details = '$ticket_template_details', ticket_priority = 'Low', ticket_status = 1, ticket_created_by = $session_user_id, ticket_client_id = $client_id, ticket_project_id = $project_id");
|
||||
|
||||
$ticket_id = mysqli_insert_id($mysqli);
|
||||
applyTicketSla($ticket_id);
|
||||
|
||||
// Task Templates for Ticket template and add the to the ticket
|
||||
$sql_task_templates = mysqli_query($mysqli,
|
||||
|
||||
@@ -131,6 +131,7 @@ if (isset($_POST['bulk_force_recurring_tickets'])) {
|
||||
// Raise the ticket
|
||||
mysqli_query($mysqli, "INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_source = 'Recurring', ticket_subject = '$subject', ticket_details = '$details', ticket_priority = '$priority', ticket_status = '$ticket_status', ticket_billable = $billable, ticket_url_key = '$url_key', ticket_created_by = $created_id, ticket_assigned_to = $assigned_id, ticket_contact_id = $contact_id, ticket_client_id = $client_id, ticket_asset_id = $asset_id, ticket_category = $category, ticket_recurring_ticket_id = $recurring_ticket_id");
|
||||
$id = mysqli_insert_id($mysqli);
|
||||
applyTicketSla($id);
|
||||
|
||||
// Copy Additional Assets from Recurring ticket to new ticket
|
||||
mysqli_query($mysqli, "INSERT INTO ticket_assets (ticket_id, asset_id)
|
||||
@@ -271,6 +272,7 @@ if (isset($_GET['force_recurring_ticket'])) {
|
||||
// Raise the ticket
|
||||
mysqli_query($mysqli, "INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_source = 'Recurring', ticket_subject = '$subject', ticket_details = '$details', ticket_priority = '$priority', ticket_status = '$ticket_status', ticket_billable = $billable, ticket_url_key = '$url_key', ticket_created_by = $created_id, ticket_assigned_to = $assigned_id, ticket_contact_id = $contact_id, ticket_client_id = $client_id, ticket_asset_id = $asset_id, ticket_category = $category, ticket_recurring_ticket_id = $recurring_ticket_id");
|
||||
$id = mysqli_insert_id($mysqli);
|
||||
applyTicketSla($id);
|
||||
|
||||
// Copy Additional Assets from Recurring ticket to new ticket
|
||||
mysqli_query($mysqli, "INSERT INTO ticket_assets (ticket_id, asset_id)
|
||||
|
||||
@@ -77,6 +77,7 @@ if (isset($_POST['add_ticket'])) {
|
||||
mysqli_query($mysqli, "INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_source = 'Agent', ticket_category = $category_id, ticket_subject = '$subject', ticket_details = '$details', ticket_priority = '$priority', ticket_billable = '$billable', ticket_status = '$ticket_status', ticket_vendor_ticket_number = '$vendor_ticket_number', ticket_vendor_id = $vendor_id, ticket_location_id = $location_id, ticket_asset_id = $asset_id, ticket_created_by = $session_user_id, ticket_assigned_to = $assigned_to, ticket_contact_id = $contact_id, ticket_url_key = '$url_key', ticket_due_at = $due, ticket_client_id = $client_id, ticket_invoice_id = 0, ticket_project_id = $project_id");
|
||||
|
||||
$ticket_id = mysqli_insert_id($mysqli);
|
||||
applyTicketSla($ticket_id);
|
||||
|
||||
// Add Tasks from Template if Template was selected
|
||||
if($ticket_template_id) {
|
||||
@@ -237,6 +238,7 @@ if (isset($_POST['edit_ticket'])) {
|
||||
}
|
||||
|
||||
mysqli_query($mysqli, "UPDATE tickets SET ticket_category = $category_id, ticket_subject = '$ticket_subject', ticket_priority = '$ticket_priority', ticket_billable = $billable, ticket_details = '$details', ticket_due_at = $due, ticket_vendor_ticket_number = '$vendor_ticket_number', ticket_contact_id = $contact_id, ticket_assigned_to = $assigned_to, ticket_vendor_id = $vendor_id, ticket_location_id = $location_id, ticket_asset_id = $asset_id, ticket_project_id = $project_id WHERE ticket_id = $ticket_id");
|
||||
applyTicketSla($ticket_id);
|
||||
|
||||
// Add Additional Assets
|
||||
if (isset($_POST['additional_assets'])) {
|
||||
@@ -343,6 +345,7 @@ if (isset($_POST['edit_ticket_priority'])) {
|
||||
}
|
||||
|
||||
mysqli_query($mysqli, "UPDATE tickets SET ticket_priority = '$priority' WHERE ticket_id = $ticket_id");
|
||||
applyTicketSla($ticket_id);
|
||||
|
||||
// Update Ticket History
|
||||
mysqli_query($mysqli, "INSERT INTO ticket_history SET ticket_history_status = '$ticket_status', ticket_history_description = '$session_name changed priority from $original_priority to $priority', ticket_history_ticket_id = $ticket_id");
|
||||
@@ -357,6 +360,66 @@ if (isset($_POST['edit_ticket_priority'])) {
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['edit_ticket_sla'])) {
|
||||
|
||||
validateCSRFToken();
|
||||
|
||||
enforceUserPermission('module_support', 2);
|
||||
|
||||
$ticket_id = intval($_POST['ticket_id']);
|
||||
$sla_id = intval($_POST['sla_id']);
|
||||
|
||||
// Get ticket details before updating
|
||||
$sql = mysqli_query($mysqli, "SELECT
|
||||
ticket_prefix, ticket_number, ticket_sla_id, ticket_status_name, ticket_client_id
|
||||
FROM tickets
|
||||
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
|
||||
WHERE ticket_id = $ticket_id"
|
||||
);
|
||||
$row = mysqli_fetch_assoc($sql);
|
||||
$ticket_prefix = escapeSql($row['ticket_prefix']);
|
||||
$ticket_number = intval($row['ticket_number']);
|
||||
$original_sla_id = intval($row['ticket_sla_id']);
|
||||
$ticket_status = escapeSql($row['ticket_status_name']);
|
||||
$client_id = intval($row['ticket_client_id']);
|
||||
|
||||
// Don't Enforce Client Access if Ticket doesn't have an assigned client
|
||||
if ($client_id) {
|
||||
enforceClientAccess();
|
||||
}
|
||||
|
||||
// Look up SLA names for the history/audit trail (0 = None)
|
||||
$original_sla_name = "None";
|
||||
if ($original_sla_id) {
|
||||
$sla_sql = mysqli_query($mysqli, "SELECT sla_name FROM slas WHERE sla_id = $original_sla_id");
|
||||
if (mysqli_num_rows($sla_sql)) {
|
||||
$original_sla_name = escapeSql(mysqli_fetch_assoc($sla_sql)['sla_name']);
|
||||
}
|
||||
}
|
||||
$sla_name = "None";
|
||||
if ($sla_id) {
|
||||
$sla_sql = mysqli_query($mysqli, "SELECT sla_name FROM slas WHERE sla_id = $sla_id");
|
||||
if (mysqli_num_rows($sla_sql)) {
|
||||
$sla_name = escapeSql(mysqli_fetch_assoc($sla_sql)['sla_name']);
|
||||
}
|
||||
}
|
||||
|
||||
// Pin the ticket to the chosen SLA and recompute its targets
|
||||
applyTicketSla($ticket_id, $sla_id);
|
||||
|
||||
// Update Ticket History
|
||||
mysqli_query($mysqli, "INSERT INTO ticket_history SET ticket_history_status = '$ticket_status', ticket_history_description = '$session_name changed SLA from $original_sla_name to $sla_name', ticket_history_ticket_id = $ticket_id");
|
||||
|
||||
logAudit("Ticket", "Edit", "$session_name changed SLA from $original_sla_name to $sla_name for ticket $ticket_prefix$ticket_number", $client_id, $ticket_id);
|
||||
|
||||
triggerCustomAction('ticket_update', $ticket_id);
|
||||
|
||||
flashAlert("SLA updated from <strong>$original_sla_name</strong> to <strong>$sla_name</strong>");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['edit_ticket_contact'])) {
|
||||
|
||||
validateCSRFToken();
|
||||
@@ -1091,6 +1154,7 @@ if (isset($_POST['bulk_edit_ticket_priority'])) {
|
||||
|
||||
// Update ticket & insert reply
|
||||
mysqli_query($mysqli, "UPDATE tickets SET ticket_priority = '$priority' WHERE ticket_id = $ticket_id");
|
||||
applyTicketSla($ticket_id);
|
||||
|
||||
mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = '$session_name updated the priority from $current_ticket_priority to $priority', ticket_reply_type = 'Internal', ticket_reply_time_worked = '00:01:00', ticket_reply_by = $session_user_id, ticket_reply_ticket_id = $ticket_id");
|
||||
|
||||
@@ -1208,10 +1272,11 @@ if (isset($_POST['bulk_merge_tickets'])) {
|
||||
|
||||
// Update current ticket
|
||||
if (empty($ticket_first_response_at)) {
|
||||
mysqli_query($mysqli, "UPDATE tickets SET ticket_first_response_at = NOW() WHERE ticket_id = $ticket_id");
|
||||
setTicketFirstResponse($ticket_id);
|
||||
}
|
||||
mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = 'Ticket $ticket_prefix$ticket_number bulk merged into <a href=\"ticket.php?ticket_id=$merge_into_ticket_id\">$ticket_prefix$merge_into_ticket_number</a>. Comment: $merge_comment', ticket_reply_time_worked = '00:01:00', ticket_reply_type = '$ticket_reply_type', ticket_reply_by = $session_user_id, ticket_reply_ticket_id = $ticket_id");
|
||||
mysqli_query($mysqli, "UPDATE tickets SET ticket_status = '5', ticket_resolved_at = NOW(), ticket_closed_at = NOW(), ticket_closed_by = $session_user_id WHERE ticket_id = $ticket_id") or die(mysqli_error($mysqli));
|
||||
setTicketResolutionSlaMet($ticket_id);
|
||||
|
||||
// Update new parent ticket
|
||||
mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = 'Ticket $ticket_prefix$ticket_number was bulk merged into this ticket with comment: $merge_comment.<br><br><b>$ticket_subject</b><br>$ticket_details', ticket_reply_time_worked = '00:01:00', ticket_reply_type = 'Internal', ticket_reply_by = $session_user_id, ticket_reply_ticket_id = $merge_into_ticket_id");
|
||||
@@ -1286,11 +1351,12 @@ if (isset($_POST['bulk_resolve_tickets'])) {
|
||||
|
||||
// Mark FR time if required
|
||||
if (empty($ticket_first_response_at)) {
|
||||
mysqli_query($mysqli, "UPDATE tickets SET ticket_first_response_at = NOW() WHERE ticket_id = $ticket_id");
|
||||
setTicketFirstResponse($ticket_id);
|
||||
}
|
||||
|
||||
// Update ticket & insert reply
|
||||
mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 4, ticket_resolved_at = NOW() WHERE ticket_id = $ticket_id");
|
||||
setTicketResolutionSlaMet($ticket_id);
|
||||
|
||||
mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = '$details', ticket_reply_type = '$ticket_reply_type', ticket_reply_time_worked = '$ticket_reply_time_worked', ticket_reply_by = $session_user_id, ticket_reply_ticket_id = $ticket_id");
|
||||
|
||||
@@ -1426,9 +1492,9 @@ if (isset($_POST['bulk_ticket_reply'])) {
|
||||
$client_uri = '';
|
||||
}
|
||||
|
||||
// Mark FR time if required
|
||||
if (empty($ticket_first_response_at)) {
|
||||
mysqli_query($mysqli, "UPDATE tickets SET ticket_first_response_at = NOW() WHERE ticket_id = $ticket_id");
|
||||
// Mark FR time if required - internal notes don't count as a response
|
||||
if (empty($ticket_first_response_at) && $ticket_reply_type == 'Public') {
|
||||
setTicketFirstResponse($ticket_id);
|
||||
}
|
||||
|
||||
// Add reply
|
||||
@@ -1451,6 +1517,7 @@ if (isset($_POST['bulk_ticket_reply'])) {
|
||||
// Resolve the ticket, if set
|
||||
if ($ticket_status == 4) {
|
||||
mysqli_query($mysqli, "UPDATE tickets SET ticket_resolved_at = NOW() WHERE ticket_id = $ticket_id");
|
||||
setTicketResolutionSlaMet($ticket_id);
|
||||
|
||||
// Logging
|
||||
logAudit("Ticket", "Resolved", "$session_name resolved Ticket $ticket_prefix$ticket_number", $client_id, $ticket_id);
|
||||
@@ -1684,6 +1751,7 @@ if (isset($_POST['bulk_add_asset_ticket'])) {
|
||||
mysqli_query($mysqli, "INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_category = $category_id, ticket_subject = '$subject_asset_prepended', ticket_details = '$details', ticket_priority = '$priority', ticket_billable = $billable, ticket_status = $ticket_status, ticket_asset_id = $asset_id, ticket_created_by = $session_user_id, ticket_assigned_to = $assigned_to, ticket_url_key = '$url_key', ticket_client_id = $client_id, ticket_project_id = $project_id");
|
||||
|
||||
$ticket_id = mysqli_insert_id($mysqli);
|
||||
applyTicketSla($ticket_id);
|
||||
|
||||
// Add Tasks
|
||||
if (!empty($_POST['tasks'])) {
|
||||
@@ -1769,6 +1837,7 @@ if (isset($_POST['add_ticket_reply'])) {
|
||||
// Resolve the ticket, if set
|
||||
if ($ticket_status == 4) {
|
||||
mysqli_query($mysqli, "UPDATE tickets SET ticket_resolved_at = NOW() WHERE ticket_id = $ticket_id");
|
||||
setTicketResolutionSlaMet($ticket_id);
|
||||
|
||||
logAudit("Ticket", "Resolved", "$session_name resolved Ticket ticket ID $ticket_id", $client_id, $ticket_id);
|
||||
}
|
||||
@@ -1885,7 +1954,7 @@ if (isset($_POST['add_ticket_reply'])) {
|
||||
|
||||
// Handle first response
|
||||
if (empty($ticket_first_response_at) && $ticket_reply_type == 'Public') {
|
||||
mysqli_query($mysqli, "UPDATE tickets SET ticket_first_response_at = NOW() WHERE ticket_id = $ticket_id");
|
||||
setTicketFirstResponse($ticket_id);
|
||||
}
|
||||
|
||||
// Custom action/notif handler
|
||||
@@ -2059,12 +2128,13 @@ if (isset($_POST['merge_ticket'])) {
|
||||
|
||||
// Update current ticket
|
||||
if (empty($ticket_first_response_at)) {
|
||||
mysqli_query($mysqli, "UPDATE tickets SET ticket_first_response_at = NOW() WHERE ticket_id = $ticket_id");
|
||||
setTicketFirstResponse($ticket_id);
|
||||
}
|
||||
|
||||
mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = 'Ticket $ticket_prefix$ticket_number merged into <a href=\"ticket.php?ticket_id=$merge_into_ticket_id\">$ticket_prefix$merge_into_ticket_number</a>. Comment: $merge_comment', ticket_reply_time_worked = '00:01:00', ticket_reply_type = '$ticket_reply_type', ticket_reply_by = $session_user_id, ticket_reply_ticket_id = $ticket_id");
|
||||
|
||||
mysqli_query($mysqli, "UPDATE tickets SET ticket_status = '5', ticket_resolved_at = NOW(), ticket_closed_at = NOW(), ticket_closed_by = $session_user_id WHERE ticket_id = $ticket_id") or die(mysqli_error($mysqli));
|
||||
setTicketResolutionSlaMet($ticket_id);
|
||||
|
||||
//Update new parent ticket
|
||||
mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = 'Ticket $ticket_prefix$ticket_number was merged into this ticket with comment: $merge_comment.<br><br><b>$ticket_subject</b><br>$ticket_details', ticket_reply_time_worked = '00:01:00', ticket_reply_type = '$ticket_reply_type', ticket_reply_by = $session_user_id, ticket_reply_ticket_id = $merge_into_ticket_id");
|
||||
@@ -2101,6 +2171,7 @@ if (isset($_POST['change_client_ticket'])) {
|
||||
|
||||
// Update ticket client & contact
|
||||
mysqli_query($mysqli, "UPDATE tickets SET ticket_client_id = $client_id, ticket_contact_id = $contact_id WHERE ticket_id = $ticket_id LIMIT 1");
|
||||
applyTicketSla($ticket_id);
|
||||
|
||||
logAudit("Ticket", "Change", "$session_name changed ticket client", $client_id, $ticket_id);
|
||||
|
||||
@@ -2134,11 +2205,12 @@ if (isset($_GET['resolve_ticket'])) {
|
||||
|
||||
// Mark FR
|
||||
if (empty($ticket_first_response_at)) {
|
||||
mysqli_query($mysqli, "UPDATE tickets SET ticket_first_response_at = NOW() WHERE ticket_id = $ticket_id");
|
||||
setTicketFirstResponse($ticket_id);
|
||||
}
|
||||
|
||||
// Resolve
|
||||
mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 4, ticket_resolved_at = NOW() WHERE ticket_id = $ticket_id");
|
||||
setTicketResolutionSlaMet($ticket_id);
|
||||
|
||||
logAudit("Ticket", "Resolved", "$session_name resolved ticket $ticket_prefix$ticket_number (ID: $ticket_id)", $client_id, $ticket_id);
|
||||
|
||||
@@ -2239,6 +2311,7 @@ if (isset($_GET['close_ticket'])) {
|
||||
}
|
||||
|
||||
mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 5, ticket_closed_at = NOW(), ticket_closed_by = $session_user_id WHERE ticket_id = $ticket_id") or die(mysqli_error($mysqli));
|
||||
setTicketResolutionSlaMet($ticket_id);
|
||||
|
||||
mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = 'Ticket closed.', ticket_reply_type = 'Internal', ticket_reply_time_worked = '00:01:00', ticket_reply_by = $session_user_id, ticket_reply_ticket_id = $ticket_id");
|
||||
|
||||
@@ -2339,6 +2412,7 @@ if (isset($_GET['reopen_ticket'])) {
|
||||
}
|
||||
|
||||
mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 2, ticket_resolved_at = NULL WHERE ticket_id = $ticket_id");
|
||||
resetTicketResolutionSla($ticket_id);
|
||||
|
||||
logAudit("Ticket", "Reopened", "$session_name reopened ticket ID $ticket_id", $client_id, $ticket_id);
|
||||
|
||||
|
||||
@@ -110,6 +110,18 @@ if (isset($_GET['ticket_id'])) {
|
||||
$ticket_updated_at = escapeHtml($row['ticket_updated_at']);
|
||||
$ticket_updated_at_ago = timeAgo($row['ticket_updated_at']);
|
||||
$ticket_first_response_at = escapeHtml($row['ticket_first_response_at']);
|
||||
$ticket_sla_id = intval($row['ticket_sla_id']);
|
||||
$ticket_response_due_at = escapeHtml($row['ticket_response_due_at']);
|
||||
$ticket_resolution_due_at = escapeHtml($row['ticket_resolution_due_at']);
|
||||
$ticket_response_sla_met = $row['ticket_response_sla_met'];
|
||||
$ticket_resolution_sla_met = $row['ticket_resolution_sla_met'];
|
||||
$ticket_sla_name = "None";
|
||||
if ($ticket_sla_id) {
|
||||
$sla_name_sql = mysqli_query($mysqli, "SELECT sla_name FROM slas WHERE sla_id = $ticket_sla_id");
|
||||
if (mysqli_num_rows($sla_name_sql)) {
|
||||
$ticket_sla_name = escapeHtml(mysqli_fetch_assoc($sla_name_sql)['sla_name']);
|
||||
}
|
||||
}
|
||||
$ticket_resolved_at = escapeHtml($row['ticket_resolved_at']);
|
||||
$ticket_resolved_at_ago = timeAgo($row['ticket_resolved_at']);
|
||||
$ticket_resolved_date = date('Y-m-d', strtotime($ticket_resolved_at));
|
||||
@@ -488,6 +500,16 @@ if (isset($_GET['ticket_id'])) {
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="mt-1">
|
||||
<i class="fa fa-fw fa-stopwatch text-secondary mr-2"></i>SLA:
|
||||
<a href="#" title="SLA"
|
||||
<?php if (lookupUserPermission("module_support") >= 2 && empty($ticket_closed_at)) { ?>
|
||||
class="ajax-modal"
|
||||
data-modal-url="modals/ticket/ticket_sla.php?id=<?= $ticket_id ?>"
|
||||
<?php } ?>
|
||||
><?= $ticket_sla_name ?></a>
|
||||
</div>
|
||||
|
||||
<!-- Ticket scheduling -->
|
||||
<?php if (empty ($ticket_closed_at)) { ?>
|
||||
<div class="mt-1">
|
||||
@@ -878,6 +900,20 @@ if (isset($_GET['ticket_id'])) {
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<!-- SLA targets (stamped at creation by applyTicketSla) -->
|
||||
<?php if ($ticket_sla_id && $ticket_response_due_at) { ?>
|
||||
<div class="mt-2">
|
||||
<i class="fas fa-fw fa-stopwatch text-secondary mr-1"></i><strong class="mr-1">Respond by:</strong><?= date('M d • g:i A', strtotime($ticket_response_due_at)) ?>
|
||||
<?php if (!is_null($ticket_response_sla_met)) { echo $ticket_response_sla_met ? "<i class='fas fa-fw fa-check text-success ml-1' title='Response SLA met'></i>" : "<i class='fas fa-fw fa-exclamation-triangle text-danger ml-1' title='Response SLA missed'></i>"; } ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
<?php if ($ticket_sla_id && $ticket_resolution_due_at) { ?>
|
||||
<div class="mt-2">
|
||||
<i class="fas fa-fw fa-flag-checkered text-secondary mr-1"></i><strong class="mr-1">Resolve by:</strong><?= date('M d • g:i A', strtotime($ticket_resolution_due_at)) ?>
|
||||
<?php if (!is_null($ticket_resolution_sla_met)) { echo $ticket_resolution_sla_met ? "<i class='fas fa-fw fa-check text-success ml-1' title='Resolution SLA met'></i>" : "<i class='fas fa-fw fa-exclamation-triangle text-danger ml-1' title='Resolution SLA missed'></i>"; } ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<!-- Time tracking -->
|
||||
<?php if ($ticket_total_reply_time) { ?>
|
||||
<div class="mt-2">
|
||||
|
||||
@@ -90,6 +90,8 @@
|
||||
$ticket_updated_at = escapeHtml($row['ticket_updated_at']);
|
||||
$ticket_updated_at_time_ago = timeAgo($row['ticket_updated_at']);
|
||||
$ticket_closed_at = escapeHtml($row['ticket_closed_at']);
|
||||
// SLA alert stages are maintained by cron/ticket_sla.php (1 = warned, 2 = breached)
|
||||
$ticket_sla_alert_stage = max(intval($row['ticket_response_sla_alert_stage']), intval($row['ticket_resolution_sla_alert_stage']));
|
||||
if (empty($ticket_updated_at)) {
|
||||
if (!empty($ticket_closed_at)) {
|
||||
$ticket_updated_at_display = "<p>Never</p>";
|
||||
@@ -192,7 +194,7 @@
|
||||
|
||||
?>
|
||||
|
||||
<tr class="<?php if(empty($ticket_closed_at) && empty($ticket_updated_at)) { echo "text-bold"; }?> <?php if (empty($ticket_closed_at) && $ticket_reply_type == "Client") { echo "table-warning"; } ?>">
|
||||
<tr class="<?php if(empty($ticket_closed_at) && empty($ticket_updated_at)) { echo "text-bold"; }?> <?php if (empty($ticket_closed_at) && $ticket_sla_alert_stage == 2) { echo "table-danger"; } elseif (empty($ticket_closed_at) && ($ticket_reply_type == "Client" || $ticket_sla_alert_stage == 1)) { echo "table-warning"; } ?>">
|
||||
|
||||
<td class="checkbox-column">
|
||||
<!-- Ticket Bulk Select (for open tickets) -->
|
||||
|
||||
Reference in New Issue
Block a user