Fix some Ticket History gaps

This commit is contained in:
johnnyq
2026-08-01 14:33:37 -04:00
parent cdb4a43b89
commit 75028ba09a
11 changed files with 163 additions and 10 deletions

View File

@@ -216,10 +216,21 @@ if (isset($_GET['disable_user'])) {
mysqli_query($mysqli, "UPDATE users SET user_status = 0 WHERE user_id = $user_id");
// Un-assign tickets
// Un-assign tickets. Collect them first so each one gets a history entry -
// otherwise a whole queue silently goes unassigned with nothing to explain it
$affected_ticket_ids = array();
$sql_affected_tickets = mysqli_query($mysqli, "SELECT ticket_id FROM tickets WHERE ticket_assigned_to = $user_id AND ticket_closed_at IS NULL");
while ($affected_ticket_row = mysqli_fetch_assoc($sql_affected_tickets)) {
$affected_ticket_ids[] = intval($affected_ticket_row['ticket_id']);
}
mysqli_query($mysqli, "UPDATE tickets SET ticket_assigned_to = 0 WHERE ticket_assigned_to = $user_id AND ticket_closed_at IS NULL");
mysqli_query($mysqli, "UPDATE recurring_tickets SET recurring_ticket_assigned_to = 0 WHERE recurring_ticket_assigned_to = $user_id");
foreach ($affected_ticket_ids as $affected_ticket_id) {
logTicketHistory($affected_ticket_id, "$session_name unassigned the ticket when $user_name was disabled");
}
logAudit("User", "Disable", "$session_name disabled user $name", 0, $user_id);
flashAlert("User <strong>$user_name</strong> disabled", 'error');
@@ -256,10 +267,26 @@ if (isset($_POST['archive_user'])) {
$user_name = escapeSql(getFieldById('users', $user_id, 'user_name'));
// Un-assign / Re-assign tickets
// Un-assign / Re-assign tickets. Same as above - collect them first so the
// move shows up on each ticket's history
$affected_ticket_ids = array();
$sql_affected_tickets = mysqli_query($mysqli, "SELECT ticket_id FROM tickets WHERE ticket_assigned_to = $user_id AND ticket_closed_at IS NULL AND ticket_resolved_at IS NULL");
while ($affected_ticket_row = mysqli_fetch_assoc($sql_affected_tickets)) {
$affected_ticket_ids[] = intval($affected_ticket_row['ticket_id']);
}
mysqli_query($mysqli, "UPDATE tickets SET ticket_assigned_to = $ticket_assign WHERE ticket_assigned_to = $user_id AND ticket_closed_at IS NULL AND ticket_resolved_at IS NULL");
mysqli_query($mysqli, "UPDATE recurring_tickets SET recurring_ticket_assigned_to = $ticket_assign WHERE recurring_ticket_assigned_to = $user_id");
$reassigned_to_name = $ticket_assign ? escapeSql(getFieldById('users', $ticket_assign, 'user_name', 'raw')) : '';
foreach ($affected_ticket_ids as $affected_ticket_id) {
if ($reassigned_to_name) {
logTicketHistory($affected_ticket_id, "$session_name reassigned the ticket to $reassigned_to_name when $user_name was archived");
} else {
logTicketHistory($affected_ticket_id, "$session_name unassigned the ticket when $user_name was archived");
}
}
// Archive user query
mysqli_query($mysqli, "UPDATE users SET user_name = '$user_name (archived)', user_password = '$password', user_status = 0, user_specific_encryption_ciphertext = '', user_archived_at = NOW() WHERE user_id = $user_id");

View File

@@ -545,6 +545,8 @@ if (isset($_POST['update_kanban_ticket'])) {
mysqli_query($mysqli, "UPDATE tickets SET ticket_order = $kanban, ticket_status = $status, ticket_resolved_at = NULL WHERE ticket_id = $ticket_id");
resetTicketResolutionSla($ticket_id);
syncTicketSlaClock($ticket_id);
$new_status_name = getTicketStatusName($status, 'sql');
logTicketHistory($ticket_id, "$session_name reopened the ticket to $new_status_name from the kanban");
triggerCustomAction('ticket_update', $ticket_id);
} elseif ($status === $statuses['Resolved']) {
// If the ticket was moved to a resolved status, we need to update ticket_resolved_at
@@ -554,6 +556,7 @@ if (isset($_POST['update_kanban_ticket'])) {
setTicketFirstResponse($ticket_id);
setTicketResolutionSlaMet($ticket_id);
syncTicketSlaClock($ticket_id);
logTicketHistory($ticket_id, "$session_name resolved the ticket from the kanban");
triggerCustomAction('ticket_update', $ticket_id);
// Client notification email
@@ -635,6 +638,8 @@ if (isset($_POST['update_kanban_ticket'])) {
// If the ticket was moved from any status to another status
mysqli_query($mysqli, "UPDATE tickets SET ticket_order = $kanban, ticket_status = $status WHERE ticket_id = $ticket_id");
syncTicketSlaClock($ticket_id);
$new_status_name = getTicketStatusName($status, 'sql');
logTicketHistory($ticket_id, "$session_name set the status to $new_status_name from the kanban");
triggerCustomAction('ticket_update', $ticket_id);
}
}

View File

@@ -127,7 +127,7 @@ if (isset($_POST['add_ticket'])) {
$ticket_details = mysqli_escape_string($mysqli, $row['ticket_details']);
$ticket_priority = escapeSql($row['ticket_priority']);
$ticket_status = escapeSql($row['ticket_status']);
$ticket_status_name = escapeSql(getTicketStatusName($row['ticket_status']));
$ticket_status_name = getTicketStatusName($row['ticket_status'], 'sql');
$client_id = intval($row['ticket_client_id']);
$ticket_created_by = intval($row['ticket_created_by']);
$ticket_assigned_to = intval($row['ticket_assigned_to']);
@@ -245,9 +245,31 @@ if (isset($_POST['edit_ticket'])) {
enforceClientAccess();
}
/*
* The edit modal can change priority and assignment, which the dedicated
* priority and assign handlers record - so read the originals first and
* record the same changes when they come through here instead
*/
$original_row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT ticket_priority, ticket_assigned_to FROM tickets WHERE ticket_id = $ticket_id"));
$original_priority = escapeSql($original_row['ticket_priority']);
$original_assigned_to = intval($original_row['ticket_assigned_to']);
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);
if ($original_priority !== $ticket_priority) {
logTicketHistory($ticket_id, "$session_name changed priority from $original_priority to $ticket_priority");
}
if ($original_assigned_to !== $assigned_to) {
if ($assigned_to) {
$new_agent_name = escapeSql(getFieldById('users', $assigned_to, 'user_name', 'raw'));
logTicketHistory($ticket_id, "$session_name assigned the ticket to $new_agent_name");
} else {
logTicketHistory($ticket_id, "$session_name unassigned the ticket");
}
}
// Add Additional Assets
if (isset($_POST['additional_assets'])) {
mysqli_query($mysqli, "DELETE FROM ticket_assets WHERE ticket_id = $ticket_id");
@@ -875,6 +897,8 @@ if (isset($_POST['assign_ticket'])) {
mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = '$ticket_reply', ticket_reply_type = 'Internal', ticket_reply_time_worked = '00:01:00', ticket_reply_by = $session_user_id, ticket_reply_ticket_id = $ticket_id");
logTicketHistory($ticket_id, "$session_name assigned the ticket to $agent_name");
logAudit("Ticket", "Edit", "$session_name reassigned $ticket_prefix$ticket_number to $agent_name", $client_id, $ticket_id);
// Notification
@@ -1083,6 +1107,8 @@ if (isset($_POST['bulk_assign_ticket'])) {
mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = '$ticket_reply', ticket_reply_type = 'Internal', ticket_reply_time_worked = '00:01:00', ticket_reply_by = $session_user_id, ticket_reply_ticket_id = $ticket_id");
logTicketHistory($ticket_id, "$session_name assigned the ticket to $agent_name");
logAudit("Ticket", "Edit", "$session_name reassigned ticket $ticket_prefix$ticket_number to $agent_name", $client_id, $ticket_id);
triggerCustomAction('ticket_assign', $ticket_id);
@@ -1292,7 +1318,9 @@ if (isset($_POST['bulk_merge_tickets'])) {
// 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");
logAudit("Ticket", "Merged", "$session_name Merged ticket $ticket_prefix$ticket_number into $ticket_prefix$merge_into_ticket_number", $client_id, $ticket_id);
logTicketHistory($ticket_id, "$session_name merged this ticket into $ticket_prefix$merge_into_ticket_number and closed it");
logAudit("Ticket", "Merged", "$session_name Merged ticket $ticket_prefix$ticket_number into $ticket_prefix$merge_into_ticket_number", $client_id, $ticket_id);
// Custom action/notif handler
triggerCustomAction('ticket_merge', $ticket_id);
@@ -1372,6 +1400,8 @@ if (isset($_POST['bulk_resolve_tickets'])) {
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");
logTicketHistory($ticket_id, "$session_name resolved the ticket");
logAudit("Ticket", "Resolve", "$session_name resolved $ticket_prefix$ticket_number - $ticket_subject", $client_id, $ticket_id);
triggerCustomAction('ticket_resolve', $ticket_id);
@@ -1518,6 +1548,9 @@ if (isset($_POST['bulk_ticket_reply'])) {
mysqli_query($mysqli, "UPDATE tickets SET ticket_status = '$ticket_status' WHERE ticket_id = $ticket_id");
syncTicketSlaClock($ticket_id);
$new_status_name = getTicketStatusName($ticket_status, 'sql');
logTicketHistory($ticket_id, "$session_name set the status to $new_status_name");
logAudit("Ticket", "Reply", "$session_name replied to ticket $ticket_prefix$ticket_number - $ticket_subject and was a $ticket_reply_type reply", $client_id, $ticket_id);
// Custom action/notif handler
@@ -1533,6 +1566,8 @@ if (isset($_POST['bulk_ticket_reply'])) {
setTicketResolutionSlaMet($ticket_id);
// Logging
logTicketHistory($ticket_id, "$session_name resolved the ticket");
logAudit("Ticket", "Resolved", "$session_name resolved Ticket $ticket_prefix$ticket_number", $client_id, $ticket_id);
triggerCustomAction('ticket_resolve', $ticket_id);
@@ -1840,6 +1875,8 @@ if (isset($_POST['add_ticket_reply'])) {
mysqli_query($mysqli, "UPDATE tickets SET ticket_resolved_at = NOW() WHERE ticket_id = $ticket_id");
setTicketResolutionSlaMet($ticket_id);
logTicketHistory($ticket_id, "$session_name resolved the ticket");
logAudit("Ticket", "Resolved", "$session_name resolved Ticket ticket ID $ticket_id", $client_id, $ticket_id);
}
@@ -1995,6 +2032,9 @@ if (isset($_POST['add_ticket_reply'])) {
flashAlert("Stored on the ticket but too large to email: <strong>" . implode(', ', $skipped_names) . "</strong>", 'error');
}
$new_status_name = getTicketStatusName($ticket_status, 'sql');
logTicketHistory($ticket_id, "$session_name set the status to $new_status_name");
logAudit("Ticket", "Reply", "$session_name replied to ticket $ticket_prefix$ticket_number - $ticket_subject and was a $ticket_reply_type reply", $client_id, $ticket_id);
redirect();
@@ -2213,6 +2253,8 @@ if (isset($_POST['merge_ticket'])) {
mysqli_query($mysqli, "UPDATE tickets SET ticket_updated_at = NOW() WHERE ticket_id = $merge_into_ticket_id");
logTicketHistory($ticket_id, "$session_name merged this ticket into $ticket_prefix$merge_into_ticket_number and closed it");
logAudit("Ticket", "Merged", "$session_name Merged ticket $ticket_prefix$ticket_number into $ticket_prefix$merge_into_ticket_number");
triggerCustomAction('ticket_merge', $ticket_id);
@@ -2285,6 +2327,8 @@ if (isset($_GET['resolve_ticket'])) {
syncTicketSlaClock($ticket_id);
setTicketResolutionSlaMet($ticket_id);
logTicketHistory($ticket_id, "$session_name resolved the ticket");
logAudit("Ticket", "Resolved", "$session_name resolved ticket $ticket_prefix$ticket_number (ID: $ticket_id)", $client_id, $ticket_id);
triggerCustomAction('ticket_resolve', $ticket_id);
@@ -2389,6 +2433,8 @@ if (isset($_GET['close_ticket'])) {
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");
logTicketHistory($ticket_id, "$session_name closed the ticket");
logAudit("Ticket", "Closed", "$session_name closed ticket ID $ticket_id", $client_id, $ticket_id);
triggerCustomAction('ticket_close', $ticket_id);
@@ -2489,6 +2535,8 @@ if (isset($_GET['reopen_ticket'])) {
syncTicketSlaClock($ticket_id);
resetTicketResolutionSla($ticket_id);
logTicketHistory($ticket_id, "$session_name reopened the ticket");
logAudit("Ticket", "Reopened", "$session_name reopened ticket ID $ticket_id", $client_id, $ticket_id);
triggerCustomAction('ticket_update', $ticket_id);

View File

@@ -87,11 +87,16 @@ if (!empty($ticket_id) && !empty($reply)) {
if (!empty($reply_ticket_status)) {
mysqli_query($mysqli, "UPDATE tickets SET ticket_status = $reply_ticket_status WHERE ticket_id = $ticket_id LIMIT 1");
$new_status_name = getTicketStatusName($reply_ticket_status, 'sql');
logTicketHistory($ticket_id, "Status set to $new_status_name via the API ($api_key_name)");
// Resolve the ticket, if set
if ($reply_ticket_status == 4) {
mysqli_query($mysqli, "UPDATE tickets SET ticket_resolved_at = NOW() WHERE ticket_id = $ticket_id AND ticket_resolved_at IS NULL LIMIT 1");
setTicketResolutionSlaMet($ticket_id);
logTicketHistory($ticket_id, "Resolved via the API ($api_key_name)");
logAudit("Ticket", "Resolved", "Resolved ticket $ticket_prefix$ticket_number via API ($api_key_name)", $client_id, $ticket_id);
triggerCustomAction('ticket_resolve', $ticket_id);

View File

@@ -38,6 +38,8 @@ if (!empty($ticket_id)) {
$update_count = mysqli_affected_rows($mysqli);
// Logging
logTicketHistory($ticket_id, "Resolved via the API ($api_key_name)");
logAudit("Ticket", "Resolved", "$ticket_prefix$ticket_number ticket via API ($api_key_name)", $client_id, $ticket_id);
logAudit("API", "Success", "Resolved ticket $ticket_prefix$ticket_number via API ($api_key_name)", $client_id);
}

View File

@@ -107,6 +107,7 @@ if (isset($_POST['add_ticket_comment'])) {
// Update Ticket Last Response Field & set ticket to open as client has replied
mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 2 WHERE ticket_id = $ticket_id AND ticket_client_id = $session_client_id LIMIT 1");
syncTicketSlaClock($ticket_id);
logTicketHistory($ticket_id, "$session_contact_name replied from the client portal, reopening the ticket");
// Get ticket details & Notify the assigned tech (if any)
@@ -247,6 +248,7 @@ if (isset($_GET['resolve_ticket'])) {
mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 4, ticket_resolved_at = NOW() WHERE ticket_id = $ticket_id AND ticket_client_id = $session_client_id");
setTicketResolutionSlaMet($ticket_id);
syncTicketSlaClock($ticket_id);
logTicketHistory($ticket_id, "$session_contact_name resolved the ticket from the client portal");
// Add reply
mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = 'Ticket resolved by $session_contact_name.', ticket_reply_type = 'Client', ticket_reply_by = $session_contact_id, ticket_reply_ticket_id = $ticket_id");
@@ -284,6 +286,7 @@ if (isset($_GET['reopen_ticket'])) {
mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 2, ticket_resolved_at = NULL WHERE ticket_id = $ticket_id AND ticket_client_id = $session_client_id");
resetTicketResolutionSla($ticket_id);
syncTicketSlaClock($ticket_id);
logTicketHistory($ticket_id, "$session_contact_name reopened the ticket from the client portal");
// Add reply
mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = 'Ticket reopened by $session_contact_name.', ticket_reply_type = 'Client', ticket_reply_by = $session_contact_id, ticket_reply_ticket_id = $ticket_id");
@@ -320,6 +323,7 @@ if (isset($_GET['close_ticket'])) {
// Fully close ticket
mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 5, ticket_closed_at = NOW() WHERE ticket_id = $ticket_id AND ticket_client_id = $session_client_id");
syncTicketSlaClock($ticket_id);
logTicketHistory($ticket_id, "$session_contact_name closed the ticket from the client portal");
// Add reply
mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = 'Ticket closed by $session_contact_name.', ticket_reply_type = 'Client', ticket_reply_by = $session_contact_id, ticket_reply_ticket_id = $ticket_id");

View File

@@ -527,6 +527,8 @@ while ($row = mysqli_fetch_assoc($sql_resolved_tickets_to_close)) {
syncTicketSlaClock($ticket_id);
//Logging
logTicketHistory($ticket_id, "Automatically closed after $config_ticket_autoclose_hours hours with no activity");
logAudit("Ticket", "Closed", "$ticket_prefix$ticket_number auto closed", $client_id, $ticket_id);
triggerCustomAction('ticket_close', $ticket_id);

View File

@@ -350,6 +350,8 @@ function addReply($from_email, $date, $subject, $ticket_number, $message, $attac
mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 2, ticket_resolved_at = NULL WHERE ticket_id = $ticket_id AND ticket_client_id = $client_id LIMIT 1");
resetTicketResolutionSla($ticket_id);
logTicketHistory($ticket_id, "$from_email_esc replied by email, reopening the ticket");
logAudit("Ticket", "Edit", "Email parser: Client contact $from_email_esc updated ticket $config_ticket_prefix$ticket_number_esc ($subject)", $client_id, $ticket_id);
triggerCustomAction('ticket_reply_client', $ticket_id);
return true;

View File

@@ -55,19 +55,35 @@ function getInvoiceBadgeColor($invoice_status) {
return $invoice_badge_color;
}
function getTicketStatusName($ticket_status) {
/*
* The display name for a ticket status id.
*
* $escape_method follows getFieldById() - 'html' (the default, unchanged for
* existing callers), 'sql' for interpolating into a query, or 'raw'. The one
* caller that wanted SQL was wrapping this in escapeSql(), which escaped the
* already-HTML-escaped string and mangled names containing & or an apostrophe.
*/
function getTicketStatusName($ticket_status, $escape_method = 'html') {
global $mysqli;
$status_id = intval($ticket_status);
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT * FROM ticket_statuses WHERE ticket_status_id = $status_id LIMIT 1"));
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT ticket_status_name FROM ticket_statuses WHERE ticket_status_id = $status_id LIMIT 1"));
if ($row) {
return escapeHtml($row['ticket_status_name']);
if (!$row) {
// Default return
return "Unknown";
}
// Default return
return "Unknown";
if ($escape_method === 'sql') {
return escapeSql($row['ticket_status_name']);
}
if ($escape_method === 'raw') {
return $row['ticket_status_name'];
}
return escapeHtml($row['ticket_status_name']);
}

View File

@@ -55,6 +55,46 @@ function logAudit($type, $action, $description, $client_id = 0, $entity_id = 0)
mysqli_query($mysqli, "INSERT INTO logs SET log_type = '$type', log_action = '$action', log_description = '$description', log_ip = '$session_ip', log_user_agent = '$session_user_agent', log_client_id = $client_id, log_user_id = $session_user_id, log_entity_id = $entity_id");
}
/*
* Records a ticket history entry - the per-ticket change trail shown in the
* History card on agent/ticket.php.
*
* Follows the same convention as logAudit() above: the description is
* interpolated as-is, so callers pass values that are already SQL-safe.
*
* Call this AFTER the change has been written - the status stamped on the entry
* is whatever the ticket is in at the time of the call.
*/
function logTicketHistory($ticket_id, $description) {
global $mysqli;
$ticket_id = intval($ticket_id);
// ticket_history_description is varchar(255) and NOT NULL, so an over-long
// description would be an error under strict mode rather than a truncation
$description = substr($description, 0, 255);
// The description arrives already escaped, and cutting it at 255 can split a
// \' pair - the leftover backslash would escape this query's closing quote
$trailing_backslashes = strlen($description) - strlen(rtrim($description, '\\'));
if ($trailing_backslashes % 2 === 1) {
$description = substr($description, 0, -1);
}
$status_name = '';
$sql = mysqli_query(
$mysqli,
"SELECT ticket_status_name FROM tickets
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
WHERE ticket_id = $ticket_id"
);
if ($sql && mysqli_num_rows($sql)) {
$status_name = escapeSql(mysqli_fetch_assoc($sql)['ticket_status_name']);
}
mysqli_query($mysqli, "INSERT INTO ticket_history SET ticket_history_status = '$status_name', ticket_history_description = '$description', ticket_history_ticket_id = $ticket_id");
}
function logApp($category, $type, $details) {
global $mysqli;

View File

@@ -168,6 +168,7 @@ if (isset($_GET['reopen_ticket'], $_GET['url_key'])) {
if (mysqli_num_rows($sql) == 1) {
// Update the ticket
mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 2, ticket_resolved_at = NULL WHERE ticket_id = $ticket_id AND ticket_url_key = '$url_key'");
logTicketHistory($ticket_id, "The client reopened the ticket from the guest link");
// Add reply
mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = 'Ticket reopened by client (guest URL).', ticket_reply_type = 'Internal', ticket_reply_by = 0, ticket_reply_ticket_id = $ticket_id");
@@ -196,6 +197,7 @@ if (isset($_GET['close_ticket'], $_GET['url_key'])) {
// Update the ticket
mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 5, ticket_closed_at = NOW() WHERE ticket_id = $ticket_id AND ticket_url_key = '$url_key'");
logTicketHistory($ticket_id, "The client closed the ticket from the guest link");
// Add reply
mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = 'Ticket closed by client (guest URL).', ticket_reply_type = 'Internal', ticket_reply_by = 0, ticket_reply_ticket_id = $ticket_id");