From e02b10d12a2eb77c14ddf829991bcf0628be74e0 Mon Sep 17 00:00:00 2001 From: johnnyq Date: Wed, 29 Oct 2025 15:51:14 -0400 Subject: [PATCH] [Feature] Added Billable column in recurring ticket list view along with bulk actions to set priority, agent, billable status, category and next run date --- .../recurring_ticket_bulk_agent_edit.php | 46 ++++ .../recurring_ticket_bulk_billable_edit.php | 29 ++ .../recurring_ticket_bulk_category_edit.php | 42 +++ .../recurring_ticket_bulk_next_run_edit.php | 32 +++ .../recurring_ticket_bulk_priority_edit.php | 36 +++ agent/post/ticket.php | 248 ++++++++++++++++++ agent/recurring_tickets.php | 61 ++++- 7 files changed, 483 insertions(+), 11 deletions(-) create mode 100644 agent/modals/recurring_ticket/recurring_ticket_bulk_agent_edit.php create mode 100644 agent/modals/recurring_ticket/recurring_ticket_bulk_billable_edit.php create mode 100644 agent/modals/recurring_ticket/recurring_ticket_bulk_category_edit.php create mode 100644 agent/modals/recurring_ticket/recurring_ticket_bulk_next_run_edit.php create mode 100644 agent/modals/recurring_ticket/recurring_ticket_bulk_priority_edit.php diff --git a/agent/modals/recurring_ticket/recurring_ticket_bulk_agent_edit.php b/agent/modals/recurring_ticket/recurring_ticket_bulk_agent_edit.php new file mode 100644 index 00000000..eee8669f --- /dev/null +++ b/agent/modals/recurring_ticket/recurring_ticket_bulk_agent_edit.php @@ -0,0 +1,46 @@ + diff --git a/agent/modals/recurring_ticket/recurring_ticket_bulk_billable_edit.php b/agent/modals/recurring_ticket/recurring_ticket_bulk_billable_edit.php new file mode 100644 index 00000000..c67d6d43 --- /dev/null +++ b/agent/modals/recurring_ticket/recurring_ticket_bulk_billable_edit.php @@ -0,0 +1,29 @@ + diff --git a/agent/modals/recurring_ticket/recurring_ticket_bulk_category_edit.php b/agent/modals/recurring_ticket/recurring_ticket_bulk_category_edit.php new file mode 100644 index 00000000..729a9efe --- /dev/null +++ b/agent/modals/recurring_ticket/recurring_ticket_bulk_category_edit.php @@ -0,0 +1,42 @@ + diff --git a/agent/modals/recurring_ticket/recurring_ticket_bulk_next_run_edit.php b/agent/modals/recurring_ticket/recurring_ticket_bulk_next_run_edit.php new file mode 100644 index 00000000..e3dc782e --- /dev/null +++ b/agent/modals/recurring_ticket/recurring_ticket_bulk_next_run_edit.php @@ -0,0 +1,32 @@ + diff --git a/agent/modals/recurring_ticket/recurring_ticket_bulk_priority_edit.php b/agent/modals/recurring_ticket/recurring_ticket_bulk_priority_edit.php new file mode 100644 index 00000000..38f2ee70 --- /dev/null +++ b/agent/modals/recurring_ticket/recurring_ticket_bulk_priority_edit.php @@ -0,0 +1,36 @@ + diff --git a/agent/post/ticket.php b/agent/post/ticket.php index 281ec9f4..97707772 100644 --- a/agent/post/ticket.php +++ b/agent/post/ticket.php @@ -2639,6 +2639,254 @@ if (isset($_POST['bulk_delete_recurring_tickets'])) { } +if (isset($_POST['bulk_assign_recurring_ticket'])) { + + enforceUserPermission('module_support', 2); + + // POST variables + $assign_to = intval($_POST['assign_to']); + + // Get a Recurring Ticket Count + $recurring_ticket_count = count($_POST['recurring_ticket_ids']); + + // Assign Tech to Selected Recurring Tickets + if (!empty($_POST['recurring_ticket_ids'])) { + foreach ($_POST['recurring_ticket_ids'] as $recurring_ticket_id) { + $recurring_ticket_id = intval($recurring_ticket_id); + + $sql = mysqli_query($mysqli, "SELECT * FROM recurring_tickets WHERE recurring_ticket_id = $recurring_ticket_id"); + $row = mysqli_fetch_array($sql); + + $recurring_ticket_name = sanitizeInput($row['recurring_ticket_name']); + $recurring_ticket_subject = sanitizeInput($row['recurring_ticket_subject']); + $client_id = intval($row['recurring_ticket_client_id']); + + // Allow for un-assigning tickets + if ($assign_to == 0) { + $ticket_reply = "Ticket unassigned, pending re-assignment."; + $agent_name = "No One"; + } else { + // Get & verify assigned agent details + $agent_details_sql = mysqli_query($mysqli, "SELECT user_name, user_email FROM users LEFT JOIN user_settings ON users.user_id = user_settings.user_id WHERE users.user_id = $assign_to"); + $agent_details = mysqli_fetch_array($agent_details_sql); + + $agent_name = sanitizeInput($agent_details['user_name']); + $agent_email = sanitizeInput($agent_details['user_email']); + + if (!$agent_name) { + flash_alert("Invalid agent!", 'error'); + redirect(); + } + } + + // Update recurring ticket + mysqli_query($mysqli, "UPDATE recurring_tickets SET recurring_ticket_assigned_to = $assign_to WHERE recurring_ticket_id = $recurring_ticket_id"); + + logAction("Recurring_Ticket", "Edit", "$session_name reassigned recurring ticket $recurring_ticket_subject to $agent_name", $client_id, $recurring_ticket_id); + + $tickets_assigned_body .= "$recurring_ticket_subject
"; + } // End For Each Ticket ID Loop + + // Notification + if ($session_user_id != $assign_to && $assign_to != 0) { + + // App Notification + mysqli_query($mysqli, "INSERT INTO notifications SET notification_type = 'Recurring Ticket', notification = '$recurring_ticket_count Recurring Tickets have been assigned to you by $session_name', notification_action = 'recurring_tickets.php?assigned=$assign_to', notification_client_id = $client_id, notification_user_id = $assign_to"); + + // Agent Email Notification + if (!empty($config_smtp_host)) { + + // Sanitize Config vars from get_settings.php + $config_ticket_from_name = sanitizeInput($config_ticket_from_name); + $config_ticket_from_email = sanitizeInput($config_ticket_from_email); + $company_name = sanitizeInput($session_company_name); + + $subject = "$config_app_name - $recurring_ticket_count recurring tickets have been assigned to you"; + $body = "Hi $agent_name,

$session_name assigned $recurring_ticket_count recurring tickets to you!

$tickets_assigned_body
Thanks,
$session_name
$company_name"; + + // Email Ticket Agent + // Queue Mail + $data = [ + [ + 'from' => $config_ticket_from_email, + 'from_name' => $config_ticket_from_name, + 'recipient' => $agent_email, + 'recipient_name' => $agent_name, + 'subject' => $subject, + 'body' => $body, + ] + ]; + addToMailQueue($data); + } + } + } + + flash_alert("Assigned $recurring_ticket_count Recurring Tickets to $agent_name"); + + redirect(); + +} + +if (isset($_POST['bulk_edit_recurring_ticket_priority'])) { + + enforceUserPermission('module_support', 2); + + $priority = sanitizeInput($_POST['bulk_priority']); + + // Assign Tech to Selected Recurring Tickets + if (isset($_POST['recurring_ticket_ids'])) { + + // Get a Ticket Count + $recurring_ticket_count = count($_POST['recurring_ticket_ids']); + + foreach ($_POST['recurring_ticket_ids'] as $recurring_ticket_id) { + $recurring_ticket_id = intval($recurring_ticket_id); + + $sql = mysqli_query($mysqli, "SELECT * FROM recurring_tickets WHERE recurring_ticket_id = $recurring_ticket_id"); + $row = mysqli_fetch_array($sql); + + $recurring_ticket_subject = sanitizeInput($row['recurring_ticket_subject']); + $original_recurring_ticket_priority = sanitizeInput($row['recurring_ticket_priority']); + $client_id = intval($row['ticket_client_id']); + + // Update recurring ticket + mysqli_query($mysqli, "UPDATE recurring_tickets SET recurring_ticket_priority = '$priority' WHERE recurring_ticket_id = $recurring_ticket_id"); + + logAction("Ticket", "Edit", "$session_name updated the priority on recurring ticket $ticket_subject from $original_recurring_ticket_priority to $priority", $client_id, $recurring_ticket_id); + + customAction('recurring_ticket_update', $recurring_ticket_id); + } // End For Each Recurring Ticket ID Loop + + logAction("Recurring Ticket", " Bulk Edit", "$session_name updated the priority to $priority on $recurring_ticket_count Recurring Tickets"); + + flash_alert("Priority updated to $priority for $recurring_ticket_count Recurring Tickets"); + } + + redirect(); + +} + +if (isset($_POST['bulk_edit_recurring_ticket_category'])) { + + enforceUserPermission('module_support', 2); + + $category_id = intval($_POST['bulk_category']); + + if (isset($_POST['recurring_ticket_ids'])) { + + $recurring_ticket_count = count($_POST['recurring_ticket_ids']); + + foreach ($_POST['recurring_ticket_ids'] as $recurring_ticket_id) { + $recurring_ticket_id = intval($recurring_ticket_id); + + $sql = mysqli_query($mysqli, "SELECT recurring_ticket_subject, category_name, recurring_ticket_client_id FROM recurring_tickets LEFT JOIN categories ON recurring_ticket_category = category_id WHERE recurring_ticket_id = $recurring_ticket_id"); + $row = mysqli_fetch_array($sql); + + $recurring_ticket_subject = sanitizeInput($row['recurring_ticket_subject']); + $previous_recurring_ticket_category_name = sanitizeInput($row['category_name']); + $client_id = intval($row['recurring_ticket_client_id']); + + $category_name = sanitizeInput(getFieldById('categories', $category_id, 'category_name')); + + mysqli_query($mysqli, "UPDATE recurring_tickets SET recurring_ticket_category = '$category_id' WHERE recurring_ticket_id = $recurring_ticket_id"); + + logAction("Recurring Ticket", "Edit", "$session_name updated the category on recurring ticket $recurring_ticket_subject from $previous_recurring_ticket_category_name to $category_name", $client_id, $recurring_ticket_id); + + customAction('recurring_ticket_update', $recurring_ticket_id); + } + + logAction("Recurring Ticket", " Bulk Edit", "$session_name updated the category to $category_name for $recurring_ticket_count Recurring Tickets"); + + flash_alert("Category set to $category_name for $recurring_ticket_count Recurring Tickets"); + } + + redirect(); + +} + +if (isset($_POST['bulk_edit_recurring_ticket_billable'])) { + + enforceUserPermission('module_support', 2); + enforceUserPermission('module_sales', 2); + + $billable = intval($_POST['billable']); + if ($billable) { + $billable_status = "Billable"; + } else { + $billable_status = "Not Billable"; + } + + if (isset($_POST['recurring_ticket_ids'])) { + + $recurring_ticket_count = count($_POST['recurring_ticket_ids']); + + foreach ($_POST['recurring_ticket_ids'] as $recurring_ticket_id) { + $recurring_ticket_id = intval($recurring_ticket_id); + + $sql = mysqli_query($mysqli, "SELECT recurring_ticket_subject, recurring_ticket_client_id FROM recurring_tickets WHERE recurring_ticket_id = $recurring_ticket_id"); + $row = mysqli_fetch_array($sql); + + $recurring_ticket_subject = sanitizeInput($row['recurring_ticket_subject']); + $previous_recurring_ticket_billable = intval($row['recurring_ticket_billable']); + if ($previous_recurring_ticket_billable) { + $previous_billable_status = "Billable"; + } else { + $previous_billable_status = "Not Billable"; + } + $client_id = intval($row['recurring_ticket_client_id']); + + mysqli_query($mysqli, "UPDATE recurring_tickets SET recurring_ticket_billable = $billable WHERE recurring_ticket_id = $recurring_ticket_id"); + + logAction("Recurring Ticket", "Edit", "$session_name updated the billable status on recurring ticket $recurring_ticket_subject from $previous_billable_status to $billable_status", $client_id, $recurring_ticket_id); + + customAction('recurring_ticket_update', $recurring_ticket_id); + } + + logAction("Recurring Ticket", " Bulk Edit", "$session_name updated the billable status to $billable_status for $recurring_ticket_count Recurring Tickets"); + + flash_alert("Billable status set to $billable_status for $recurring_ticket_count Recurring Tickets"); + } + + redirect(); + +} + +if (isset($_POST['bulk_edit_recurring_ticket_next_run_date'])) { + + enforceUserPermission('module_support', 2); + + $next_run_date = sanitizeInput($_POST['next_run_date']); + + if (isset($_POST['recurring_ticket_ids'])) { + + $recurring_ticket_count = count($_POST['recurring_ticket_ids']); + + foreach ($_POST['recurring_ticket_ids'] as $recurring_ticket_id) { + $recurring_ticket_id = intval($recurring_ticket_id); + + $sql = mysqli_query($mysqli, "SELECT recurring_ticket_subject, recurring_ticket_client_id FROM recurring_tickets WHERE recurring_ticket_id = $recurring_ticket_id"); + $row = mysqli_fetch_array($sql); + + $recurring_ticket_subject = sanitizeInput($row['recurring_ticket_subject']); + $previous_recurring_ticket_next_run_date = sanitizeInput($row['recurring_ticket_next_run']); + $client_id = intval($row['recurring_ticket_client_id']); + + mysqli_query($mysqli, "UPDATE recurring_tickets SET recurring_ticket_next_run = '$next_run_date' WHERE recurring_ticket_id = $recurring_ticket_id"); + + logAction("Recurring Ticket", "Edit", "$session_name updated the Next run date on recurring ticket $recurring_ticket_subject from $previous_recurring_ticket_next_run_date to $next_run_date", $client_id, $recurring_ticket_id); + + customAction('recurring_ticket_update', $recurring_ticket_id); + } + + logAction("Recurring Ticket", " Bulk Edit", "$session_name updated the Next run date to $next_run_date for $recurring_ticket_count Recurring Tickets"); + + flash_alert("Next run date set to $next_run_date for $recurring_ticket_count Recurring Tickets"); + } + + redirect(); + +} + if (isset($_POST['edit_ticket_billable_status'])) { enforceUserPermission('module_support', 2); diff --git a/agent/recurring_tickets.php b/agent/recurring_tickets.php index 23381ea2..d26e644d 100644 --- a/agent/recurring_tickets.php +++ b/agent/recurring_tickets.php @@ -96,6 +96,26 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); Force Reoccur + + Assign Agent + + + + Set Category + + + + Set Priority + + + + Set Billable + + + + Set Next Run Date + + @@ -122,7 +142,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); - + Next Run Date @@ -146,6 +166,11 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); Frequency + + + Billable + + Assigned @@ -176,6 +201,12 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); $recurring_ticket_priority = nullable_htmlentities($row['recurring_ticket_priority']); $recurring_ticket_frequency = nullable_htmlentities($row['recurring_ticket_frequency']); $recurring_ticket_next_run = nullable_htmlentities($row['recurring_ticket_next_run']); + $recurring_ticket_billable = intval($row['recurring_ticket_billable']); + if ($recurring_ticket_billable) { + $recurring_ticket_billable_display = ""; + } else { + $recurring_ticket_billable_display = "-"; + } $recurring_ticket_category = getFallBack(nullable_htmlentities($row['category_name'])); $recurring_ticket_client_name = nullable_htmlentities($row['client_name']); $assigned_to = getFallBack(nullable_htmlentities($row['user_name'])); @@ -184,23 +215,24 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
- +
- +
- + - - - - + + + + + - + @@ -217,12 +249,12 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); Edit - + Force Reoccur - + Delete @@ -238,6 +270,13 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); +