mirror of
https://github.com/itflow-org/itflow
synced 2026-08-28 02:15:13 +00:00
Add SLA response target to ticket created emails, with a call-in note on High and Urgent
This commit is contained in:
@@ -190,7 +190,9 @@ if (isset($_POST['bulk_force_recurring_tickets'])) {
|
||||
if (!empty($config_smtp_provider) && $config_ticket_client_general_notifications == 1 && filter_var($contact_email, FILTER_VALIDATE_EMAIL)) {
|
||||
|
||||
$email_subject = "Ticket Created - [$ticket_prefix$ticket_number] - $ticket_subject (scheduled)";
|
||||
$email_body = "<i style=\'color: #808080\'>##- Please type your reply above this line -##</i><br><br>Hello $contact_name,<br><br>A ticket regarding \"$ticket_subject\" has been automatically created for you.<br><br>--------------------------------<br>$ticket_details--------------------------------<br><br>Ticket: $ticket_prefix$ticket_number<br>Subject: $ticket_subject<br>Status: Open<br>Portal: https://$config_base_url/client/ticket.php?id=$id<br><br>--<br>$company_name - Support<br>$config_ticket_from_email<br>$company_phone";
|
||||
// SLA response commitment for this client + priority, empty when no SLA applies
|
||||
$sla_notice = escapeSql(getTicketSlaEmailNotice($id, $company_phone));
|
||||
$email_body = "<i style=\'color: #808080\'>##- Please type your reply above this line -##</i><br><br>Hello $contact_name,<br><br>A ticket regarding \"$ticket_subject\" has been automatically created for you.<br><br>--------------------------------<br>$ticket_details--------------------------------<br><br>Ticket: $ticket_prefix$ticket_number<br>Subject: $ticket_subject<br>Status: Open<br>Portal: https://$config_base_url/client/ticket.php?id=$id$sla_notice<br><br>--<br>$company_name - Support<br>$config_ticket_from_email<br>$company_phone";
|
||||
|
||||
$email = [
|
||||
'from' => $config_ticket_from_email,
|
||||
@@ -337,7 +339,9 @@ if (isset($_GET['force_recurring_ticket'])) {
|
||||
if (!empty($config_smtp_provider) && $config_ticket_client_general_notifications == 1 && filter_var($contact_email, FILTER_VALIDATE_EMAIL)) {
|
||||
|
||||
$email_subject = "Ticket created - [$ticket_prefix$ticket_number] - $ticket_subject (scheduled)";
|
||||
$email_body = "<i style=\'color: #808080\'>##- Please type your reply above this line -##</i><br><br>Hello $contact_name,<br><br>A ticket regarding \"$ticket_subject\" has been automatically created for you.<br><br>--------------------------------<br>$ticket_details--------------------------------<br><br>Ticket: $ticket_prefix$ticket_number<br>Subject: $ticket_subject<br>Status: Open<br>Portal: https://$config_base_url/client/ticket.php?id=$id<br><br>--<br>$company_name - Support<br>$config_ticket_from_email<br>$company_phone";
|
||||
// SLA response commitment for this client + priority, empty when no SLA applies
|
||||
$sla_notice = escapeSql(getTicketSlaEmailNotice($id, $company_phone));
|
||||
$email_body = "<i style=\'color: #808080\'>##- Please type your reply above this line -##</i><br><br>Hello $contact_name,<br><br>A ticket regarding \"$ticket_subject\" has been automatically created for you.<br><br>--------------------------------<br>$ticket_details--------------------------------<br><br>Ticket: $ticket_prefix$ticket_number<br>Subject: $ticket_subject<br>Status: Open<br>Portal: https://$config_base_url/client/ticket.php?id=$id$sla_notice<br><br>--<br>$company_name - Support<br>$config_ticket_from_email<br>$company_phone";
|
||||
|
||||
$email = [
|
||||
'from' => $config_ticket_from_email,
|
||||
|
||||
@@ -140,7 +140,9 @@ if (isset($_POST['add_ticket'])) {
|
||||
// EMAILING
|
||||
|
||||
$subject = "Ticket Created [$ticket_prefix$ticket_number] - $ticket_subject";
|
||||
$body = "<i style=\'color: #808080\'>##- Please type your reply above this line -##</i><br><br>Hello $contact_name,<br><br>A ticket regarding \"$ticket_subject\" has been created for you.<br><br>--------------------------------<br>$ticket_details--------------------------------<br><br>Ticket: $ticket_prefix$ticket_number<br>Subject: $ticket_subject<br>Status: Open<br>Portal: <a href=\'https://$config_base_url/guest/guest_view_ticket.php?ticket_id=$ticket_id&url_key=$url_key\'>View ticket</a><br><br>--<br>$company_name - Support<br>$config_ticket_from_email<br>$company_phone";
|
||||
// SLA response commitment for this client + priority, empty when no SLA applies
|
||||
$sla_notice = escapeSql(getTicketSlaEmailNotice($ticket_id, $company_phone));
|
||||
$body = "<i style=\'color: #808080\'>##- Please type your reply above this line -##</i><br><br>Hello $contact_name,<br><br>A ticket regarding \"$ticket_subject\" has been created for you.<br><br>--------------------------------<br>$ticket_details--------------------------------<br><br>Ticket: $ticket_prefix$ticket_number<br>Subject: $ticket_subject<br>Status: Open<br>Portal: <a href=\'https://$config_base_url/guest/guest_view_ticket.php?ticket_id=$ticket_id&url_key=$url_key\'>View ticket</a>$sla_notice<br><br>--<br>$company_name - Support<br>$config_ticket_from_email<br>$company_phone";
|
||||
|
||||
// Verify contact email is valid
|
||||
if (filter_var($contact_email, FILTER_VALIDATE_EMAIL)) {
|
||||
@@ -315,7 +317,9 @@ if (isset($_POST['edit_ticket'])) {
|
||||
$data = []; // Queue array
|
||||
|
||||
$subject = "Ticket Created - [$ticket_prefix$ticket_number] - $ticket_subject";
|
||||
$body = "<i style=\'color: #808080\'>##- Please type your reply above this line -##</i><br><br>Hello $contact_name,<br><br>A ticket regarding \"$ticket_subject\" has been created for you.<br><br>--------------------------------<br>$ticket_details--------------------------------<br><br>Ticket: $ticket_prefix$ticket_number<br>Subject: $ticket_subject<br>Status: $ticket_status<br>Portal: <a href=\'https://$config_base_url/guest/guest_view_ticket.php?ticket_id=$ticket_id&url_key=$url_key\'>View ticket</a><br><br>--<br>$company_name - Support<br>$config_ticket_from_email<br>$company_phone";
|
||||
// SLA response commitment for this client + priority, empty when no SLA applies
|
||||
$sla_notice = escapeSql(getTicketSlaEmailNotice($ticket_id, $company_phone));
|
||||
$body = "<i style=\'color: #808080\'>##- Please type your reply above this line -##</i><br><br>Hello $contact_name,<br><br>A ticket regarding \"$ticket_subject\" has been created for you.<br><br>--------------------------------<br>$ticket_details--------------------------------<br><br>Ticket: $ticket_prefix$ticket_number<br>Subject: $ticket_subject<br>Status: $ticket_status<br>Portal: <a href=\'https://$config_base_url/guest/guest_view_ticket.php?ticket_id=$ticket_id&url_key=$url_key\'>View ticket</a>$sla_notice<br><br>--<br>$company_name - Support<br>$config_ticket_from_email<br>$company_phone";
|
||||
|
||||
|
||||
// Only add contact to email queue if email is valid
|
||||
@@ -511,7 +515,9 @@ if (isset($_POST['edit_ticket_contact'])) {
|
||||
$data = []; // Queue array
|
||||
|
||||
$subject = "Ticket Created - [$ticket_prefix$ticket_number] - $ticket_subject";
|
||||
$body = "<i style=\'color: #808080\'>##- Please type your reply above this line -##</i><br><br>Hello $contact_name,<br><br>A ticket regarding \"$ticket_subject\" has been created for you.<br><br>--------------------------------<br>$ticket_details--------------------------------<br><br>Ticket: $ticket_prefix$ticket_number<br>Subject: $ticket_subject<br>Status: $ticket_status<br>Portal: <a href=\'https://$config_base_url/guest/guest_view_ticket.php?ticket_id=$ticket_id&url_key=$url_key\'>View ticket</a><br><br>--<br>$company_name - Support<br>$config_ticket_from_email<br>$company_phone";
|
||||
// SLA response commitment for this client + priority, empty when no SLA applies
|
||||
$sla_notice = escapeSql(getTicketSlaEmailNotice($ticket_id, $company_phone));
|
||||
$body = "<i style=\'color: #808080\'>##- Please type your reply above this line -##</i><br><br>Hello $contact_name,<br><br>A ticket regarding \"$ticket_subject\" has been created for you.<br><br>--------------------------------<br>$ticket_details--------------------------------<br><br>Ticket: $ticket_prefix$ticket_number<br>Subject: $ticket_subject<br>Status: $ticket_status<br>Portal: <a href=\'https://$config_base_url/guest/guest_view_ticket.php?ticket_id=$ticket_id&url_key=$url_key\'>View ticket</a>$sla_notice<br><br>--<br>$company_name - Support<br>$config_ticket_from_email<br>$company_phone";
|
||||
|
||||
$data[] = [
|
||||
'from' => $config_ticket_from_email,
|
||||
|
||||
@@ -717,7 +717,7 @@ if (isset($_GET['ticket_id'])) {
|
||||
|
||||
<!-- Who will see this reply, stated in the label rather than left to a colour -->
|
||||
<div class="btn-group w-100 mb-3" role="group">
|
||||
<input class="btn-check" id="public_reply_type_opt0" type="radio" name="public_reply_type" value="0" checked>
|
||||
<input class="btn-check" id="public_reply_type_opt0" type="radio" name="public_reply_type" value="0">
|
||||
<label class="btn btn-outline-dark" for="public_reply_type_opt0"><i class="fas fa-fw fa-lock me-1"></i>Internal note</label>
|
||||
<input class="btn-check" id="public_reply_type_opt1" type="radio" name="public_reply_type" value="1" checked>
|
||||
<label class="btn btn-outline-info" for="public_reply_type_opt1"><i class="fas fa-fw fa-comment me-1"></i>Public reply</label>
|
||||
|
||||
@@ -441,7 +441,9 @@ if (mysqli_num_rows($sql_recurring_tickets) > 0) {
|
||||
if (!empty($config_smtp_provider) && $config_ticket_client_general_notifications == 1 && filter_var($contact_email, FILTER_VALIDATE_EMAIL)) {
|
||||
|
||||
$email_subject = "Ticket created - [$ticket_prefix$ticket_number] - $ticket_subject (scheduled)";
|
||||
$email_body = "<i style=\'color: #808080\'>##- Please type your reply above this line -##</i><br><br>Hello $contact_name,<br><br>A ticket regarding \"$ticket_subject\" has been automatically created for you.<br><br>--------------------------------<br>$ticket_details--------------------------------<br><br>Ticket: $ticket_prefix$ticket_number<br>Subject: $ticket_subject<br>Status: Open<br>Portal: https://$config_base_url/client/ticket.php?id=$id<br><br>--<br>$company_name - Support<br>$config_ticket_from_email<br>$company_phone";
|
||||
// SLA response commitment for this client + priority, empty when no SLA applies
|
||||
$sla_notice = escapeSql(getTicketSlaEmailNotice($id, $company_phone));
|
||||
$email_body = "<i style=\'color: #808080\'>##- Please type your reply above this line -##</i><br><br>Hello $contact_name,<br><br>A ticket regarding \"$ticket_subject\" has been automatically created for you.<br><br>--------------------------------<br>$ticket_details--------------------------------<br><br>Ticket: $ticket_prefix$ticket_number<br>Subject: $ticket_subject<br>Status: Open<br>Portal: https://$config_base_url/client/ticket.php?id=$id$sla_notice<br><br>--<br>$company_name - Support<br>$config_ticket_from_email<br>$company_phone";
|
||||
|
||||
$email = [
|
||||
'from' => $config_ticket_from_email,
|
||||
|
||||
@@ -161,7 +161,9 @@ function addTicket($contact_id, $contact_name, $contact_email, $client_id, $date
|
||||
$data = [];
|
||||
if ($config_ticket_client_general_notifications == 1 && !preg_match($bad_pattern, $contact_email)) {
|
||||
$subject_email = "Ticket created - [$config_ticket_prefix$ticket_number] - $subject";
|
||||
$body = "<i style='color: #808080'>##- Please type your reply above this line -##</i><br><br>Hello $contact_name,<br><br>Thank you for your email. A ticket regarding \"$subject\" has been automatically created for you.<br><br>Ticket: $config_ticket_prefix$ticket_number<br>Subject: $subject<br>Status: New<br>Portal: <a href='https://$config_base_url/guest/guest_view_ticket.php?ticket_id=$id&url_key=$url_key'>View ticket</a><br><br>--<br>$company_name - Support<br>$config_ticket_from_email<br>$company_phone";
|
||||
// SLA response commitment for this client + priority, empty when no SLA applies
|
||||
$sla_notice = getTicketSlaEmailNotice($id, $company_phone);
|
||||
$body = "<i style='color: #808080'>##- Please type your reply above this line -##</i><br><br>Hello $contact_name,<br><br>Thank you for your email. A ticket regarding \"$subject\" has been automatically created for you.<br><br>Ticket: $config_ticket_prefix$ticket_number<br>Subject: $subject<br>Status: New<br>Portal: <a href='https://$config_base_url/guest/guest_view_ticket.php?ticket_id=$id&url_key=$url_key'>View ticket</a>$sla_notice<br><br>--<br>$company_name - Support<br>$config_ticket_from_email<br>$company_phone";
|
||||
$data[] = [
|
||||
'from' => $config_ticket_from_email,
|
||||
'from_name' => $config_ticket_from_name,
|
||||
|
||||
@@ -425,6 +425,87 @@ function applyTicketSla($ticket_id, $forced_sla_id = null)
|
||||
syncTicketSlaClock($ticket_id);
|
||||
}
|
||||
|
||||
// Human-readable SLA target, e.g. "2 business hours" or "45 minutes". The
|
||||
// "business" qualifier is dropped when no business calendar is configured,
|
||||
// because addBusinessMinutes runs 24x7 in that case and the promise would
|
||||
// otherwise be misleading. The condition mirrors that function's own guard.
|
||||
function formatSlaMinutes($minutes)
|
||||
{
|
||||
$minutes = intval($minutes);
|
||||
|
||||
$sla_settings = getSlaSettings();
|
||||
$day_start = $sla_settings['business_hours_start'];
|
||||
$day_end = $sla_settings['business_hours_end'];
|
||||
|
||||
$qualifier = '';
|
||||
if (!empty($sla_settings['business_days']) && !empty($day_start) && !empty($day_end) && $day_start < $day_end) {
|
||||
$qualifier = 'business ';
|
||||
}
|
||||
|
||||
if ($minutes < 60) {
|
||||
return $minutes . ' minute' . ($minutes == 1 ? '' : 's');
|
||||
}
|
||||
|
||||
$hours = intdiv($minutes, 60);
|
||||
$remainder = $minutes % 60;
|
||||
|
||||
$text = $hours . ' ' . $qualifier . 'hour' . ($hours == 1 ? '' : 's');
|
||||
if ($remainder > 0) {
|
||||
$text .= ' ' . $remainder . ' minute' . ($remainder == 1 ? '' : 's');
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
// Client-facing SLA block for a "ticket created" email. Returns '' when no SLA
|
||||
// applies to the ticket or the plan carries no response target, so callers can
|
||||
// append it unconditionally.
|
||||
//
|
||||
// Call this AFTER applyTicketSla(), which is what stamps ticket_response_due_at.
|
||||
//
|
||||
// The returned HTML deliberately contains NO single or double quotes. Most of
|
||||
// these email bodies are assembled pre-escaped and handed to addToMailQueue,
|
||||
// which interpolates the body straight into its INSERT without escaping it, so
|
||||
// a stray quote here would break the query at those call sites.
|
||||
function getTicketSlaEmailNotice($ticket_id, $company_phone = '')
|
||||
{
|
||||
global $mysqli;
|
||||
|
||||
$ticket_id = intval($ticket_id);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT ticket_priority, ticket_response_due_at, sla_response_minutes
|
||||
FROM tickets
|
||||
LEFT JOIN slas ON ticket_sla_id = sla_id
|
||||
WHERE ticket_id = $ticket_id LIMIT 1");
|
||||
if (!$sql || !mysqli_num_rows($sql)) {
|
||||
return '';
|
||||
}
|
||||
$row = mysqli_fetch_assoc($sql);
|
||||
|
||||
$response_minutes = intval($row['sla_response_minutes']);
|
||||
|
||||
if (empty($row['ticket_response_due_at']) || $response_minutes <= 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$priority = $row['ticket_priority'];
|
||||
$target = formatSlaMinutes($response_minutes);
|
||||
$due = date('D j M, g:i A', strtotime($row['ticket_response_due_at']));
|
||||
|
||||
$notice = "<br><br>Priority: $priority<br>Target response: within $target (by $due)";
|
||||
|
||||
// Higher priorities get told to phone rather than sit on an email thread
|
||||
if (!empty($company_phone) && ($priority == 'Urgent' || $priority == 'High')) {
|
||||
if ($priority == 'Urgent') {
|
||||
$notice .= "<br><br><strong>This ticket is marked Urgent.</strong> If the issue is stopping work right now, please call us on $company_phone rather than waiting for a reply to this email.";
|
||||
} else {
|
||||
$notice .= "<br><br><strong>This ticket is marked High priority.</strong> If it is business-impacting, calling us on $company_phone will get you the fastest response.";
|
||||
}
|
||||
}
|
||||
|
||||
return $notice;
|
||||
}
|
||||
|
||||
// Record the ticket's first response (if not already recorded) and judge the
|
||||
// response SLA against the stored due date. Replaces the previous inline
|
||||
// ticket_first_response_at updates so the SLA verdict can never drift from
|
||||
|
||||
Reference in New Issue
Block a user