mirror of
https://github.com/itflow-org/itflow
synced 2026-09-21 14:11:17 +00:00
Roll SLA email targets up to business days, escape priority, validate priority in the tickets API
This commit is contained in:
@@ -27,7 +27,15 @@ if (isset($_POST['ticket_subject'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (isset($_POST['ticket_priority'])) {
|
// Priority has to be one of the four the rest of the app is built around:
|
||||||
|
// sla_assignments are keyed on these exact strings, and the ticket list and
|
||||||
|
// kanban both fall through to the Low styling for anything else, so an
|
||||||
|
// unrecognised value silently reads as the lowest priority everywhere.
|
||||||
|
// Anything else is normalised away rather than rejected, matching how this
|
||||||
|
// model already handles a non-integer client_id.
|
||||||
|
$allowed_priorities = ['Low', 'Medium', 'High', 'Urgent'];
|
||||||
|
|
||||||
|
if (isset($_POST['ticket_priority']) && in_array($_POST['ticket_priority'], $allowed_priorities, true)) {
|
||||||
$priority = escapeSql($_POST['ticket_priority']);
|
$priority = escapeSql($_POST['ticket_priority']);
|
||||||
} elseif ($ticket_row) {
|
} elseif ($ticket_row) {
|
||||||
$priority = mysqli_real_escape_string($mysqli, $ticket_row['ticket_priority']);
|
$priority = mysqli_real_escape_string($mysqli, $ticket_row['ticket_priority']);
|
||||||
|
|||||||
@@ -425,10 +425,18 @@ function applyTicketSla($ticket_id, $forced_sla_id = null)
|
|||||||
syncTicketSlaClock($ticket_id);
|
syncTicketSlaClock($ticket_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Human-readable SLA target, e.g. "2 business hours" or "45 minutes". The
|
// Human-readable SLA target, e.g. "45 minutes", "4 business hours" or
|
||||||
// "business" qualifier is dropped when no business calendar is configured,
|
// "3 business days". The "business" qualifier is dropped when no business
|
||||||
// because addBusinessMinutes runs 24x7 in that case and the promise would
|
// calendar is configured, because addBusinessMinutes runs 24x7 in that case
|
||||||
// otherwise be misleading. The condition mirrors that function's own guard.
|
// and the promise would otherwise be misleading. The condition mirrors that
|
||||||
|
// function's own guard.
|
||||||
|
//
|
||||||
|
// Anything at or over one business day rolls up to days: with 9-5 hours a
|
||||||
|
// 1440-minute target is three working days, but "24 business hours" reads to
|
||||||
|
// a client as tomorrow. The exact deadline always travels next to this text
|
||||||
|
// in the email, so the wording only has to give the right impression - a
|
||||||
|
// remainder under five minutes is dropped rather than rendering the likes of
|
||||||
|
// "1 business hour 1 minute".
|
||||||
function formatSlaMinutes($minutes)
|
function formatSlaMinutes($minutes)
|
||||||
{
|
{
|
||||||
$minutes = intval($minutes);
|
$minutes = intval($minutes);
|
||||||
@@ -438,20 +446,37 @@ function formatSlaMinutes($minutes)
|
|||||||
$day_end = $sla_settings['business_hours_end'];
|
$day_end = $sla_settings['business_hours_end'];
|
||||||
|
|
||||||
$qualifier = '';
|
$qualifier = '';
|
||||||
|
$day_minutes = 1440;
|
||||||
if (!empty($sla_settings['business_days']) && !empty($day_start) && !empty($day_end) && $day_start < $day_end) {
|
if (!empty($sla_settings['business_days']) && !empty($day_start) && !empty($day_end) && $day_start < $day_end) {
|
||||||
$qualifier = 'business ';
|
$qualifier = 'business ';
|
||||||
|
$working_minutes = intval((strtotime($day_end) - strtotime($day_start)) / 60);
|
||||||
|
if ($working_minutes > 0) {
|
||||||
|
$day_minutes = $working_minutes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($minutes < 60) {
|
if ($minutes < 60) {
|
||||||
return $minutes . ' minute' . ($minutes == 1 ? '' : 's');
|
return $minutes . ' minute' . ($minutes == 1 ? '' : 's');
|
||||||
}
|
}
|
||||||
|
|
||||||
$hours = intdiv($minutes, 60);
|
if ($minutes < $day_minutes) {
|
||||||
$remainder = $minutes % 60;
|
$hours = intdiv($minutes, 60);
|
||||||
|
$remainder = $minutes % 60;
|
||||||
|
|
||||||
$text = $hours . ' ' . $qualifier . 'hour' . ($hours == 1 ? '' : 's');
|
$text = $hours . ' ' . $qualifier . 'hour' . ($hours == 1 ? '' : 's');
|
||||||
if ($remainder > 0) {
|
if ($remainder >= 5) {
|
||||||
$text .= ' ' . $remainder . ' minute' . ($remainder == 1 ? '' : 's');
|
$text .= ' ' . $remainder . ' minutes';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $text;
|
||||||
|
}
|
||||||
|
|
||||||
|
$days = intdiv($minutes, $day_minutes);
|
||||||
|
$hours = intdiv($minutes % $day_minutes, 60);
|
||||||
|
|
||||||
|
$text = $days . ' ' . $qualifier . 'day' . ($days == 1 ? '' : 's');
|
||||||
|
if ($hours > 0) {
|
||||||
|
$text .= ' ' . $hours . ' hour' . ($hours == 1 ? '' : 's');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $text;
|
return $text;
|
||||||
@@ -488,7 +513,9 @@ function getTicketSlaEmailNotice($ticket_id, $company_phone = '')
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$priority = $row['ticket_priority'];
|
// The only value in this notice that comes from the database rather than a
|
||||||
|
// literal - escaped so the quote-free guarantee above holds for it too
|
||||||
|
$priority = escapeHtml($row['ticket_priority']);
|
||||||
$target = formatSlaMinutes($response_minutes);
|
$target = formatSlaMinutes($response_minutes);
|
||||||
$due = date('D j M, g:i A', strtotime($row['ticket_response_due_at']));
|
$due = date('D j M, g:i A', strtotime($row['ticket_response_due_at']));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user