From 5e63ef9a2a660fcf2292bb71efbea996d1addace Mon Sep 17 00:00:00 2001 From: Marcus Hill Date: Sun, 24 Mar 2024 22:36:21 +0000 Subject: [PATCH 1/7] Ticket Statuses from DB First swing at this to share my progress, isn't ready to merge yet but would appreciate thoughts --- client_tickets.php | 8 ++++---- database_updates.php | 33 ++++++++++++++++++++++++++++++--- database_version.php | 2 +- db.sql | 17 +++++++++++++++++ functions.php | 37 +++++++++++++++++++++++++++++++++++++ get_settings.php | 4 ++++ portal/portal_functions.php | 4 ++-- portal/portal_post.php | 6 +++--- post/ticket.php | 36 +++++++++++++++++++++++------------- setup.php | 8 +++++++- tickets.php | 22 ++++++---------------- 11 files changed, 134 insertions(+), 43 deletions(-) diff --git a/client_tickets.php b/client_tickets.php index a10de9c5..4518e822 100644 --- a/client_tickets.php +++ b/client_tickets.php @@ -142,14 +142,14 @@ $total_scheduled_tickets = intval($row['total_scheduled_tickets']); $ticket_number = nullable_htmlentities($row['ticket_number']); $ticket_subject = nullable_htmlentities($row['ticket_subject']); $ticket_priority = nullable_htmlentities($row['ticket_priority']); - $ticket_status = nullable_htmlentities($row['ticket_status']); + $ticket_status = sanitizeInput(getTicketStatusName($row['ticket_status'])); $ticket_billable = intval($row['ticket_billable']); $ticket_created_at = nullable_htmlentities($row['ticket_created_at']); $ticket_created_at_time_ago = timeAgo($row['ticket_created_at']); $ticket_updated_at = nullable_htmlentities($row['ticket_updated_at']); $ticket_updated_at_time_ago = timeAgo($row['ticket_updated_at']); if (empty($ticket_updated_at)) { - if ($ticket_status == "Closed") { + if ($ticket_status == $config_ticket_status_id_closed || $ticket_status == "Closed") { $ticket_updated_at_display = "

Never

"; } else { $ticket_updated_at_display = "

Never

"; @@ -173,7 +173,7 @@ $total_scheduled_tickets = intval($row['total_scheduled_tickets']); $ticket_assigned_to = intval($row['ticket_assigned_to']); if (empty($ticket_assigned_to)) { - if ($ticket_status == "Closed") { + if ($ticket_status == $config_ticket_status_id_closed || $ticket_status == "Closed") { $ticket_assigned_to_display = "

Not Assigned

"; } else { $ticket_assigned_to_display = "

Not Assigned

"; @@ -281,7 +281,7 @@ $total_scheduled_tickets = intval($row['total_scheduled_tickets']); CURRENT_DATABASE_VERSION) { mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.1.3'"); } - // if (CURRENT_DATABASE_VERSION == '1.1.3') { - // // Insert queries here required to update to DB version 1.1.4 + if (CURRENT_DATABASE_VERSION == '1.1.3') { + + // Add new ticket_statuses table + mysqli_query($mysqli, "CREATE TABLE `ticket_statuses` ( + `ticket_status_id` INT(11) NOT NULL AUTO_INCREMENT, + `ticket_status_name` VARCHAR(200) NOT NULL, + `ticket_status_color` VARCHAR(200) NOT NULL, + `ticket_status_active` TINYINT(1) NOT NULL DEFAULT '1', + PRIMARY KEY (`ticket_status_id`) + )"); + + // Pre-seed ticket statuses + mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'New', ticket_status_color = 'danger'"); // Default ID for new tickets is 1 + mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'Open', ticket_status_color = 'primary'"); // 2 + mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'On Hold', ticket_status_color = 'success'"); // 3 + mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'Auto Close', ticket_status_color = 'dark'"); // 5 + mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'Closed', ticket_status_color = 'dark'"); // 5 + + // Add default values above to settings + mysqli_query($mysqli, "ALTER TABLE `settings` ADD `config_ticket_status_id_new` int(1) NOT NULL DEFAULT '1' AFTER `config_ticket_new_ticket_notification_email`"); + mysqli_query($mysqli, "ALTER TABLE `settings` ADD `config_ticket_status_id_open` int(1) NOT NULL DEFAULT '2' AFTER `config_ticket_status_id_new`"); + mysqli_query($mysqli, "ALTER TABLE `settings` ADD `config_ticket_status_id_autoclose` int(1) NOT NULL DEFAULT '4' AFTER `config_ticket_status_id_open`"); + mysqli_query($mysqli, "ALTER TABLE `settings` ADD `config_ticket_status_id_closed` int(1) NOT NULL DEFAULT '5' AFTER `config_ticket_status_id_autoclose`"); + + mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.1.4'"); + } + + // if (CURRENT_DATABASE_VERSION == '1.1.4') { + // // Insert queries here required to update to DB version 1.1.5 // // Then, update the database to the next sequential version - // mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.1.4'"); + // mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.1.5'"); // } } else { diff --git a/database_version.php b/database_version.php index 1760e835..62e7c706 100644 --- a/database_version.php +++ b/database_version.php @@ -5,5 +5,5 @@ * It is used in conjunction with database_updates.php */ -DEFINE("LATEST_DATABASE_VERSION", "1.1.3"); +DEFINE("LATEST_DATABASE_VERSION", "1.1.4"); diff --git a/db.sql b/db.sql index efe7b6e8..c2d9f586 100644 --- a/db.sql +++ b/db.sql @@ -1296,6 +1296,10 @@ CREATE TABLE `settings` ( `config_ticket_autoclose` tinyint(1) NOT NULL DEFAULT 0, `config_ticket_autoclose_hours` int(5) NOT NULL DEFAULT 72, `config_ticket_new_ticket_notification_email` varchar(200) DEFAULT NULL, + `config_ticket_status_id_new` int(1) NOT NULL DEFAULT 1, + `config_ticket_status_id_open` int(1) NOT NULL DEFAULT 2, + `config_ticket_status_id_autoclose` int(1) NOT NULL DEFAULT 4, + `config_ticket_status_id_closed` int(1) NOT NULL DEFAULT 5, `config_enable_cron` tinyint(1) NOT NULL DEFAULT 0, `config_cron_key` varchar(255) DEFAULT NULL, `config_recurring_auto_send_invoice` tinyint(1) NOT NULL DEFAULT 1, @@ -1560,6 +1564,19 @@ CREATE TABLE `ticket_replies` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `ticket_statuses` +-- + +DROP TABLE IF EXISTS `ticket_statuses`; +CREATE TABLE IF NOT EXISTS `ticket_statuses` ( + `ticket_status_id` int(11) NOT NULL AUTO_INCREMENT, + `ticket_status_name` varchar(200) NOT NULL, + `ticket_status_color` varchar(200) NOT NULL, + `ticket_status_active` TINYINT(1) NOT NULL DEFAULT '1', + PRIMARY KEY (`ticket_status_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + -- -- Table structure for table `ticket_views` -- diff --git a/functions.php b/functions.php index 17df05b4..fb8d89a6 100644 --- a/functions.php +++ b/functions.php @@ -1139,6 +1139,22 @@ function createiCalStrCancel($originaliCalStr) { } function getTicketStatusColor($ticket_status) { + + global $mysqli; + + if (intval($ticket_status)) { + $status_id = intval($ticket_status); + $row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT * FROM ticket_statuses WHERE ticket_status_id = $status_id LIMIT 1")); + + if ($row) { + return nullable_htmlentities($row['ticket_status_color']); + } + + // Default return + return "Unknown"; + } + + // Legacy support for named statuses if ($ticket_status == "New") { return "danger"; } elseif ($ticket_status == "Open") { @@ -1151,3 +1167,24 @@ function getTicketStatusColor($ticket_status) { return "dark"; } } + +function getTicketStatusName($ticket_status) { + + global $mysqli; + + // Legacy support for named statuses + if (!intval($ticket_status)) { + return $ticket_status; + } + + $status_id = intval($ticket_status); + $row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT * FROM ticket_statuses WHERE ticket_status_id = $status_id LIMIT 1")); + + if ($row) { + return nullable_htmlentities($row['ticket_status_name']); + } + + // Default return + return "Unknown"; + +} diff --git a/get_settings.php b/get_settings.php index 5a3dbc2d..92c1ef16 100644 --- a/get_settings.php +++ b/get_settings.php @@ -68,6 +68,10 @@ $config_ticket_client_general_notifications = intval($row['config_ticket_client_ $config_ticket_autoclose = intval($row['config_ticket_autoclose']); $config_ticket_autoclose_hours = intval($row['config_ticket_autoclose_hours']); $config_ticket_new_ticket_notification_email = $row['config_ticket_new_ticket_notification_email']; +$config_ticket_status_id_new = intval($row['config_ticket_status_id_new']); +$config_ticket_status_id_open = intval($row['config_ticket_status_id_open']); +$config_ticket_status_id_autoclose = intval($row['config_ticket_status_id_autoclose']); +$config_ticket_status_id_closed = intval($row['config_ticket_status_id_closed']); // Cron $config_enable_cron = intval($row['config_enable_cron']); diff --git a/portal/portal_functions.php b/portal/portal_functions.php index a9ac1f14..25f3886c 100644 --- a/portal/portal_functions.php +++ b/portal/portal_functions.php @@ -16,10 +16,10 @@ function verifyContactTicketAccess($requested_ticket_id, $expected_ticket_state) // Setup if ($expected_ticket_state == "Closed") { // Closed tickets - $ticket_state_snippet = "ticket_status = 'Closed'"; + $ticket_state_snippet = "ticket_status = 'Closed' OR ticket_status = $config_ticket_status_id_closed"; } else { // Open (working/hold) tickets - $ticket_state_snippet = "ticket_status != 'Closed'"; + $ticket_state_snippet = "ticket_status != 'Closed' or ticket_status != $config_ticket_status_id_closed"; } // Verify the contact has access to the provided ticket ID diff --git a/portal/portal_post.php b/portal/portal_post.php index 2e154385..f22dbf2d 100644 --- a/portal/portal_post.php +++ b/portal/portal_post.php @@ -33,7 +33,7 @@ if (isset($_POST['add_ticket'])) { $new_config_ticket_next_number = $config_ticket_next_number + 1; mysqli_query($mysqli, "UPDATE settings SET config_ticket_next_number = $new_config_ticket_next_number WHERE company_id = 1"); - mysqli_query($mysqli, "INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_subject = '$subject', ticket_details = '$details', ticket_priority = '$priority', ticket_status = 'New', ticket_created_by = 0, ticket_contact_id = $contact, ticket_client_id = $client_id"); + mysqli_query($mysqli, "INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_subject = '$subject', ticket_details = '$details', ticket_priority = '$priority', ticket_status = $config_ticket_status_id_new, ticket_created_by = 0, ticket_contact_id = $contact, ticket_client_id = $client_id"); $id = mysqli_insert_id($mysqli); // Notify agent DL of the new ticket, if populated with a valid email @@ -86,7 +86,7 @@ if (isset($_POST['add_ticket_comment'])) { $ticket_reply_id = mysqli_insert_id($mysqli); // Update Ticket Last Response Field & set ticket to open as client has replied - mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 'Open' WHERE ticket_id = $ticket_id AND ticket_client_id = $session_client_id LIMIT 1"); + mysqli_query($mysqli, "UPDATE tickets SET ticket_status = $config_ticket_status_id_open WHERE ticket_id = $ticket_id AND ticket_client_id = $session_client_id LIMIT 1"); // Get ticket details & Notify the assigned tech (if any) @@ -201,7 +201,7 @@ if (isset($_GET['close_ticket'])) { if (verifyContactTicketAccess($ticket_id, "Open")) { // Close ticket - mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 'Closed', ticket_closed_at = NOW() WHERE ticket_id = $ticket_id AND ticket_client_id = $session_client_id"); + mysqli_query($mysqli, "UPDATE tickets SET ticket_status = $config_ticket_status_id_closed, ticket_closed_at = NOW() WHERE ticket_id = $ticket_id AND ticket_client_id = $session_client_id"); // 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"); diff --git a/post/ticket.php b/post/ticket.php index 1ac2f621..edceef98 100644 --- a/post/ticket.php +++ b/post/ticket.php @@ -11,9 +11,9 @@ if (isset($_POST['add_ticket'])) { $client_id = intval($_POST['client']); $assigned_to = intval($_POST['assigned_to']); if ($assigned_to == 0) { - $ticket_status = 'New'; + $ticket_status = $config_ticket_status_id_new; } else { - $ticket_status = 'Open'; + $ticket_status = $config_ticket_status_id_open; } $contact = intval($_POST['contact']); $subject = sanitizeInput($_POST['subject']); @@ -82,6 +82,7 @@ if (isset($_POST['add_ticket'])) { $ticket_details = mysqli_escape_string($mysqli, $row['ticket_details']); $ticket_priority = sanitizeInput($row['ticket_priority']); $ticket_status = sanitizeInput($row['ticket_status']); + $ticket_status_name = sanitizeInput(getTicketStatusName($row['ticket_status'])); $client_id = intval($row['ticket_client_id']); $ticket_created_by = intval($row['ticket_created_by']); $ticket_assigned_to = intval($row['ticket_assigned_to']); @@ -330,8 +331,15 @@ if (isset($_POST['assign_ticket'])) { $ticket_id = intval($_POST['ticket_id']); $assigned_to = intval($_POST['assigned_to']); $ticket_status = sanitizeInput($_POST['ticket_status']); + + // TODO: Remove this legacy if if ($ticket_status == 'New' && $assigned_to !== 0) { - $ticket_status = 'Open'; + $ticket_status = $config_ticket_status_id_open; + } + + // New + if ($ticket_status == $config_ticket_status_id_new && $assigned_to !== 0) { + $ticket_status = $config_ticket_status_id_open; } // Allow for un-assigning tickets @@ -356,7 +364,7 @@ if (isset($_POST['assign_ticket'])) { } // Get & verify ticket details - $ticket_details_sql = mysqli_query($mysqli, "SELECT ticket_prefix, ticket_number, ticket_subject, ticket_client_id, client_name FROM tickets LEFT JOIN clients ON ticket_client_id = client_id WHERE ticket_id = '$ticket_id' AND ticket_status != 'Closed'"); + $ticket_details_sql = mysqli_query($mysqli, "SELECT ticket_prefix, ticket_number, ticket_subject, ticket_client_id, client_name FROM tickets LEFT JOIN clients ON ticket_client_id = client_id WHERE ticket_id = '$ticket_id' AND ticket_status != $config_ticket_status_id_closed AND ticket_status != 'Closed'"); $ticket_details = mysqli_fetch_array($ticket_details_sql); $ticket_prefix = sanitizeInput($ticket_details['ticket_prefix']); @@ -434,7 +442,7 @@ if (isset($_GET['delete_ticket'])) { $ticket_status = sanitizeInput($row['ticket_status']); $client_id = intval($row['ticket_client_id']); - if ($ticket_status !== 'Closed') { + if ($ticket_status !== $config_ticket_status_id_closed && $ticket_status !== 'Closed') { mysqli_query($mysqli, "DELETE FROM tickets WHERE ticket_id = $ticket_id"); // Delete all ticket replies @@ -479,7 +487,7 @@ if (isset($_POST['bulk_assign_ticket'])) { $client_id = intval($row['ticket_client_id']); if ($ticket_status == 'New' && $assigned_to !== 0) { - $ticket_status = 'Open'; + $ticket_status = $config_ticket_status_id_open; } // Allow for un-assigning tickets @@ -621,7 +629,7 @@ if (isset($_POST['bulk_close_tickets'])) { $ticket_prefix = sanitizeInput($row['ticket_prefix']); $ticket_number = intval($row['ticket_number']); - $ticket_status = sanitizeInput($row['ticket_status']); + $ticket_status = sanitizeInput(getTicketStatusName($row['ticket_status'])); $ticket_subject = sanitizeInput($row['ticket_subject']); $current_ticket_priority = sanitizeInput($row['ticket_priority']); $client_id = intval($row['ticket_client_id']); @@ -713,6 +721,7 @@ if (isset($_POST['bulk_ticket_reply'])) { // POST variables $ticket_reply = mysqli_escape_string($mysqli, $_POST['bulk_reply_details']); $ticket_status = sanitizeInput($_POST['bulk_status']); + $ticket_status_name = sanitizeInput(getTicketStatusName($row['ticket_status'])); $private_note = intval($_POST['bulk_private_reply']); if ($private_note == 1) { $ticket_reply_type = 'Internal'; @@ -780,7 +789,7 @@ if (isset($_POST['bulk_ticket_reply'])) { if (filter_var($contact_email, FILTER_VALIDATE_EMAIL)) { $subject = "Ticket update - [$ticket_prefix$ticket_number] - $ticket_subject"; - $body = "##- Please type your reply above this line -##

Hello $contact_name,

Your ticket regarding $ticket_subject has been updated.

--------------------------------
$ticket_reply
--------------------------------

Ticket: $ticket_prefix$ticket_number
Subject: $ticket_subject
Status: $ticket_status
Portal: https://$base_url/portal/ticket.php?id=$ticket_id

--
$company_name - Support
$from_email
$company_phone"; + $body = "##- Please type your reply above this line -##

Hello $contact_name,

Your ticket regarding $ticket_subject has been updated.

--------------------------------
$ticket_reply
--------------------------------

Ticket: $ticket_prefix$ticket_number
Subject: $ticket_subject
Status: $ticket_status_name
Portal: https://$base_url/portal/ticket.php?id=$ticket_id

--
$company_name - Support
$from_email
$company_phone"; $data = []; @@ -842,6 +851,7 @@ if (isset($_POST['add_ticket_reply'])) { $ticket_id = intval($_POST['ticket_id']); $ticket_reply = mysqli_real_escape_string($mysqli, $_POST['ticket_reply']); $ticket_status = sanitizeInput($_POST['status']); + $ticket_status_name = sanitizeInput(getTicketStatusName($row['ticket_status'])); // Handle the time inputs for hours, minutes, and seconds $hours = intval($_POST['hours']); $minutes = intval($_POST['minutes']); @@ -869,7 +879,7 @@ if (isset($_POST['add_ticket_reply'])) { // Update Ticket Last Response Field mysqli_query($mysqli, "UPDATE tickets SET ticket_status = '$ticket_status' WHERE ticket_id = $ticket_id"); - if ($ticket_status == 'Closed') { + if ($ticket_status == $config_ticket_status_id_closed || $ticket_status == 'Closed') { mysqli_query($mysqli, "UPDATE tickets SET ticket_closed_at = NOW() WHERE ticket_id = $ticket_id"); } @@ -909,15 +919,15 @@ if (isset($_POST['add_ticket_reply'])) { // Slightly different email subject/text depending on if this update closed the ticket or not - if ($ticket_status == 'Closed') { + if ($ticket_status == $config_ticket_status_id_closed || $ticket_status == 'Closed') { $subject = "Ticket closed - [$ticket_prefix$ticket_number] - $ticket_subject | (do not reply)"; $body = "Hello $contact_name,

Your ticket regarding $ticket_subject has been closed.

--------------------------------
$ticket_reply
--------------------------------

We hope the request/issue was resolved to your satisfaction. If you need further assistance, please raise a new ticket using the below details. Please do not reply to this email.

Ticket: $ticket_prefix$ticket_number
Subject: $ticket_subject
Portal: https://$config_base_url/portal/ticket.php?id=$ticket_id

--
$company_name - Support
$config_ticket_from_email
$company_phone"; - } elseif ($ticket_status == 'Auto Close') { + } elseif ($ticket_status == $config_ticket_status_id_autoclose || $ticket_status == 'Auto Close') { $subject = "Ticket update - [$ticket_prefix$ticket_number] - $ticket_subject | (pending closure)"; - $body = "##- Please type your reply above this line -##

Hello $contact_name,

Your ticket regarding $ticket_subject has been updated and is pending closure.

--------------------------------
$ticket_reply
--------------------------------

If your request/issue is resolved, you can simply ignore this email. If you need further assistance, please respond to let us know!

Ticket: $ticket_prefix$ticket_number
Subject: $ticket_subject
Status: $ticket_status
Portal: https://$config_base_url/portal/ticket.php?id=$ticket_id

--
$company_name - Support
$config_ticket_from_email
$company_phone"; + $body = "##- Please type your reply above this line -##

Hello $contact_name,

Your ticket regarding $ticket_subject has been updated and is pending closure.

--------------------------------
$ticket_reply
--------------------------------

If your request/issue is resolved, you can simply ignore this email. If you need further assistance, please respond to let us know!

Ticket: $ticket_prefix$ticket_number
Subject: $ticket_subject
Status: $ticket_status_name
Portal: https://$config_base_url/portal/ticket.php?id=$ticket_id

--
$company_name - Support
$config_ticket_from_email
$company_phone"; } else { $subject = "Ticket update - [$ticket_prefix$ticket_number] - $ticket_subject"; - $body = "##- Please type your reply above this line -##

Hello $contact_name,

Your ticket regarding $ticket_subject has been updated.

--------------------------------
$ticket_reply
--------------------------------

Ticket: $ticket_prefix$ticket_number
Subject: $ticket_subject
Status: $ticket_status
Portal: https://$config_base_url/portal/ticket.php?id=$ticket_id

--
$company_name - Support
$config_ticket_from_email
$company_phone"; + $body = "##- Please type your reply above this line -##

Hello $contact_name,

Your ticket regarding $ticket_subject has been updated.

--------------------------------
$ticket_reply
--------------------------------

Ticket: $ticket_prefix$ticket_number
Subject: $ticket_subject
Status: $ticket_status_name
Portal: https://$config_base_url/portal/ticket.php?id=$ticket_id

--
$company_name - Support
$config_ticket_from_email
$company_phone"; } $data = []; diff --git a/setup.php b/setup.php index 0d5a7476..59df2dfe 100644 --- a/setup.php +++ b/setup.php @@ -257,7 +257,7 @@ if (isset($_POST['add_company_settings'])) { unlink('uploads/tmp/cronkey.php'); } - + // Create Main Account Types mysqli_query($mysqli,"INSERT INTO account_types SET account_type_name = 'Asset', account_type_parent = 1, account_type_description = 'Assets are economic resources which are expected to benefit the business in the future.'"); @@ -295,6 +295,12 @@ if (isset($_POST['add_company_settings'])) { //Create Calendar mysqli_query($mysqli,"INSERT INTO calendars SET calendar_name = 'Default', calendar_color = 'blue'"); + // Add default ticket statuses + mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'New', ticket_status_color = 'danger'"); // Default ID for new tickets is 1 + mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'Open', ticket_status_color = 'primary'"); // 2 + mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'On Hold', ticket_status_color = 'success'"); // 3 + mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'Auto Close', ticket_status_color = 'success'"); // 4 + mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'Closed', ticket_status_color = 'dark'"); // 5 $_SESSION['alert_message'] = "Company $name created!"; diff --git a/tickets.php b/tickets.php index ee713383..9c9f463e 100644 --- a/tickets.php +++ b/tickets.php @@ -311,7 +311,7 @@ $user_active_assigned_tickets = intval($row['total_tickets_assigned']); $ticket_number = intval($row['ticket_number']); $ticket_subject = nullable_htmlentities($row['ticket_subject']); $ticket_priority = nullable_htmlentities($row['ticket_priority']); - $ticket_status = nullable_htmlentities($row['ticket_status']); + $ticket_status = sanitizeInput(getTicketStatusName($row['ticket_status'])); $ticket_billable = intval($row['ticket_billable']); $ticket_scheduled_for = nullable_htmlentities($row['ticket_schedule']); $ticket_created_at = nullable_htmlentities($row['ticket_created_at']); @@ -319,7 +319,7 @@ $user_active_assigned_tickets = intval($row['total_tickets_assigned']); $ticket_updated_at = nullable_htmlentities($row['ticket_updated_at']); $ticket_updated_at_time_ago = timeAgo($row['ticket_updated_at']); if (empty($ticket_updated_at)) { - if ($ticket_status == "Closed") { + if ($ticket_status == $config_ticket_status_id_closed || $ticket_status == "Closed") { $ticket_updated_at_display = "

Never

"; } else { $ticket_updated_at_display = "

Never

"; @@ -333,17 +333,7 @@ $user_active_assigned_tickets = intval($row['total_tickets_assigned']); $contact_name = nullable_htmlentities($row['contact_name']); $contact_email = nullable_htmlentities($row['contact_email']); - if ($ticket_status == "New") { - $ticket_status_color = "danger"; - } elseif ($ticket_status == "Open") { - $ticket_status_color = "primary"; - } elseif ($ticket_status == "On Hold") { - $ticket_status_color = "success"; - } elseif ($ticket_status == "Auto Close") { - $ticket_status_color = "dark"; - } elseif ($ticket_status == "Closed") { - $ticket_status_color = "dark"; - } + $ticket_status_color = getTicketStatusColor($ticket_status); if ($ticket_priority == "High") { $ticket_priority_color = "danger"; @@ -355,7 +345,7 @@ $user_active_assigned_tickets = intval($row['total_tickets_assigned']); $ticket_assigned_to = intval($row['ticket_assigned_to']); if (empty($ticket_assigned_to)) { - if ($ticket_status == "Closed") { + if ($ticket_status == $config_ticket_status_id_closed || $ticket_status == "Closed") { $ticket_assigned_to_display = "

Not Assigned

"; } else { $ticket_assigned_to_display = "

Not Assigned

"; @@ -398,7 +388,7 @@ $user_active_assigned_tickets = intval($row['total_tickets_assigned']); - +
@@ -470,7 +460,7 @@ $user_active_assigned_tickets = intval($row['total_tickets_assigned']); Date: Sun, 24 Mar 2024 22:54:38 +0000 Subject: [PATCH 2/7] Ticket Statuses from DB First swing at this to share my progress, isn't ready to merge yet but would appreciate thoughts --- database_updates.php | 2 +- portal/portal_functions.php | 2 +- portal/ticket.php | 6 +++--- portal/ticket_view_all.php | 2 +- portal/tickets.php | 12 ++++++------ 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/database_updates.php b/database_updates.php index c4b75721..8d7d2d7c 100644 --- a/database_updates.php +++ b/database_updates.php @@ -1691,7 +1691,7 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) { // Add new ticket_statuses table mysqli_query($mysqli, "CREATE TABLE `ticket_statuses` ( - `ticket_status_id` INT(11) NOT NULL AUTO_INCREMENT, + `ticket_status_id` INT(11) NOT NULL AUTO_INCREMENT, `ticket_status_name` VARCHAR(200) NOT NULL, `ticket_status_color` VARCHAR(200) NOT NULL, `ticket_status_active` TINYINT(1) NOT NULL DEFAULT '1', diff --git a/portal/portal_functions.php b/portal/portal_functions.php index 25f3886c..af4783ae 100644 --- a/portal/portal_functions.php +++ b/portal/portal_functions.php @@ -11,7 +11,7 @@ function verifyContactTicketAccess($requested_ticket_id, $expected_ticket_state) { // Access the global variables - global $mysqli, $session_contact_id, $session_contact_primary, $session_contact_is_technical_contact, $session_client_id; + global $mysqli, $session_contact_id, $session_contact_primary, $session_contact_is_technical_contact, $session_client_id, $config_ticket_status_id_closed; // Setup if ($expected_ticket_state == "Closed") { diff --git a/portal/ticket.php b/portal/ticket.php index cee3b2f6..84891a8b 100644 --- a/portal/ticket.php +++ b/portal/ticket.php @@ -32,7 +32,7 @@ if (isset($_GET['id']) && intval($_GET['id'])) { $ticket_prefix = nullable_htmlentities($ticket_row['ticket_prefix']); $ticket_number = intval($ticket_row['ticket_number']); - $ticket_status = nullable_htmlentities($ticket_row['ticket_status']); + $ticket_status = sanitizeInput(getTicketStatusName($ticket_row['ticket_status'])); $ticket_priority = nullable_htmlentities($ticket_row['ticket_priority']); $ticket_subject = nullable_htmlentities($ticket_row['ticket_subject']); $ticket_details = $purifier->purify($ticket_row['ticket_details']); @@ -56,7 +56,7 @@ if (isset($_GET['id']) && intval($_GET['id'])) {

Ticket + if ($ticket_status !== $config_ticket_status_id_closed AND $ticket_status !== "Closed") { ?> Close ticket

@@ -70,7 +70,7 @@ if (isset($_GET['id']) && intval($_GET['id'])) {
Priority:
- + Assigned to:

diff --git a/portal/ticket_view_all.php b/portal/ticket_view_all.php index 5eea42d1..f22f5c5f 100644 --- a/portal/ticket_view_all.php +++ b/portal/ticket_view_all.php @@ -61,7 +61,7 @@ $all_tickets = mysqli_query($mysqli, "SELECT * FROM tickets LEFT JOIN contacts O $ticket_prefix = nullable_htmlentities($row['ticket_prefix']); $ticket_number = intval($row['ticket_number']); $ticket_subject = nullable_htmlentities($row['ticket_subject']); - $ticket_status = nullable_htmlentities($row['ticket_status']); + $ticket_status = sanitizeInput(getTicketStatusName($row['ticket_status'])); $ticket_contact_name = nullable_htmlentities($row['contact_name']); echo ""; diff --git a/portal/tickets.php b/portal/tickets.php index ebd2696e..940cb358 100644 --- a/portal/tickets.php +++ b/portal/tickets.php @@ -13,13 +13,13 @@ require_once "inc_portal.php"; if (!isset($_GET['status'])) { // If nothing is set, assume we only want to see open tickets $status = 'Open'; - $ticket_status_snippet = "ticket_status != 'Closed'"; + $ticket_status_snippet = "ticket_status != $config_ticket_status_id_closed AND ticket_status != 'Closed'"; } elseif (isset($_GET['status']) && ($_GET['status']) == 'Open') { $status = 'Open'; - $ticket_status_snippet = "ticket_status != 'Closed'"; + $ticket_status_snippet = "ticket_status != $config_ticket_status_id_closed AND ticket_status != 'Closed'"; } elseif (isset($_GET['status']) && ($_GET['status']) == 'Closed') { $status = 'Closed'; - $ticket_status_snippet = "ticket_status = 'Closed'"; + $ticket_status_snippet = "ticket_status = $config_ticket_status_id_closed OR ticket_status = 'Closed'"; } else { $status = '%'; $ticket_status_snippet = "ticket_status LIKE '%'"; @@ -28,12 +28,12 @@ if (!isset($_GET['status'])) { $contact_tickets = mysqli_query($mysqli, "SELECT * FROM tickets LEFT JOIN contacts ON ticket_contact_id = contact_id WHERE $ticket_status_snippet AND ticket_contact_id = $session_contact_id AND ticket_client_id = $session_client_id ORDER BY ticket_id DESC"); //Get Total tickets closed -$sql_total_tickets_closed = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS total_tickets_closed FROM tickets WHERE ticket_status = 'Closed' AND ticket_client_id = $session_client_id AND ticket_contact_id = $session_contact_id"); +$sql_total_tickets_closed = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS total_tickets_closed FROM tickets WHERE ticket_status = $config_ticket_status_id_closed OR ticket_status = 'Closed' AND ticket_client_id = $session_client_id AND ticket_contact_id = $session_contact_id"); $row = mysqli_fetch_array($sql_total_tickets_closed); $total_tickets_closed = intval($row['total_tickets_closed']); //Get Total tickets open -$sql_total_tickets_open = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS total_tickets_open FROM tickets WHERE ticket_status != 'Closed' AND ticket_client_id = $session_client_id AND ticket_contact_id = $session_contact_id"); +$sql_total_tickets_open = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS total_tickets_open FROM tickets WHERE ticket_status != $config_ticket_status_id_closed AND ticket_status != 'Closed' AND ticket_client_id = $session_client_id AND ticket_contact_id = $session_contact_id"); $row = mysqli_fetch_array($sql_total_tickets_open); $total_tickets_open = intval($row['total_tickets_open']); @@ -65,7 +65,7 @@ $total_tickets = intval($row['total_tickets']); $ticket_prefix = nullable_htmlentities($row['ticket_prefix']); $ticket_number = intval($row['ticket_number']); $ticket_subject = nullable_htmlentities($row['ticket_subject']); - $ticket_status = nullable_htmlentities($row['ticket_status']); + $ticket_status = sanitizeInput(getTicketStatusName($row['ticket_status'])); ?> From 63f35d576067946bb1aebcf9a72a82eadc079490 Mon Sep 17 00:00:00 2001 From: Marcus Hill Date: Sun, 24 Mar 2024 22:57:21 +0000 Subject: [PATCH 3/7] Ticket Statuses from DB First swing at this to share my progress, isn't ready to merge yet but would appreciate thoughts --- portal/ticket.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/portal/ticket.php b/portal/ticket.php index 84891a8b..03a60c1d 100644 --- a/portal/ticket.php +++ b/portal/ticket.php @@ -56,7 +56,7 @@ if (isset($_GET['id']) && intval($_GET['id'])) {

Ticket + if ($ticket_status !== $config_ticket_status_id_closed && $ticket_status !== "Closed") { ?> Close ticket

From 667a93210c932bc066ad82fcddfba473c583596e Mon Sep 17 00:00:00 2001 From: Marcus Hill Date: Fri, 29 Mar 2024 11:22:32 +0000 Subject: [PATCH 4/7] Ticket Statuses from DB --- client_tickets.php | 27 ++++++------ cron.php | 22 +++++----- cron_ticket_email_parser.php | 10 ++--- dashboard.php | 23 ++++------ database_updates.php | 80 ++++++++++++++++++++++++++++++++--- database_version.php | 2 +- db.sql | 81 +++++++++++++++++++++++++++++++----- functions.php | 32 +++----------- global_search.php | 32 +++++++------- post/ticket.php | 7 +--- report_ticket_by_client.php | 4 +- ticket.php | 39 +++++++++-------- ticket_assign_modal.php | 2 +- tickets.php | 66 +++++++++++++++-------------- 14 files changed, 263 insertions(+), 164 deletions(-) diff --git a/client_tickets.php b/client_tickets.php index 4518e822..eba4013c 100644 --- a/client_tickets.php +++ b/client_tickets.php @@ -7,15 +7,13 @@ $order = "DESC"; require_once "inc_all_client.php"; -if (isset($_GET['status']) && ($_GET['status']) == 'Open') { - $status = 'Open'; - $ticket_status_snippet = "ticket_status != 'Closed'"; -} elseif (isset($_GET['status']) && ($_GET['status']) == 'Closed') { +if (isset($_GET['status']) && ($_GET['status']) == 'Closed') { $status = 'Closed'; - $ticket_status_snippet = "ticket_status = 'Closed'"; + $ticket_status_snippet = "ticket_closed_at IS NOT NULL"; } else { + // Default - Show open tickets $status = 'Open'; - $ticket_status_snippet = "ticket_status != 'Closed'"; + $ticket_status_snippet = "ticket_closed_at IS NULL"; } if (isset($_GET['billable']) && ($_GET['billable']) == '1') { @@ -50,12 +48,12 @@ $sql = mysqli_query( $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); //Get Total tickets open -$sql_total_tickets_open = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS total_tickets_open FROM tickets WHERE ticket_client_id = $client_id AND ticket_status != 'Closed'"); +$sql_total_tickets_open = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS total_tickets_open FROM tickets WHERE ticket_client_id = $client_id AND ticket_closed_at IS NULL"); $row = mysqli_fetch_array($sql_total_tickets_open); $total_tickets_open = intval($row['total_tickets_open']); //Get Total tickets closed -$sql_total_tickets_closed = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS total_tickets_closed FROM tickets WHERE ticket_client_id = $client_id AND ticket_status = 'Closed'"); +$sql_total_tickets_closed = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS total_tickets_closed FROM tickets WHERE ticket_client_id = $client_id AND ticket_closed_at IS NOT NULL"); $row = mysqli_fetch_array($sql_total_tickets_closed); $total_tickets_closed = intval($row['total_tickets_closed']); @@ -142,14 +140,15 @@ $total_scheduled_tickets = intval($row['total_scheduled_tickets']); $ticket_number = nullable_htmlentities($row['ticket_number']); $ticket_subject = nullable_htmlentities($row['ticket_subject']); $ticket_priority = nullable_htmlentities($row['ticket_priority']); - $ticket_status = sanitizeInput(getTicketStatusName($row['ticket_status'])); + $ticket_status_id = intval($row['ticket_status']); + $ticket_status_name = sanitizeInput(getTicketStatusName($row['ticket_status'])); $ticket_billable = intval($row['ticket_billable']); $ticket_created_at = nullable_htmlentities($row['ticket_created_at']); $ticket_created_at_time_ago = timeAgo($row['ticket_created_at']); $ticket_updated_at = nullable_htmlentities($row['ticket_updated_at']); $ticket_updated_at_time_ago = timeAgo($row['ticket_updated_at']); if (empty($ticket_updated_at)) { - if ($ticket_status == $config_ticket_status_id_closed || $ticket_status == "Closed") { + if (!empty($ticket_closed_at)) { $ticket_updated_at_display = "

Never

"; } else { $ticket_updated_at_display = "

Never

"; @@ -159,7 +158,7 @@ $total_scheduled_tickets = intval($row['total_scheduled_tickets']); } $ticket_closed_at = nullable_htmlentities($row['ticket_closed_at']); - $ticket_status_color = getTicketStatusColor($ticket_status); + $ticket_status_color = getTicketStatusColor($ticket_status_id); if ($ticket_priority == "High") { $ticket_priority_display = "$ticket_priority"; @@ -173,7 +172,7 @@ $total_scheduled_tickets = intval($row['total_scheduled_tickets']); $ticket_assigned_to = intval($row['ticket_assigned_to']); if (empty($ticket_assigned_to)) { - if ($ticket_status == $config_ticket_status_id_closed || $ticket_status == "Closed") { + if (!empty($ticket_closed_at)) { $ticket_assigned_to_display = "

Not Assigned

"; } else { $ticket_assigned_to_display = "

Not Assigned

"; @@ -256,7 +255,7 @@ $total_scheduled_tickets = intval($row['total_scheduled_tickets']); - + @@ -281,7 +280,7 @@ $total_scheduled_tickets = intval($row['total_scheduled_tickets']); 0) { $contact_id = intval($row['scheduled_ticket_contact_id']); $asset_id = intval($row['scheduled_ticket_asset_id']); - $ticket_status = 'New'; // Default + $ticket_status = $config_ticket_status_id_new; // Default if ($assigned_id > 0) { - $ticket_status = 'Open'; // Set to open if we've auto-assigned an agent + $ticket_status = $config_ticket_status_id_open; // Set to open if we've auto-assigned an agent } // Assign this new ticket the next ticket number @@ -381,7 +383,7 @@ if ($config_ticket_autoclose == 1) { $sql_tickets_to_chase = mysqli_query( $mysqli, "SELECT * FROM tickets - WHERE ticket_status = 'Auto Close' + WHERE ticket_status = '$config_ticket_status_id_autoclose' AND ticket_updated_at < NOW() - INTERVAL $config_ticket_autoclose_hours HOUR" ); @@ -395,7 +397,7 @@ if ($config_ticket_autoclose == 1) { $ticket_assigned_to = sanitizeInput($row['ticket_assigned_to']); $client_id = intval($row['ticket_client_id']); - mysqli_query($mysqli,"UPDATE tickets SET ticket_status = 'Closed', ticket_closed_at = NOW(), ticket_closed_by = $ticket_assigned_to WHERE ticket_id = $ticket_id"); + mysqli_query($mysqli,"UPDATE tickets SET ticket_status = '$config_ticket_status_id_closed', ticket_closed_at = NOW(), ticket_closed_by = $ticket_assigned_to WHERE ticket_id = $ticket_id"); //Logging mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Ticket', log_action = 'Closed', log_description = '$ticket_prefix$ticket_number auto closed', log_entity_id = $ticket_id"); @@ -410,7 +412,7 @@ if ($config_ticket_autoclose == 1) { "SELECT contact_name, contact_email, ticket_id, ticket_prefix, ticket_number, ticket_subject, ticket_status, ticket_client_id FROM tickets LEFT JOIN clients ON ticket_client_id = client_id LEFT JOIN contacts ON ticket_contact_id = contact_id - WHERE ticket_status = 'Auto Close' + WHERE ticket_status = '$config_ticket_status_id_autoclose' AND ticket_updated_at < NOW() - INTERVAL 48 HOUR" ); @@ -422,7 +424,7 @@ if ($config_ticket_autoclose == 1) { $ticket_prefix = sanitizeInput($row['ticket_prefix']); $ticket_number = intval($row['ticket_number']); $ticket_subject = sanitizeInput($row['ticket_subject']); - $ticket_status = sanitizeInput($row['ticket_status']); + $ticket_status = sanitizeInput( getTicketStatusName($row['ticket_status'])); $client_id = intval($row['ticket_client_id']); $sql_ticket_reply = mysqli_query($mysqli, "SELECT ticket_reply FROM ticket_replies WHERE ticket_reply_type = 'Public' AND ticket_reply_ticket_id = $ticket_id ORDER BY ticket_reply_created_at DESC LIMIT 1"); @@ -431,7 +433,7 @@ if ($config_ticket_autoclose == 1) { $subject = "Ticket pending closure - [$ticket_prefix$ticket_number] - $ticket_subject"; - $body = "##- Please type your reply above this line -##

Hello, $contact_name

This is an automatic friendly reminder that your ticket regarding \"$ticket_subject\" will be closed, unless you respond.

--------------------------------
$ticket_reply--------------------------------

If your issue is resolved, you can ignore this email - the ticket will automatically close. If you need further assistance, please respond to this email.

Ticket: $ticket_prefix$ticket_number
Subject: $ticket_subject
Status: $ticket_status
Portal: https://$config_base_url/portal/ticket.php?id=$ticket_id

--
$company_name - Support
$config_ticket_from_email
$company_phone"; + $body = "##- Please type your reply above this line -##

Hello, $contact_name

This is an automatic friendly reminder that your ticket regarding \"$ticket_subject\" will be closed, unless you respond.

--------------------------------
$ticket_reply--------------------------------

If your issue is resolved, you can ignore this email - the ticket will automatically close. If you need further assistance, please respond to this email.

Ticket: $ticket_prefix$ticket_number
Subject: $ticket_subject
Status: $ticket_status
Portal: https://$config_base_url/portal/ticket.php?id=$ticket_id

--
$company_name - Support
$config_ticket_from_email
$company_phone"; $data = [ [ diff --git a/cron_ticket_email_parser.php b/cron_ticket_email_parser.php index b8cee1ff..fde69c29 100644 --- a/cron_ticket_email_parser.php +++ b/cron_ticket_email_parser.php @@ -110,7 +110,7 @@ $allowed_extensions = array('jpg', 'jpeg', 'gif', 'png', 'webp', 'pdf', 'txt', ' function addTicket($contact_id, $contact_name, $contact_email, $client_id, $date, $subject, $message, $attachments) { // Access global variables - global $mysqli,$config_app_name, $company_name, $company_phone, $config_ticket_prefix, $config_ticket_client_general_notifications, $config_ticket_new_ticket_notification_email, $config_base_url, $config_ticket_from_name, $config_ticket_from_email, $config_smtp_host, $config_smtp_port, $config_smtp_encryption, $config_smtp_username, $config_smtp_password, $allowed_extensions; + global $mysqli,$config_app_name, $company_name, $company_phone, $config_ticket_prefix, $config_ticket_client_general_notifications, $config_ticket_new_ticket_notification_email, $config_ticket_status_id_new, $config_ticket_status_id_closed, $config_base_url, $config_ticket_from_name, $config_ticket_from_email, $config_smtp_host, $config_smtp_port, $config_smtp_encryption, $config_smtp_username, $config_smtp_password, $allowed_extensions; // Get the next Ticket Number and add 1 for the new ticket number $ticket_number_sql = mysqli_fetch_array(mysqli_query($mysqli, "SELECT config_ticket_next_number FROM settings WHERE company_id = 1")); @@ -122,7 +122,7 @@ function addTicket($contact_id, $contact_name, $contact_email, $client_id, $date $message = nl2br($message); $message = mysqli_escape_string($mysqli, "Email from: $contact_email at $date:-

$message"); - mysqli_query($mysqli, "INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_subject = '$subject', ticket_details = '$message', ticket_priority = 'Low', ticket_status = 'New', ticket_created_by = 0, ticket_contact_id = $contact_id, ticket_client_id = $client_id"); + mysqli_query($mysqli, "INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_subject = '$subject', ticket_details = '$message', ticket_priority = 'Low', ticket_status = '$config_ticket_status_id_new', ticket_created_by = 0, ticket_contact_id = $contact_id, ticket_client_id = $client_id"); $id = mysqli_insert_id($mysqli); // Logging @@ -213,7 +213,7 @@ function addReply($from_email, $date, $subject, $ticket_number, $message, $attac // Add email as a comment/reply to an existing ticket // Access global variables - global $mysqli, $config_app_name, $company_name, $company_phone, $config_ticket_prefix, $config_base_url, $config_ticket_from_name, $config_ticket_from_email, $config_smtp_host, $config_smtp_port, $config_smtp_encryption, $config_smtp_username, $config_smtp_password, $allowed_extensions; + global $mysqli, $config_app_name, $company_name, $company_phone, $config_ticket_prefix, $config_ticket_status_id_open, $config_ticket_status_id_closed, $config_base_url, $config_ticket_from_name, $config_ticket_from_email, $config_smtp_host, $config_smtp_port, $config_smtp_encryption, $config_smtp_username, $config_smtp_password, $allowed_extensions; // Set default reply type $ticket_reply_type = 'Client'; @@ -243,7 +243,7 @@ function addReply($from_email, $date, $subject, $ticket_number, $message, $attac $client_name = sanitizeInput($row['client_name']); // Check ticket isn't closed - tickets can't be re-opened - if ($ticket_status == "Closed") { + if ($ticket_status == $config_ticket_status_id_closed) { mysqli_query($mysqli, "INSERT INTO notifications SET notification_type = 'Ticket', notification = 'Email parser: $from_email attempted to re-open ticket $config_ticket_prefix$ticket_number (ID $ticket_id) - check inbox manually to see email', notification_action = 'ticket.php?ticket_id=$ticket_id', notification_client_id = $client_id"); $email_subject = "Action required: This ticket is already closed"; @@ -360,7 +360,7 @@ function addReply($from_email, $date, $subject, $ticket_number, $message, $attac } // Update Ticket Last Response Field & set ticket to open as client has replied - mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 'Open' WHERE ticket_id = $ticket_id AND ticket_client_id = $client_id LIMIT 1"); + mysqli_query($mysqli, "UPDATE tickets SET ticket_status = '$config_ticket_status_id_open' WHERE ticket_id = $ticket_id AND ticket_client_id = $client_id LIMIT 1"); echo "Updated existing ticket.
"; mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Ticket', log_action = 'Update', log_description = 'Email parser: Client contact $from_email updated ticket $config_ticket_prefix$ticket_number ($subject)', log_client_id = $client_id"); diff --git a/dashboard.php b/dashboard.php index 8d20596d..3cc490b6 100644 --- a/dashboard.php +++ b/dashboard.php @@ -89,7 +89,7 @@ if ($user_config_dashboard_financial_enable == 1) { //Define var so it doesnt throw errors in logs $largest_income_month = 0; - + //Get Total income $sql_total_payments_to_invoices = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS total_payments_to_invoices FROM payments WHERE YEAR(payment_date) = $year"); $row = mysqli_fetch_array($sql_total_payments_to_invoices); @@ -169,7 +169,7 @@ if ($user_config_dashboard_financial_enable == 1) { if ($config_module_enable_ticketing && $config_module_enable_accounting) { //Get Unbilled, closed tickets - $sql_unbilled_tickets = mysqli_query($mysqli, "SELECT COUNT('ticket_id') AS unbilled_tickets FROM tickets WHERE ticket_status = 'Closed' AND ticket_billable = 1 AND ticket_invoice_id = 0 AND YEAR(ticket_created_at) = $year"); + $sql_unbilled_tickets = mysqli_query($mysqli, "SELECT COUNT('ticket_id') AS unbilled_tickets FROM tickets WHERE ticket_closed_at IS NOT NULL AND ticket_billable = 1 AND ticket_invoice_id = 0 AND YEAR(ticket_created_at) = $year"); $row = mysqli_fetch_array($sql_unbilled_tickets); $unbilled_tickets = intval($row['unbilled_tickets']); } else { @@ -772,13 +772,14 @@ if ($user_config_dashboard_technical_enable == 1) { $ticket_number = intval($row['ticket_number']); $ticket_subject = nullable_htmlentities($row['ticket_subject']); $ticket_priority = nullable_htmlentities($row['ticket_priority']); - $ticket_status = nullable_htmlentities($row['ticket_status']); + $ticket_status_id = intval($row['ticket_status']); + $ticket_status_name = sanitizeInput(getTicketStatusName($row['ticket_status'])); $ticket_created_at = nullable_htmlentities($row['ticket_created_at']); $ticket_created_at_time_ago = timeAgo($row['ticket_created_at']); $ticket_updated_at = nullable_htmlentities($row['ticket_updated_at']); $ticket_updated_at_time_ago = timeAgo($row['ticket_updated_at']); if (empty($ticket_updated_at)) { - if ($ticket_status == "Closed") { + if (!empty($ticket_closed_at)) { $ticket_updated_at_display = "

Never

"; } else { $ticket_updated_at_display = "

Never

"; @@ -791,17 +792,7 @@ if ($user_config_dashboard_technical_enable == 1) { $contact_id = intval($row['ticket_contact_id']); $contact_name = nullable_htmlentities($row['contact_name']); - if ($ticket_status == "New") { - $ticket_status_color = "danger"; - } elseif ($ticket_status == "Open") { - $ticket_status_color = "primary"; - } elseif ($ticket_status == "On Hold") { - $ticket_status_color = "success"; - } elseif ($ticket_status == "Auto Close") { - $ticket_status_color = "dark"; - } elseif ($ticket_status == "Closed") { - $ticket_status_color = "dark"; - } + $ticket_status_color = getTicketStatusColor($ticket_status_id); if ($ticket_priority == "High") { $ticket_priority_color = "danger"; @@ -831,7 +822,7 @@ if ($user_config_dashboard_technical_enable == 1) { - + diff --git a/database_updates.php b/database_updates.php index 8d7d2d7c..67d8f09c 100644 --- a/database_updates.php +++ b/database_updates.php @@ -1689,8 +1689,69 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) { if (CURRENT_DATABASE_VERSION == '1.1.3') { + mysqli_query($mysqli, "ALTER TABLE `networks` ADD `network_subnet` VARCHAR(200) DEFAULT NULL AFTER `network`"); + mysqli_query($mysqli, "ALTER TABLE `networks` ADD `network_primary_dns` VARCHAR(200) DEFAULT NULL AFTER `network_gateway`"); + mysqli_query($mysqli, "ALTER TABLE `networks` ADD `network_secondary_dns` VARCHAR(200) DEFAULT NULL AFTER `network_primary_dns`"); + mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.1.4'"); + } + + if (CURRENT_DATABASE_VERSION == '1.1.4') { + + // Add Project Templates + mysqli_query($mysqli, "CREATE TABLE `project_templates` ( + `project_template_id` INT(11) NOT NULL AUTO_INCREMENT, + `project_template_name` VARCHAR(200) NOT NULL, + `project_template_description` TEXT DEFAULT NULL, + `project_template_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP(), + `project_template_updated_at` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, + `project_template_archived_at` DATETIME DEFAULT NULL, + PRIMARY KEY (`project_template_id`) + )"); + + // Add Ticket Templates + mysqli_query($mysqli, "CREATE TABLE `ticket_templates` ( + `ticket_template_id` INT(11) NOT NULL AUTO_INCREMENT, + `ticket_template_name` VARCHAR(200) NOT NULL, + `ticket_template_description` TEXT DEFAULT NULL, + `ticket_template_subject` VARCHAR(200) DEFAULT NULL, + `ticket_template_details` LONGTEXT DEFAULT NULL, + `ticket_template_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP(), + `ticket_template_updated_at` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, + `ticket_template_archived_at` DATETIME DEFAULT NULL, + `ticket_template_project_template_id` INT(11) NOT NULL DEFAULT 0, + PRIMARY KEY (`ticket_template_id`) + )"); + + // Add Task Templates + mysqli_query($mysqli, "CREATE TABLE `task_templates` ( + `task_template_id` INT(11) NOT NULL AUTO_INCREMENT, + `task_template_name` VARCHAR(200) NOT NULL, + `task_template_description` TEXT DEFAULT NULL, + `task_template_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP(), + `task_template_updated_at` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, + `task_template_archived_at` DATETIME DEFAULT NULL, + `task_template_ticket_template_id` INT(11) NOT NULL, + PRIMARY KEY (`task_template_id`) + )"); + + mysqli_query($mysqli, "ALTER TABLE `projects` ADD `project_completed_at` DATETIME DEFAULT NULL AFTER `project_updated_at`"); + + mysqli_query($mysqli, "ALTER TABLE `tickets` ADD `ticket_project_id` INT(11) NOT NULL DEFAULT 0 AFTER `ticket_invoice_id`"); + + mysqli_query($mysqli, "ALTER TABLE `tasks` DROP `task_template`"); + mysqli_query($mysqli, "ALTER TABLE `tasks` DROP `task_finish_date`"); + mysqli_query($mysqli, "ALTER TABLE `tasks` DROP `task_project_id`"); + + mysqli_query($mysqli, "ALTER TABLE `projects` DROP `project_template`"); + + mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.1.5'"); + } + + if (CURRENT_DATABASE_VERSION == '1.1.5') { + // Add new ticket_statuses table - mysqli_query($mysqli, "CREATE TABLE `ticket_statuses` ( + mysqli_query($mysqli, + "CREATE TABLE `ticket_statuses` ( `ticket_status_id` INT(11) NOT NULL AUTO_INCREMENT, `ticket_status_name` VARCHAR(200) NOT NULL, `ticket_status_color` VARCHAR(200) NOT NULL, @@ -1702,7 +1763,7 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) { mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'New', ticket_status_color = 'danger'"); // Default ID for new tickets is 1 mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'Open', ticket_status_color = 'primary'"); // 2 mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'On Hold', ticket_status_color = 'success'"); // 3 - mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'Auto Close', ticket_status_color = 'dark'"); // 5 + mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'Auto Close', ticket_status_color = 'dark'"); // 4 mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'Closed', ticket_status_color = 'dark'"); // 5 // Add default values above to settings @@ -1711,13 +1772,20 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) { mysqli_query($mysqli, "ALTER TABLE `settings` ADD `config_ticket_status_id_autoclose` int(1) NOT NULL DEFAULT '4' AFTER `config_ticket_status_id_open`"); mysqli_query($mysqli, "ALTER TABLE `settings` ADD `config_ticket_status_id_closed` int(1) NOT NULL DEFAULT '5' AFTER `config_ticket_status_id_autoclose`"); - mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.1.4'"); + // Update existing tickets to use new values + mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 1 WHERE ticket_status = 'New'"); // New + mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 2 WHERE ticket_status = 'Open'"); // Open + mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 3 WHERE ticket_status = 'On Hold'"); // On Hold + mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 4 WHERE ticket_status = 'Auto Close'"); // Auto Close + mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 5 WHERE ticket_closed_at IS NOT NULL"); // Closed + + mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.1.6'"); } - // if (CURRENT_DATABASE_VERSION == '1.1.4') { - // // Insert queries here required to update to DB version 1.1.5 + // if (CURRENT_DATABASE_VERSION == '1.1.6') { + // // Insert queries here required to update to DB version 1.1.7 // // Then, update the database to the next sequential version - // mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.1.5'"); + // mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.1.7'"); // } } else { diff --git a/database_version.php b/database_version.php index 62e7c706..f933d1f9 100644 --- a/database_version.php +++ b/database_version.php @@ -5,5 +5,5 @@ * It is used in conjunction with database_updates.php */ -DEFINE("LATEST_DATABASE_VERSION", "1.1.4"); +DEFINE("LATEST_DATABASE_VERSION", "1.1.6"); diff --git a/db.sql b/db.sql index c2d9f586..47b15f0f 100644 --- a/db.sql +++ b/db.sql @@ -848,7 +848,10 @@ CREATE TABLE `networks` ( `network_description` text DEFAULT NULL, `network_vlan` int(11) DEFAULT NULL, `network` varchar(200) NOT NULL, + `network_subnet` varchar(200) DEFAULT NULL, `network_gateway` varchar(200) NOT NULL, + `network_primary_dns` varchar(200) DEFAULT NULL, + `network_secondary_dns` varchar(200) DEFAULT NULL, `network_dhcp_range` varchar(200) DEFAULT NULL, `network_notes` text DEFAULT NULL, `network_created_at` datetime NOT NULL DEFAULT current_timestamp(), @@ -928,6 +931,24 @@ CREATE TABLE `products` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `project_templates` +-- + +DROP TABLE IF EXISTS `project_templates`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `project_templates` ( + `project_template_id` int(11) NOT NULL AUTO_INCREMENT, + `project_template_name` varchar(200) NOT NULL, + `project_template_description` text DEFAULT NULL, + `project_template_created_at` datetime NOT NULL DEFAULT current_timestamp(), + `project_template_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(), + `project_template_archived_at` datetime DEFAULT NULL, + PRIMARY KEY (`project_template_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `projects` -- @@ -937,11 +958,11 @@ DROP TABLE IF EXISTS `projects`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `projects` ( `project_id` int(11) NOT NULL AUTO_INCREMENT, - `project_template` tinyint(1) NOT NULL DEFAULT 0, `project_name` varchar(255) NOT NULL, `project_description` text DEFAULT NULL, `project_created_at` datetime NOT NULL DEFAULT current_timestamp(), `project_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(), + `project_completed_at` datetime DEFAULT NULL, `project_archived_at` datetime DEFAULT NULL, `project_client_id` int(11) NOT NULL DEFAULT 0, PRIMARY KEY (`project_id`) @@ -1483,6 +1504,25 @@ CREATE TABLE `tags` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `task_templates` +-- + +DROP TABLE IF EXISTS `task_templates`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `task_templates` ( + `task_template_id` int(11) NOT NULL AUTO_INCREMENT, + `task_template_name` varchar(200) NOT NULL, + `task_template_description` text DEFAULT NULL, + `task_template_created_at` datetime NOT NULL DEFAULT current_timestamp(), + `task_template_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(), + `task_template_archived_at` datetime DEFAULT NULL, + `task_template_ticket_template_id` int(11) NOT NULL, + PRIMARY KEY (`task_template_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `tasks` -- @@ -1492,17 +1532,14 @@ DROP TABLE IF EXISTS `tasks`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `tasks` ( `task_id` int(11) NOT NULL AUTO_INCREMENT, - `task_template` tinyint(1) NOT NULL DEFAULT 0, `task_name` varchar(255) NOT NULL, `task_description` text DEFAULT NULL, - `task_finish_date` date DEFAULT NULL, `task_status` varchar(255) DEFAULT NULL, `task_completed_at` datetime DEFAULT NULL, `task_completed_by` int(11) DEFAULT NULL, `task_created_at` datetime NOT NULL DEFAULT current_timestamp(), `task_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(), `task_ticket_id` int(11) DEFAULT NULL, - `task_project_id` int(11) DEFAULT NULL, PRIMARY KEY (`task_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -1564,17 +1601,38 @@ CREATE TABLE `ticket_replies` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `ticket_templates` +-- + +DROP TABLE IF EXISTS `ticket_templates`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `ticket_templates` ( + `ticket_template_id` int(11) NOT NULL AUTO_INCREMENT, + `ticket_template_name` varchar(200) NOT NULL, + `ticket_template_description` text DEFAULT NULL, + `ticket_template_subject` varchar(200) DEFAULT NULL, + `ticket_template_details` longtext DEFAULT NULL, + `ticket_template_created_at` datetime NOT NULL DEFAULT current_timestamp(), + `ticket_template_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(), + `ticket_template_archived_at` datetime DEFAULT NULL, + `ticket_template_project_template_id` int(11) NOT NULL DEFAULT 0, + PRIMARY KEY (`ticket_template_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `ticket_statuses` -- DROP TABLE IF EXISTS `ticket_statuses`; CREATE TABLE IF NOT EXISTS `ticket_statuses` ( - `ticket_status_id` int(11) NOT NULL AUTO_INCREMENT, - `ticket_status_name` varchar(200) NOT NULL, - `ticket_status_color` varchar(200) NOT NULL, - `ticket_status_active` TINYINT(1) NOT NULL DEFAULT '1', - PRIMARY KEY (`ticket_status_id`) + `ticket_status_id` int(11) NOT NULL AUTO_INCREMENT, + `ticket_status_name` varchar(200) NOT NULL, + `ticket_status_color` varchar(200) NOT NULL, + `ticket_status_active` TINYINT(1) NOT NULL DEFAULT '1', + PRIMARY KEY (`ticket_status_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; -- @@ -1620,7 +1678,7 @@ CREATE TABLE `tickets` ( `ticket_id` int(11) NOT NULL AUTO_INCREMENT, `ticket_prefix` varchar(200) DEFAULT NULL, `ticket_number` int(11) NOT NULL, - `ticket_source` varchar(255) DEFAULT NULL, + `ticket_source` varchar(255) DEFAULT NULL COMMENT 'Where the Ticket Came from\r\nEmail, Client Portal, In-App, Project Template', `ticket_category` varchar(200) DEFAULT NULL, `ticket_subject` varchar(200) NOT NULL, `ticket_details` longtext NOT NULL, @@ -1644,6 +1702,7 @@ CREATE TABLE `tickets` ( `ticket_location_id` int(11) NOT NULL DEFAULT 0, `ticket_asset_id` int(11) NOT NULL DEFAULT 0, `ticket_invoice_id` int(11) NOT NULL DEFAULT 0, + `ticket_project_id` int(11) NOT NULL DEFAULT 0, PRIMARY KEY (`ticket_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -1820,4 +1879,4 @@ CREATE TABLE `vendors` ( /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2024-03-19 17:11:58 +-- As of 2024 03 29 diff --git a/functions.php b/functions.php index fb8d89a6..de0a016e 100644 --- a/functions.php +++ b/functions.php @@ -1142,41 +1142,21 @@ function getTicketStatusColor($ticket_status) { global $mysqli; - if (intval($ticket_status)) { - $status_id = intval($ticket_status); - $row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT * FROM ticket_statuses WHERE ticket_status_id = $status_id LIMIT 1")); + $status_id = intval($ticket_status); + $row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT ticket_status_color FROM ticket_statuses WHERE ticket_status_id = $status_id LIMIT 1")); - if ($row) { - return nullable_htmlentities($row['ticket_status_color']); - } - - // Default return - return "Unknown"; + if ($row) { + return nullable_htmlentities($row['ticket_status_color']); } - // Legacy support for named statuses - if ($ticket_status == "New") { - return "danger"; - } elseif ($ticket_status == "Open") { - return "primary"; - } elseif ($ticket_status == "On Hold") { - return "success"; - } elseif ($ticket_status == "Auto Close") { - return "dark"; - } elseif ($ticket_status == "Closed") { - return "dark"; - } + // Default return + return "Unknown"; } function getTicketStatusName($ticket_status) { global $mysqli; - // Legacy support for named statuses - if (!intval($ticket_status)) { - return $ticket_status; - } - $status_id = intval($ticket_status); $row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT * FROM ticket_statuses WHERE ticket_status_id = $status_id LIMIT 1")); diff --git a/global_search.php b/global_search.php index 14fceb2c..9bb698cf 100644 --- a/global_search.php +++ b/global_search.php @@ -26,7 +26,7 @@ if (isset($_GET['query'])) { AND client_name LIKE '%$query%' ORDER BY client_id DESC LIMIT 5" ); - + $sql_contacts = mysqli_query($mysqli, "SELECT * FROM contacts LEFT JOIN clients ON client_id = contact_client_id WHERE contact_archived_at IS NULL @@ -37,7 +37,7 @@ if (isset($_GET['query'])) { OR contact_mobile LIKE '%$phone_query%') ORDER BY contact_id DESC LIMIT 5" ); - + $sql_vendors = mysqli_query($mysqli, "SELECT * FROM vendors LEFT JOIN clients ON vendor_client_id = client_id WHERE vendor_archived_at IS NULL @@ -52,20 +52,20 @@ if (isset($_GET['query'])) { AND domain_name LIKE '%$query%' ORDER BY domain_id DESC LIMIT 5" ); - + $sql_products = mysqli_query($mysqli, "SELECT * FROM products WHERE product_archived_at IS NULL AND product_name LIKE '%$query%' ORDER BY product_id DESC LIMIT 5" ); - + $sql_documents = mysqli_query($mysqli, "SELECT * FROM documents LEFT JOIN clients on document_client_id = clients.client_id WHERE document_archived_at IS NULL AND MATCH(document_content_raw) AGAINST ('$query') ORDER BY document_id DESC LIMIT 5" ); - + $sql_tickets = mysqli_query($mysqli, "SELECT * FROM tickets LEFT JOIN clients on tickets.ticket_client_id = clients.client_id WHERE ticket_archived_at IS NULL @@ -73,7 +73,7 @@ if (isset($_GET['query'])) { OR ticket_number = '$ticket_num_query') ORDER BY ticket_id DESC LIMIT 5" ); - + $sql_logins = mysqli_query($mysqli, "SELECT * FROM logins LEFT JOIN contacts ON login_contact_id = contact_id LEFT JOIN clients ON login_client_id = client_id @@ -108,10 +108,10 @@ if (isset($_GET['query'])) { ); $q = nullable_htmlentities($_GET['query']); - + ?> - +
@@ -291,7 +291,7 @@ if (isset($_GET['query'])) { $domain_id = intval($row['domain_id']); $client_id = intval($row['client_id']); $client_name = nullable_htmlentities($row['client_name']); - + ?> @@ -308,7 +308,7 @@ if (isset($_GET['query'])) {
- + 0) { ?> @@ -418,7 +418,7 @@ if (isset($_GET['query'])) { $ticket_prefix = nullable_htmlentities($row['ticket_prefix']); $ticket_number = intval($row['ticket_number']); $ticket_subject = nullable_htmlentities($row['ticket_subject']); - $ticket_status = nullable_htmlentities($row['ticket_status']); + $ticket_status = nullable_htmlentities(getTicketStatusName($row['ticket_status'])); $client_name = nullable_htmlentities($row['client_name']); $client_id = intval($row['ticket_client_id']); @@ -598,7 +598,7 @@ if (isset($_GET['query'])) { if (empty($contact_name)) { $contact_name_display = "-"; }else{ - $contact_name_display = "$contact_name"; + $contact_name_display = "$contact_name"; } $contact_archived_at = nullable_htmlentities($row['contact_archived_at']); if (empty($contact_archived_at)) { @@ -652,12 +652,12 @@ if (isset($_GET['query'])) { while ($row = mysqli_fetch_array($sql_ticket_replies)) { $ticket_id = intval($row['ticket_id']); - + // Only output the ticket header if we're at a new ticket if ($ticket_id !== $last_ticket_id) { if ($last_ticket_id !== null) { // Close the previous ticket's card (except for the very first ticket) - echo '
'; + echo ''; } $ticket_prefix = nullable_htmlentities($row['ticket_prefix']); @@ -699,7 +699,7 @@ if (isset($_GET['query'])) { if ($last_ticket_id !== null) { // Close the last ticket's card - echo ''; + echo ''; } ?> @@ -721,4 +721,4 @@ require_once "footer.php"; ?> - \ No newline at end of file + diff --git a/post/ticket.php b/post/ticket.php index edceef98..468020c1 100644 --- a/post/ticket.php +++ b/post/ticket.php @@ -850,16 +850,13 @@ if (isset($_POST['add_ticket_reply'])) { $ticket_id = intval($_POST['ticket_id']); $ticket_reply = mysqli_real_escape_string($mysqli, $_POST['ticket_reply']); - $ticket_status = sanitizeInput($_POST['status']); + $ticket_status = intval($_POST['status']); $ticket_status_name = sanitizeInput(getTicketStatusName($row['ticket_status'])); // Handle the time inputs for hours, minutes, and seconds $hours = intval($_POST['hours']); $minutes = intval($_POST['minutes']); $seconds = intval($_POST['seconds']); - //var_dump($_POST); - //exit; - // Combine into a single time string $ticket_reply_time_worked = sanitizeInput(sprintf("%02d:%02d:%02d", $hours, $minutes, $seconds)); @@ -877,7 +874,7 @@ if (isset($_POST['add_ticket_reply'])) { $ticket_reply_id = mysqli_insert_id($mysqli); // Update Ticket Last Response Field - mysqli_query($mysqli, "UPDATE tickets SET ticket_status = '$ticket_status' WHERE ticket_id = $ticket_id"); + mysqli_query($mysqli, "UPDATE tickets SET ticket_status = $ticket_status WHERE ticket_id = $ticket_id"); if ($ticket_status == $config_ticket_status_id_closed || $ticket_status == 'Closed') { mysqli_query($mysqli, "UPDATE tickets SET ticket_closed_at = NOW() WHERE ticket_id = $ticket_id"); diff --git a/report_ticket_by_client.php b/report_ticket_by_client.php index b182850d..96b967e4 100644 --- a/report_ticket_by_client.php +++ b/report_ticket_by_client.php @@ -94,12 +94,12 @@ $sql_clients = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients $ticket_raised_count = intval($row['ticket_raised_count']); // Calculate total tickets raised in period that are closed - $sql_ticket_closed_count = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS ticket_closed_count FROM tickets WHERE YEAR(ticket_created_at) = $year AND ticket_client_id = $client_id AND ticket_status = 'Closed'"); + $sql_ticket_closed_count = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS ticket_closed_count FROM tickets WHERE YEAR(ticket_created_at) = $year AND ticket_client_id = $client_id AND ticket_closed_at IS NOT NULL"); $row = mysqli_fetch_array($sql_ticket_closed_count); $ticket_closed_count = intval($row['ticket_closed_count']); // Used to calculate average time to close tickets that were raised in period specified - $sql_tickets = mysqli_query($mysqli, "SELECT ticket_created_at, ticket_closed_at FROM tickets WHERE YEAR(ticket_created_at) = $year AND ticket_client_id = $client_id AND ticket_status = 'Closed' AND ticket_closed_at IS NOT NULL"); + $sql_tickets = mysqli_query($mysqli, "SELECT ticket_created_at, ticket_closed_at FROM tickets WHERE YEAR(ticket_created_at) = $year AND ticket_client_id = $client_id AND ticket_closed_at IS NOT NULL"); if ($ticket_raised_count > 0) { diff --git a/ticket.php b/ticket.php index 2b030fd7..08231ff9 100644 --- a/ticket.php +++ b/ticket.php @@ -252,9 +252,9 @@ if (isset($_GET['ticket_id'])) {
-

Ticket

+

Ticket

- +
- +
- +
@@ -337,16 +337,15 @@ if (isset($_GET['ticket_id'])) {
@@ -608,7 +607,7 @@ if (isset($_GET['ticket_id'])) { if ($prev_ticket_row) { $prev_ticket_id = intval($prev_ticket_row['ticket_id']); $prev_ticket_subject = nullable_htmlentities($prev_ticket_row['ticket_subject']); - $prev_ticket_status = nullable_htmlentities($prev_ticket_row['ticket_status']); + $prev_ticket_status = nullable_htmlentities( getTicketStatusName($prev_ticket_row['ticket_status'])); ?>
@@ -682,7 +681,7 @@ if (isset($_GET['ticket_id'])) { + if (empty ($ticket_closed_at)) { ?>
Scheduled:
@@ -908,7 +907,7 @@ if (isset($_GET['ticket_id'])) {
-
@@ -926,7 +925,7 @@ if (isset($_GET['ticket_id'])) { + if (empty($ticket_closed_at)) { ?> Close Ticket @@ -969,7 +968,7 @@ require_once "footer.php"; - + diff --git a/ticket_assign_modal.php b/ticket_assign_modal.php index eaf75208..de84f7c0 100644 --- a/ticket_assign_modal.php +++ b/ticket_assign_modal.php @@ -9,7 +9,7 @@
- + "; } ?> + $ticket_scheduled_for
"; } ?> @@ -460,7 +464,7 @@ $user_active_assigned_tickets = intval($row['total_tickets_assigned']); Date: Fri, 29 Mar 2024 11:32:46 +0000 Subject: [PATCH 5/7] Ticket Statuses from DB / add project id --- tickets.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tickets.php b/tickets.php index 646897de..cad4d9ee 100644 --- a/tickets.php +++ b/tickets.php @@ -331,6 +331,7 @@ $user_active_assigned_tickets = intval($row['total_tickets_assigned']); } else { $ticket_updated_at_display = "$ticket_updated_at_time_ago
$ticket_updated_at"; } + $project_id = intval($row['ticket_project_id']); $client_id = intval($row['ticket_client_id']); $client_name = nullable_htmlentities($row['client_name']); From a961b8aa72313d80f3115c956e5da1e996b5c9ee Mon Sep 17 00:00:00 2001 From: Marcus Hill Date: Fri, 29 Mar 2024 12:08:02 +0000 Subject: [PATCH 6/7] Ticket Statuses from DB / touchups --- tickets.php | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/tickets.php b/tickets.php index e0ead524..97188353 100644 --- a/tickets.php +++ b/tickets.php @@ -367,14 +367,20 @@ $user_active_assigned_tickets = intval($row['total_tickets_assigned']); } // Get who last updated the ticket - to be shown in the last Response column - $ticket_reply_type = "Client"; // Default to client for unreplied tickets - $ticket_reply_by_display = ""; // Default none - $sql_ticket_reply = mysqli_query($mysqli, "SELECT ticket_reply_type, ticket_reply_created_at, contact_name, user_name FROM ticket_replies - LEFT JOIN users ON ticket_reply_by = user_id - LEFT JOIN contacts ON ticket_reply_by = contact_id - WHERE ticket_reply_ticket_id = $ticket_id - AND ticket_reply_archived_at IS NULL - ORDER BY ticket_reply_id DESC LIMIT 1" + + // Defaults to prevent undefined errors + $ticket_reply_created_at = ""; + $ticket_reply_created_at_time_ago = ""; + $ticket_reply_by_display = ""; + $ticket_reply_type = "Client"; // Default to client for un-replied tickets + + $sql_ticket_reply = mysqli_query($mysqli, + "SELECT ticket_reply_type, ticket_reply_created_at, contact_name, user_name FROM ticket_replies + LEFT JOIN users ON ticket_reply_by = user_id + LEFT JOIN contacts ON ticket_reply_by = contact_id + WHERE ticket_reply_ticket_id = $ticket_id + AND ticket_reply_archived_at IS NULL + ORDER BY ticket_reply_id DESC LIMIT 1" ); $row = mysqli_fetch_array($sql_ticket_reply); From 7df1d419faba9b6772de166f574c5180dbf6ea8c Mon Sep 17 00:00:00 2001 From: Marcus Hill Date: Fri, 29 Mar 2024 23:20:52 +0000 Subject: [PATCH 7/7] Ticket Statuses from DB / use left join instead of a function, hard-code system statuses --- client_tickets.php | 10 +++++----- cron.php | 16 ++++++---------- cron_ticket_email_parser.php | 10 +++++----- database_updates.php | 8 +------- db.sql | 6 +----- get_settings.php | 4 ---- portal/portal_functions.php | 6 +++--- portal/portal_post.php | 6 +++--- portal/ticket.php | 24 ++++++++++++++++++------ portal/ticket_view_all.php | 11 ++++------- portal/tickets.php | 17 +++++++---------- post/ticket.php | 35 ++++++++++++++++------------------- ticket.php | 36 +++++++++++++++++++----------------- tickets.php | 8 ++++---- 14 files changed, 92 insertions(+), 105 deletions(-) diff --git a/client_tickets.php b/client_tickets.php index d51bde86..284acdbb 100644 --- a/client_tickets.php +++ b/client_tickets.php @@ -38,6 +38,7 @@ $sql = mysqli_query( LEFT JOIN assets ON ticket_asset_id = asset_id LEFT JOIN locations ON ticket_location_id = location_id LEFT JOIN vendors ON ticket_vendor_id = vendor_id + LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id WHERE ticket_client_id = $client_id AND $ticket_status_snippet AND $ticket_billable_snippet @@ -140,8 +141,9 @@ $total_scheduled_tickets = intval($row['total_scheduled_tickets']); $ticket_number = nullable_htmlentities($row['ticket_number']); $ticket_subject = nullable_htmlentities($row['ticket_subject']); $ticket_priority = nullable_htmlentities($row['ticket_priority']); - $ticket_status_id = intval($row['ticket_status']); - $ticket_status_name = sanitizeInput(getTicketStatusName($row['ticket_status'])); + $ticket_status_id = intval($row['ticket_status_id']); + $ticket_status_name = nullable_htmlentities($row['ticket_status_name']); + $ticket_status_color = nullable_htmlentities($row['ticket_status_color']); $ticket_billable = intval($row['ticket_billable']); $ticket_created_at = nullable_htmlentities($row['ticket_created_at']); $ticket_created_at_time_ago = timeAgo($row['ticket_created_at']); @@ -158,8 +160,6 @@ $total_scheduled_tickets = intval($row['total_scheduled_tickets']); } $ticket_closed_at = nullable_htmlentities($row['ticket_closed_at']); - $ticket_status_color = getTicketStatusColor($ticket_status_id); - if ($ticket_priority == "High") { $ticket_priority_display = "$ticket_priority"; } elseif ($ticket_priority == "Medium") { @@ -180,7 +180,7 @@ $total_scheduled_tickets = intval($row['total_scheduled_tickets']); } else { $ticket_assigned_to_display = nullable_htmlentities($row['user_name']); } - + $project_id = intval($row['ticket_project_id']); $contact_name = nullable_htmlentities($row['contact_name']); diff --git a/cron.php b/cron.php index 5a168af9..a8d9f4bd 100644 --- a/cron.php +++ b/cron.php @@ -52,10 +52,6 @@ $config_ticket_client_general_notifications = intval($row['config_ticket_client_ $config_ticket_autoclose = intval($row['config_ticket_autoclose']); $config_ticket_autoclose_hours = intval($row['config_ticket_autoclose_hours']); $config_ticket_new_ticket_notification_email = sanitizeInput($row['config_ticket_new_ticket_notification_email']); -$config_ticket_status_id_new = intval($row['config_ticket_status_id_new']); -$config_ticket_status_id_open = intval($row['config_ticket_status_id_open']); -$config_ticket_status_id_autoclose = intval($row['config_ticket_status_id_autoclose']); -$config_ticket_status_id_closed = intval($row['config_ticket_status_id_closed']); // Get Config for Telemetry $config_theme = $row['config_theme']; @@ -229,7 +225,7 @@ foreach ($warranty_alert_array as $day) { // Notify of New Tickets // Get Ticket Pending Assignment -$sql_tickets_pending_assignment = mysqli_query($mysqli,"SELECT ticket_id FROM tickets WHERE ticket_status = '$config_ticket_status_id_new'"); +$sql_tickets_pending_assignment = mysqli_query($mysqli,"SELECT ticket_id FROM tickets WHERE ticket_status = 1"); $tickets_pending_assignment = mysqli_num_rows($sql_tickets_pending_assignment); @@ -260,9 +256,9 @@ if (mysqli_num_rows($sql_scheduled_tickets) > 0) { $contact_id = intval($row['scheduled_ticket_contact_id']); $asset_id = intval($row['scheduled_ticket_asset_id']); - $ticket_status = $config_ticket_status_id_new; // Default + $ticket_status = 1; // Default if ($assigned_id > 0) { - $ticket_status = $config_ticket_status_id_open; // Set to open if we've auto-assigned an agent + $ticket_status = 2; // Set to open if we've auto-assigned an agent } // Assign this new ticket the next ticket number @@ -383,7 +379,7 @@ if ($config_ticket_autoclose == 1) { $sql_tickets_to_chase = mysqli_query( $mysqli, "SELECT * FROM tickets - WHERE ticket_status = '$config_ticket_status_id_autoclose' + WHERE ticket_status = 4 AND ticket_updated_at < NOW() - INTERVAL $config_ticket_autoclose_hours HOUR" ); @@ -397,7 +393,7 @@ if ($config_ticket_autoclose == 1) { $ticket_assigned_to = sanitizeInput($row['ticket_assigned_to']); $client_id = intval($row['ticket_client_id']); - mysqli_query($mysqli,"UPDATE tickets SET ticket_status = '$config_ticket_status_id_closed', ticket_closed_at = NOW(), ticket_closed_by = $ticket_assigned_to WHERE ticket_id = $ticket_id"); + mysqli_query($mysqli,"UPDATE tickets SET ticket_status = 5, ticket_closed_at = NOW(), ticket_closed_by = $ticket_assigned_to WHERE ticket_id = $ticket_id"); //Logging mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Ticket', log_action = 'Closed', log_description = '$ticket_prefix$ticket_number auto closed', log_entity_id = $ticket_id"); @@ -412,7 +408,7 @@ if ($config_ticket_autoclose == 1) { "SELECT contact_name, contact_email, ticket_id, ticket_prefix, ticket_number, ticket_subject, ticket_status, ticket_client_id FROM tickets LEFT JOIN clients ON ticket_client_id = client_id LEFT JOIN contacts ON ticket_contact_id = contact_id - WHERE ticket_status = '$config_ticket_status_id_autoclose' + WHERE ticket_status = 4 AND ticket_updated_at < NOW() - INTERVAL 48 HOUR" ); diff --git a/cron_ticket_email_parser.php b/cron_ticket_email_parser.php index fde69c29..152797f1 100644 --- a/cron_ticket_email_parser.php +++ b/cron_ticket_email_parser.php @@ -110,7 +110,7 @@ $allowed_extensions = array('jpg', 'jpeg', 'gif', 'png', 'webp', 'pdf', 'txt', ' function addTicket($contact_id, $contact_name, $contact_email, $client_id, $date, $subject, $message, $attachments) { // Access global variables - global $mysqli,$config_app_name, $company_name, $company_phone, $config_ticket_prefix, $config_ticket_client_general_notifications, $config_ticket_new_ticket_notification_email, $config_ticket_status_id_new, $config_ticket_status_id_closed, $config_base_url, $config_ticket_from_name, $config_ticket_from_email, $config_smtp_host, $config_smtp_port, $config_smtp_encryption, $config_smtp_username, $config_smtp_password, $allowed_extensions; + global $mysqli,$config_app_name, $company_name, $company_phone, $config_ticket_prefix, $config_ticket_client_general_notifications, $config_ticket_new_ticket_notification_email, $config_base_url, $config_ticket_from_name, $config_ticket_from_email, $config_smtp_host, $config_smtp_port, $config_smtp_encryption, $config_smtp_username, $config_smtp_password, $allowed_extensions; // Get the next Ticket Number and add 1 for the new ticket number $ticket_number_sql = mysqli_fetch_array(mysqli_query($mysqli, "SELECT config_ticket_next_number FROM settings WHERE company_id = 1")); @@ -122,7 +122,7 @@ function addTicket($contact_id, $contact_name, $contact_email, $client_id, $date $message = nl2br($message); $message = mysqli_escape_string($mysqli, "Email from: $contact_email at $date:-

$message"); - mysqli_query($mysqli, "INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_subject = '$subject', ticket_details = '$message', ticket_priority = 'Low', ticket_status = '$config_ticket_status_id_new', ticket_created_by = 0, ticket_contact_id = $contact_id, ticket_client_id = $client_id"); + mysqli_query($mysqli, "INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_subject = '$subject', ticket_details = '$message', ticket_priority = 'Low', ticket_status = 1, ticket_created_by = 0, ticket_contact_id = $contact_id, ticket_client_id = $client_id"); $id = mysqli_insert_id($mysqli); // Logging @@ -213,7 +213,7 @@ function addReply($from_email, $date, $subject, $ticket_number, $message, $attac // Add email as a comment/reply to an existing ticket // Access global variables - global $mysqli, $config_app_name, $company_name, $company_phone, $config_ticket_prefix, $config_ticket_status_id_open, $config_ticket_status_id_closed, $config_base_url, $config_ticket_from_name, $config_ticket_from_email, $config_smtp_host, $config_smtp_port, $config_smtp_encryption, $config_smtp_username, $config_smtp_password, $allowed_extensions; + global $mysqli, $config_app_name, $company_name, $company_phone, $config_ticket_prefix, $config_base_url, $config_ticket_from_name, $config_ticket_from_email, $config_smtp_host, $config_smtp_port, $config_smtp_encryption, $config_smtp_username, $config_smtp_password, $allowed_extensions; // Set default reply type $ticket_reply_type = 'Client'; @@ -243,7 +243,7 @@ function addReply($from_email, $date, $subject, $ticket_number, $message, $attac $client_name = sanitizeInput($row['client_name']); // Check ticket isn't closed - tickets can't be re-opened - if ($ticket_status == $config_ticket_status_id_closed) { + if ($ticket_status == 5) { mysqli_query($mysqli, "INSERT INTO notifications SET notification_type = 'Ticket', notification = 'Email parser: $from_email attempted to re-open ticket $config_ticket_prefix$ticket_number (ID $ticket_id) - check inbox manually to see email', notification_action = 'ticket.php?ticket_id=$ticket_id', notification_client_id = $client_id"); $email_subject = "Action required: This ticket is already closed"; @@ -360,7 +360,7 @@ function addReply($from_email, $date, $subject, $ticket_number, $message, $attac } // Update Ticket Last Response Field & set ticket to open as client has replied - mysqli_query($mysqli, "UPDATE tickets SET ticket_status = '$config_ticket_status_id_open' WHERE ticket_id = $ticket_id AND ticket_client_id = $client_id LIMIT 1"); + mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 2 WHERE ticket_id = $ticket_id AND ticket_client_id = $client_id LIMIT 1"); echo "Updated existing ticket.
"; mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Ticket', log_action = 'Update', log_description = 'Email parser: Client contact $from_email updated ticket $config_ticket_prefix$ticket_number ($subject)', log_client_id = $client_id"); diff --git a/database_updates.php b/database_updates.php index aff41310..e3a5f101 100644 --- a/database_updates.php +++ b/database_updates.php @@ -1758,19 +1758,13 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) { PRIMARY KEY (`ticket_status_id`) )"); - // Pre-seed ticket statuses + // Pre-seed default system/built-in ticket statuses mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'New', ticket_status_color = 'danger'"); // Default ID for new tickets is 1 mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'Open', ticket_status_color = 'primary'"); // 2 mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'On Hold', ticket_status_color = 'success'"); // 3 mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'Auto Close', ticket_status_color = 'dark'"); // 4 mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'Closed', ticket_status_color = 'dark'"); // 5 - // Add default values above to settings - mysqli_query($mysqli, "ALTER TABLE `settings` ADD `config_ticket_status_id_new` int(1) NOT NULL DEFAULT '1' AFTER `config_ticket_new_ticket_notification_email`"); - mysqli_query($mysqli, "ALTER TABLE `settings` ADD `config_ticket_status_id_open` int(1) NOT NULL DEFAULT '2' AFTER `config_ticket_status_id_new`"); - mysqli_query($mysqli, "ALTER TABLE `settings` ADD `config_ticket_status_id_autoclose` int(1) NOT NULL DEFAULT '4' AFTER `config_ticket_status_id_open`"); - mysqli_query($mysqli, "ALTER TABLE `settings` ADD `config_ticket_status_id_closed` int(1) NOT NULL DEFAULT '5' AFTER `config_ticket_status_id_autoclose`"); - // Update existing tickets to use new values mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 1 WHERE ticket_status = 'New'"); // New mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 2 WHERE ticket_status = 'Open'"); // Open diff --git a/db.sql b/db.sql index 5478e4eb..b64a7bfd 100644 --- a/db.sql +++ b/db.sql @@ -1317,10 +1317,6 @@ CREATE TABLE `settings` ( `config_ticket_autoclose` tinyint(1) NOT NULL DEFAULT 0, `config_ticket_autoclose_hours` int(5) NOT NULL DEFAULT 72, `config_ticket_new_ticket_notification_email` varchar(200) DEFAULT NULL, - `config_ticket_status_id_new` int(1) NOT NULL DEFAULT 1, - `config_ticket_status_id_open` int(1) NOT NULL DEFAULT 2, - `config_ticket_status_id_autoclose` int(1) NOT NULL DEFAULT 4, - `config_ticket_status_id_closed` int(1) NOT NULL DEFAULT 5, `config_enable_cron` tinyint(1) NOT NULL DEFAULT 0, `config_cron_key` varchar(255) DEFAULT NULL, `config_recurring_auto_send_invoice` tinyint(1) NOT NULL DEFAULT 1, @@ -1879,4 +1875,4 @@ CREATE TABLE `vendors` ( /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- As of 2024 03 29 \ No newline at end of file +-- As of 2024 03 29 diff --git a/get_settings.php b/get_settings.php index 92c1ef16..5a3dbc2d 100644 --- a/get_settings.php +++ b/get_settings.php @@ -68,10 +68,6 @@ $config_ticket_client_general_notifications = intval($row['config_ticket_client_ $config_ticket_autoclose = intval($row['config_ticket_autoclose']); $config_ticket_autoclose_hours = intval($row['config_ticket_autoclose_hours']); $config_ticket_new_ticket_notification_email = $row['config_ticket_new_ticket_notification_email']; -$config_ticket_status_id_new = intval($row['config_ticket_status_id_new']); -$config_ticket_status_id_open = intval($row['config_ticket_status_id_open']); -$config_ticket_status_id_autoclose = intval($row['config_ticket_status_id_autoclose']); -$config_ticket_status_id_closed = intval($row['config_ticket_status_id_closed']); // Cron $config_enable_cron = intval($row['config_enable_cron']); diff --git a/portal/portal_functions.php b/portal/portal_functions.php index af4783ae..2b960e13 100644 --- a/portal/portal_functions.php +++ b/portal/portal_functions.php @@ -11,15 +11,15 @@ function verifyContactTicketAccess($requested_ticket_id, $expected_ticket_state) { // Access the global variables - global $mysqli, $session_contact_id, $session_contact_primary, $session_contact_is_technical_contact, $session_client_id, $config_ticket_status_id_closed; + global $mysqli, $session_contact_id, $session_contact_primary, $session_contact_is_technical_contact, $session_client_id; // Setup if ($expected_ticket_state == "Closed") { // Closed tickets - $ticket_state_snippet = "ticket_status = 'Closed' OR ticket_status = $config_ticket_status_id_closed"; + $ticket_state_snippet = "ticket_status = 5"; } else { // Open (working/hold) tickets - $ticket_state_snippet = "ticket_status != 'Closed' or ticket_status != $config_ticket_status_id_closed"; + $ticket_state_snippet = "ticket_status != 5"; } // Verify the contact has access to the provided ticket ID diff --git a/portal/portal_post.php b/portal/portal_post.php index f22dbf2d..b98a2555 100644 --- a/portal/portal_post.php +++ b/portal/portal_post.php @@ -33,7 +33,7 @@ if (isset($_POST['add_ticket'])) { $new_config_ticket_next_number = $config_ticket_next_number + 1; mysqli_query($mysqli, "UPDATE settings SET config_ticket_next_number = $new_config_ticket_next_number WHERE company_id = 1"); - mysqli_query($mysqli, "INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_subject = '$subject', ticket_details = '$details', ticket_priority = '$priority', ticket_status = $config_ticket_status_id_new, ticket_created_by = 0, ticket_contact_id = $contact, ticket_client_id = $client_id"); + mysqli_query($mysqli, "INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_subject = '$subject', ticket_details = '$details', ticket_priority = '$priority', ticket_status = 1, ticket_created_by = 0, ticket_contact_id = $contact, ticket_client_id = $client_id"); $id = mysqli_insert_id($mysqli); // Notify agent DL of the new ticket, if populated with a valid email @@ -86,7 +86,7 @@ if (isset($_POST['add_ticket_comment'])) { $ticket_reply_id = mysqli_insert_id($mysqli); // Update Ticket Last Response Field & set ticket to open as client has replied - mysqli_query($mysqli, "UPDATE tickets SET ticket_status = $config_ticket_status_id_open WHERE ticket_id = $ticket_id AND ticket_client_id = $session_client_id LIMIT 1"); + mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 2 WHERE ticket_id = $ticket_id AND ticket_client_id = $session_client_id LIMIT 1"); // Get ticket details & Notify the assigned tech (if any) @@ -201,7 +201,7 @@ if (isset($_GET['close_ticket'])) { if (verifyContactTicketAccess($ticket_id, "Open")) { // Close ticket - mysqli_query($mysqli, "UPDATE tickets SET ticket_status = $config_ticket_status_id_closed, ticket_closed_at = NOW() WHERE ticket_id = $ticket_id AND ticket_client_id = $session_client_id"); + 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"); // 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"); diff --git a/portal/ticket.php b/portal/ticket.php index 03a60c1d..7b6725b7 100644 --- a/portal/ticket.php +++ b/portal/ticket.php @@ -20,10 +20,21 @@ if (isset($_GET['id']) && intval($_GET['id'])) { if ($session_contact_primary == 1 || $session_contact_is_technical_contact) { // For a primary / technical contact viewing all tickets - $ticket_sql = mysqli_query($mysqli, "SELECT * FROM tickets LEFT JOIN users on ticket_assigned_to = user_id WHERE ticket_id = $ticket_id AND ticket_client_id = $session_client_id"); + $ticket_sql = mysqli_query($mysqli, + "SELECT * FROM tickets + LEFT JOIN users on ticket_assigned_to = user_id + LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id + WHERE ticket_id = $ticket_id AND ticket_client_id = $session_client_id" + ); + } else { // For a user viewing their own ticket - $ticket_sql = mysqli_query($mysqli, "SELECT * FROM tickets LEFT JOIN users on ticket_assigned_to = user_id WHERE ticket_id = $ticket_id AND ticket_client_id = $session_client_id AND ticket_contact_id = $session_contact_id"); + $ticket_sql = mysqli_query($mysqli, + "SELECT * FROM tickets + LEFT JOIN users on ticket_assigned_to = user_id + LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id + WHERE ticket_id = $ticket_id AND ticket_client_id = $session_client_id AND ticket_contact_id = $session_contact_id" + ); } $ticket_row = mysqli_fetch_array($ticket_sql); @@ -32,11 +43,12 @@ if (isset($_GET['id']) && intval($_GET['id'])) { $ticket_prefix = nullable_htmlentities($ticket_row['ticket_prefix']); $ticket_number = intval($ticket_row['ticket_number']); - $ticket_status = sanitizeInput(getTicketStatusName($ticket_row['ticket_status'])); + $ticket_status = nullable_htmlentities($ticket_row['ticket_status_name']); $ticket_priority = nullable_htmlentities($ticket_row['ticket_priority']); $ticket_subject = nullable_htmlentities($ticket_row['ticket_subject']); $ticket_details = $purifier->purify($ticket_row['ticket_details']); $ticket_assigned_to = nullable_htmlentities($ticket_row['user_name']); + $ticket_closed_at = nullable_htmlentities($ticket_row['ticket_closed_at']); $ticket_feedback = nullable_htmlentities($ticket_row['ticket_feedback']); ?> @@ -56,7 +68,7 @@ if (isset($_GET['id']) && intval($_GET['id'])) {

Ticket + if (empty($ticket_closed_at)) { ?> Close ticket

@@ -70,7 +82,7 @@ if (isset($_GET['id']) && intval($_GET['id'])) {
Priority:
- + Assigned to:

@@ -81,7 +93,7 @@ if (isset($_GET['id']) && intval($_GET['id'])) { - + diff --git a/portal/ticket_view_all.php b/portal/ticket_view_all.php index f22f5c5f..8abefd09 100644 --- a/portal/ticket_view_all.php +++ b/portal/ticket_view_all.php @@ -16,19 +16,16 @@ if ($session_contact_primary == 0 && !$session_contact_is_technical_contact) { if (!isset($_GET['status'])) { // If nothing is set, assume we only want to see open tickets $status = 'Open'; - $ticket_status_snippet = "ticket_status != 'Closed'"; -} elseif (isset($_GET['status']) && ($_GET['status']) == 'Open') { - $status = 'Open'; - $ticket_status_snippet = "ticket_status != 'Closed'"; + $ticket_status_snippet = "ticket_status != 5"; } elseif (isset($_GET['status']) && ($_GET['status']) == 'Closed') { $status = 'Closed'; - $ticket_status_snippet = "ticket_status = 'Closed'"; + $ticket_status_snippet = "ticket_status = 5"; } else { $status = '%'; $ticket_status_snippet = "ticket_status LIKE '%'"; } -$all_tickets = mysqli_query($mysqli, "SELECT * FROM tickets LEFT JOIN contacts ON ticket_contact_id = contact_id WHERE $ticket_status_snippet AND ticket_client_id = $session_client_id ORDER BY ticket_id DESC"); +$all_tickets = mysqli_query($mysqli, "SELECT * FROM tickets LEFT JOIN contacts ON ticket_contact_id = contact_id LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id WHERE $ticket_status_snippet AND ticket_client_id = $session_client_id ORDER BY ticket_id DESC"); ?>

All tickets

@@ -61,7 +58,7 @@ $all_tickets = mysqli_query($mysqli, "SELECT * FROM tickets LEFT JOIN contacts O $ticket_prefix = nullable_htmlentities($row['ticket_prefix']); $ticket_number = intval($row['ticket_number']); $ticket_subject = nullable_htmlentities($row['ticket_subject']); - $ticket_status = sanitizeInput(getTicketStatusName($row['ticket_status'])); + $ticket_status = nullable_htmlentities($row['ticket_status_name']); $ticket_contact_name = nullable_htmlentities($row['contact_name']); echo ""; diff --git a/portal/tickets.php b/portal/tickets.php index 940cb358..523d5435 100644 --- a/portal/tickets.php +++ b/portal/tickets.php @@ -13,32 +13,29 @@ require_once "inc_portal.php"; if (!isset($_GET['status'])) { // If nothing is set, assume we only want to see open tickets $status = 'Open'; - $ticket_status_snippet = "ticket_status != $config_ticket_status_id_closed AND ticket_status != 'Closed'"; -} elseif (isset($_GET['status']) && ($_GET['status']) == 'Open') { - $status = 'Open'; - $ticket_status_snippet = "ticket_status != $config_ticket_status_id_closed AND ticket_status != 'Closed'"; + $ticket_status_snippet = "ticket_status != 5 AND ticket_status != 'Closed'"; } elseif (isset($_GET['status']) && ($_GET['status']) == 'Closed') { $status = 'Closed'; - $ticket_status_snippet = "ticket_status = $config_ticket_status_id_closed OR ticket_status = 'Closed'"; + $ticket_status_snippet = "ticket_status = 5 OR ticket_status = 'Closed'"; } else { $status = '%'; $ticket_status_snippet = "ticket_status LIKE '%'"; } -$contact_tickets = mysqli_query($mysqli, "SELECT * FROM tickets LEFT JOIN contacts ON ticket_contact_id = contact_id WHERE $ticket_status_snippet AND ticket_contact_id = $session_contact_id AND ticket_client_id = $session_client_id ORDER BY ticket_id DESC"); +$contact_tickets = mysqli_query($mysqli, "SELECT * FROM tickets LEFT JOIN contacts ON ticket_contact_id = contact_id LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id WHERE $ticket_status_snippet AND ticket_contact_id = $session_contact_id AND ticket_client_id = $session_client_id ORDER BY ticket_id DESC"); //Get Total tickets closed -$sql_total_tickets_closed = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS total_tickets_closed FROM tickets WHERE ticket_status = $config_ticket_status_id_closed OR ticket_status = 'Closed' AND ticket_client_id = $session_client_id AND ticket_contact_id = $session_contact_id"); +$sql_total_tickets_closed = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS total_tickets_closed FROM tickets WHERE ticket_closed_at IS NOT NULL AND ticket_client_id = $session_client_id AND ticket_contact_id = $session_contact_id"); $row = mysqli_fetch_array($sql_total_tickets_closed); $total_tickets_closed = intval($row['total_tickets_closed']); //Get Total tickets open -$sql_total_tickets_open = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS total_tickets_open FROM tickets WHERE ticket_status != $config_ticket_status_id_closed AND ticket_status != 'Closed' AND ticket_client_id = $session_client_id AND ticket_contact_id = $session_contact_id"); +$sql_total_tickets_open = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS total_tickets_open FROM tickets WHERE ticket_closed_at IS NULL AND ticket_client_id = $session_client_id AND ticket_contact_id = $session_contact_id"); $row = mysqli_fetch_array($sql_total_tickets_open); $total_tickets_open = intval($row['total_tickets_open']); //Get Total tickets -$sql_total_tickets = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS total_tickets FROM tickets WHERE ticket_client_id = $session_client_id AND ticket_contact_id = $session_contact_id"); +$sql_total_tickets = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS total_tickets FROM tickets WHERE ticket_client_id = $session_client_id AND ticket_contact_id = $session_contact_id"); $row = mysqli_fetch_array($sql_total_tickets); $total_tickets = intval($row['total_tickets']); @@ -65,7 +62,7 @@ $total_tickets = intval($row['total_tickets']); $ticket_prefix = nullable_htmlentities($row['ticket_prefix']); $ticket_number = intval($row['ticket_number']); $ticket_subject = nullable_htmlentities($row['ticket_subject']); - $ticket_status = sanitizeInput(getTicketStatusName($row['ticket_status'])); + $ticket_status = nullable_htmlentities($row['ticket_status_name']); ?> diff --git a/post/ticket.php b/post/ticket.php index e3f302ef..5da65657 100644 --- a/post/ticket.php +++ b/post/ticket.php @@ -11,9 +11,9 @@ if (isset($_POST['add_ticket'])) { $client_id = intval($_POST['client']); $assigned_to = intval($_POST['assigned_to']); if ($assigned_to == 0) { - $ticket_status = $config_ticket_status_id_new; + $ticket_status = 1; } else { - $ticket_status = $config_ticket_status_id_open; + $ticket_status = 2; } $contact = intval($_POST['contact']); $subject = sanitizeInput($_POST['subject']); @@ -63,7 +63,7 @@ if (isset($_POST['add_ticket'])) { // Check that task_name is not-empty (For some reason the !empty on the array doesnt work here like in watchers) if (!empty($task_name)) { mysqli_query($mysqli,"INSERT INTO tasks SET task_name = '$task_name', task_ticket_id = $ticket_id"); - } + } } } @@ -345,14 +345,9 @@ if (isset($_POST['assign_ticket'])) { $assigned_to = intval($_POST['assigned_to']); $ticket_status = sanitizeInput($_POST['ticket_status']); - // TODO: Remove this legacy if - if ($ticket_status == 'New' && $assigned_to !== 0) { - $ticket_status = $config_ticket_status_id_open; - } - - // New - if ($ticket_status == $config_ticket_status_id_new && $assigned_to !== 0) { - $ticket_status = $config_ticket_status_id_open; + // New > Open as assigned + if ($ticket_status == 1 && $assigned_to !== 0) { + $ticket_status = 2; } // Allow for un-assigning tickets @@ -377,7 +372,7 @@ if (isset($_POST['assign_ticket'])) { } // Get & verify ticket details - $ticket_details_sql = mysqli_query($mysqli, "SELECT ticket_prefix, ticket_number, ticket_subject, ticket_client_id, client_name FROM tickets LEFT JOIN clients ON ticket_client_id = client_id WHERE ticket_id = '$ticket_id' AND ticket_status != $config_ticket_status_id_closed AND ticket_status != 'Closed'"); + $ticket_details_sql = mysqli_query($mysqli, "SELECT ticket_prefix, ticket_number, ticket_subject, ticket_client_id, client_name FROM tickets LEFT JOIN clients ON ticket_client_id = client_id WHERE ticket_id = '$ticket_id' AND ticket_status != 5"); $ticket_details = mysqli_fetch_array($ticket_details_sql); $ticket_prefix = sanitizeInput($ticket_details['ticket_prefix']); @@ -447,15 +442,16 @@ if (isset($_GET['delete_ticket'])) { $ticket_id = intval($_GET['delete_ticket']); // Get Ticket and Client ID for logging and alert message - $sql = mysqli_query($mysqli, "SELECT ticket_prefix, ticket_number, ticket_subject, ticket_status, ticket_client_id FROM tickets WHERE ticket_id = $ticket_id"); + $sql = mysqli_query($mysqli, "SELECT ticket_prefix, ticket_number, ticket_subject, ticket_status, ticket_closed_at, ticket_client_id FROM tickets WHERE ticket_id = $ticket_id"); $row = mysqli_fetch_array($sql); $ticket_prefix = sanitizeInput($row['ticket_prefix']); $ticket_number = sanitizeInput($row['ticket_number']); $ticket_subject = sanitizeInput($row['ticket_subject']); $ticket_status = sanitizeInput($row['ticket_status']); + $ticket_closed_at = sanitizeInput($row['ticket_closed_at']); $client_id = intval($row['ticket_client_id']); - if ($ticket_status !== $config_ticket_status_id_closed && $ticket_status !== 'Closed') { + if (empty($ticket_closed_at)) { mysqli_query($mysqli, "DELETE FROM tickets WHERE ticket_id = $ticket_id"); // Delete all ticket replies @@ -499,8 +495,8 @@ if (isset($_POST['bulk_assign_ticket'])) { $ticket_subject = sanitizeInput($row['ticket_subject']); $client_id = intval($row['ticket_client_id']); - if ($ticket_status == 'New' && $assigned_to !== 0) { - $ticket_status = $config_ticket_status_id_open; + if ($ticket_status == 1 && $assigned_to !== 0) { + $ticket_status = 2; } // Allow for un-assigning tickets @@ -889,7 +885,8 @@ if (isset($_POST['add_ticket_reply'])) { // Update Ticket Last Response Field mysqli_query($mysqli, "UPDATE tickets SET ticket_status = $ticket_status WHERE ticket_id = $ticket_id"); - if ($ticket_status == $config_ticket_status_id_closed || $ticket_status == 'Closed') { + // CLose the ticket, if set + if ($ticket_status == 5) { mysqli_query($mysqli, "UPDATE tickets SET ticket_closed_at = NOW() WHERE ticket_id = $ticket_id"); } @@ -929,10 +926,10 @@ if (isset($_POST['add_ticket_reply'])) { // Slightly different email subject/text depending on if this update closed the ticket or not - if ($ticket_status == $config_ticket_status_id_closed || $ticket_status == 'Closed') { + if ($ticket_status == 5) { $subject = "Ticket closed - [$ticket_prefix$ticket_number] - $ticket_subject | (do not reply)"; $body = "Hello $contact_name,

Your ticket regarding $ticket_subject has been closed.

--------------------------------
$ticket_reply
--------------------------------

We hope the request/issue was resolved to your satisfaction. If you need further assistance, please raise a new ticket using the below details. Please do not reply to this email.

Ticket: $ticket_prefix$ticket_number
Subject: $ticket_subject
Portal: https://$config_base_url/portal/ticket.php?id=$ticket_id

--
$company_name - Support
$config_ticket_from_email
$company_phone"; - } elseif ($ticket_status == $config_ticket_status_id_autoclose || $ticket_status == 'Auto Close') { + } elseif ($ticket_status == 4) { $subject = "Ticket update - [$ticket_prefix$ticket_number] - $ticket_subject | (pending closure)"; $body = "##- Please type your reply above this line -##

Hello $contact_name,

Your ticket regarding $ticket_subject has been updated and is pending closure.

--------------------------------
$ticket_reply
--------------------------------

If your request/issue is resolved, you can simply ignore this email. If you need further assistance, please respond to let us know!

Ticket: $ticket_prefix$ticket_number
Subject: $ticket_subject
Status: $ticket_status_name
Portal: https://$config_base_url/portal/ticket.php?id=$ticket_id

--
$company_name - Support
$config_ticket_from_email
$company_phone"; } else { diff --git a/ticket.php b/ticket.php index e128714d..bde6acab 100644 --- a/ticket.php +++ b/ticket.php @@ -27,6 +27,7 @@ if (isset($_GET['ticket_id'])) { LEFT JOIN locations ON ticket_location_id = location_id LEFT JOIN assets ON ticket_asset_id = asset_id LEFT JOIN vendors ON ticket_vendor_id = vendor_id + LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id WHERE ticket_id = $ticket_id LIMIT 1" ); @@ -76,8 +77,9 @@ if (isset($_GET['ticket_id'])) { } $ticket_feedback = nullable_htmlentities($row['ticket_feedback']); - $ticket_status = nullable_htmlentities($row['ticket_status']); - $ticket_status_color = getTicketStatusColor($ticket_status); + $ticket_status = intval($row['ticket_status_id']); + $ticket_status_name = nullable_htmlentities($row['ticket_status_name']); + $ticket_status_color = nullable_htmlentities($row['ticket_status_color']); $ticket_vendor_ticket_number = nullable_htmlentities($row['ticket_vendor_ticket_number']); $ticket_created_at = nullable_htmlentities($row['ticket_created_at']); @@ -261,11 +263,11 @@ if (isset($_GET['ticket_id'])) {
- +
-

Ticket

+

Ticket

- +
@@ -306,7 +308,7 @@ if (isset($_GET['ticket_id'])) { Close - + +
@@ -788,7 +790,7 @@ if (isset($_GET['ticket_id'])) { - +