' . escapeHtml(ticketReference($row)) . ' is closed - nothing more goes on it.', 'error'); redirect(); } // What the window showed, cleaned again - it came back from the page $note = trim(documentHtmlPurify((string) ($_POST['note'] ?? ''))); if (trim(strip_tags($note)) === '') { flashAlert('There was no summary to save - ask for it again.', 'error'); redirect(); } $note = mysqli_real_escape_string($mysqli, '

AI summary

' . $note); mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = '$note', ticket_reply_type = 'Internal', ticket_reply_time_worked = '00:00:00', ticket_reply_by = $session_user_id, ticket_reply_ticket_id = $ticket_id"); mysqli_query($mysqli, "UPDATE tickets SET ticket_updated_at = NOW() WHERE ticket_id = $ticket_id"); logAudit("Ticket", "Reply", "$session_name saved an AI summary as an internal note on ticket " . escapeSql(ticketReference($row)), $client_id, $ticket_id); flashAlert('Summary saved as an internal note on ' . escapeHtml(ticketReference($row)) . ''); redirect(); } // Triage with AI, from the ticket's menu - what it suggests shows on the ticket, to apply or dismiss if (isset($_GET['triage_ticket_ai'])) { validateCSRFToken(); $row = ticketForRequest($_GET['triage_ticket_ai'], 2); if (!aiCan()) { permissionRefuse(permissionRefusedText('module_ai', 1, 0)); } $result = aiTicketTriage(intval($row['ticket_id'])); if (!$result['ok']) { flashAlert('AI triage didn\'t work - ' . escapeHtml($result['error']), 'error'); redirect(); } $changes = aiTriageChanges($result['triage'], $row); flashAlert($changes ? 'AI triage suggests a ' . escapeHtml(implode(' and a ', array_keys($changes))) . ' - apply it or dismiss it on the ticket' : 'AI triage agrees with the category and priority it has', 'info'); redirect(); } // Apply what AI triage suggests - or dismiss it if (isset($_POST['apply_ticket_ai_triage']) || isset($_POST['dismiss_ticket_ai_triage'])) { validateCSRFToken(); $row = ticketForRequest($_POST['ticket_id'] ?? 0, 2); $ticket_id = intval($row['ticket_id']); $triage = aiTriageRow($ticket_id); if (!$triage || $triage['ai_triage_state'] !== 'suggested') { flashAlert('There is no AI triage waiting on this ticket.', 'info'); redirect(); } if (isset($_POST['dismiss_ticket_ai_triage'])) { mysqli_query($mysqli, "UPDATE ai_ticket_triage SET ai_triage_state = 'dismissed', ai_triage_by = $session_user_id WHERE ai_triage_ticket_id = $ticket_id"); flashAlert('AI triage dismissed', 'info'); redirect(); } if (!ticketIsOpen($row)) { flashAlert('Ticket ' . escapeHtml(ticketReference($row)) . ' isn\'t open - reopen it to change it.', 'error'); redirect(); } // Those ticked - both, without the window's script $only = array_values(array_intersect((array) ($_POST['apply'] ?? ['category', 'priority']), ['category', 'priority'])); $changes = aiTriageApply($ticket_id, stripslashes($session_name), $only, 'applied', $session_user_id); if (!$changes) { flashAlert('Nothing to change - the ticket has that already', 'info'); redirect(); } $said = []; foreach ($changes as $field => $change) { $said[] = ucfirst($field) . ' ' . escapeHtml($change[1]) . ''; } flashAlert(implode(' and ', $said) . ' set on ' . escapeHtml(ticketReference($row)) . ''); redirect(); }