Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ticketing updates - guest view & resolved vs closed #998

Merged
merged 3 commits into from
Aug 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions client_tickets.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@

if (isset($_GET['status']) && ($_GET['status']) == 'Closed') {
$status = 'Closed';
$ticket_status_snippet = "ticket_closed_at IS NOT NULL";
$ticket_status_snippet = "ticket_resolved_at IS NOT NULL";
} else {
// Default - Show open tickets
$status = 'Open';
$ticket_status_snippet = "ticket_closed_at IS NULL";
$ticket_status_snippet = "ticket_resolved_at IS NULL";
}

if (isset($_GET['billable']) && ($_GET['billable']) == '1') {
Expand Down Expand Up @@ -49,12 +49,12 @@
$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_closed_at IS NULL");
$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_resolved_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_closed_at IS NOT NULL");
$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_resolved_at IS NOT NULL");
$row = mysqli_fetch_array($sql_total_tickets_closed);
$total_tickets_closed = intval($row['total_tickets_closed']);

Expand Down Expand Up @@ -215,7 +215,7 @@

?>

<tr class="<?php if(empty($ticket_reply_created_at)) { echo "text-bold"; }?> <?php if ($ticket_reply_type == "Client") { echo "table-warning"; } ?>">
<tr class="<?php if(empty($ticket_reply_created_at)) { echo "text-bold"; }?> <?php if (empty($ticket_closed_at) && $ticket_reply_type == "Client") { echo "table-warning"; } ?>">

<!-- Ticket Number -->
<td>
Expand Down Expand Up @@ -263,8 +263,10 @@

<!-- Ticket Last Response -->
<td>
<div title="<?php echo $ticket_reply_created_at; ?>"><?php echo $ticket_reply_created_at_time_ago; ?></div>
<div><?php echo $ticket_reply_by_display; ?></div>
<?php if (!empty($ticket_reply_created_at)) { ?>
<div title="<?php echo $ticket_reply_created_at; ?>"><?php echo $ticket_reply_created_at_time_ago; ?></div>
<div><?php echo $ticket_reply_by_display; ?></div>
<?php } ?>
</td>

<!-- Ticket Created At -->
Expand Down
95 changes: 20 additions & 75 deletions cron.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
$config_ticket_from_name = sanitizeInput($row['config_ticket_from_name']);
$config_ticket_from_email = sanitizeInput($row['config_ticket_from_email']);
$config_ticket_client_general_notifications = intval($row['config_ticket_client_general_notifications']);
$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']);

Expand Down Expand Up @@ -380,86 +379,32 @@
//mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Cron', log_action = 'Task', log_description = 'Cron created sent out recurring tickets'");


// AUTO CLOSE TICKET - CLOSE
// Automatically silently closes tickets 22 hrs after the last chase
// TICKET RESOLUTION/CLOSURE PROCESS
// Changes tickets status from 'Resolved' >> 'Closed' after a defined interval

// Check to make sure auto-close is enabled
if ($config_ticket_autoclose == 1) {
$sql_tickets_to_chase = mysqli_query(
$mysqli,
"SELECT * FROM tickets
WHERE ticket_status = 4
AND ticket_updated_at < NOW() - INTERVAL $config_ticket_autoclose_hours HOUR"
);

while ($row = mysqli_fetch_array($sql_tickets_to_chase)) {

$ticket_id = $row['ticket_id'];
$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_assigned_to = sanitizeInput($row['ticket_assigned_to']);
$client_id = intval($row['ticket_client_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");

}


// AUTO CLOSE TICKETS - CHASE
// Automatically sends a chaser email after approx 48 hrs/2 days
$sql_tickets_to_chase = mysqli_query(
$mysqli,
"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 = 4
AND ticket_updated_at < NOW() - INTERVAL 48 HOUR"
);

while ($row = mysqli_fetch_array($sql_tickets_to_chase)) {
$sql_resolved_tickets_to_close = mysqli_query(
$mysqli,
"SELECT * FROM tickets
WHERE ticket_status = 4
AND ticket_updated_at < NOW() - INTERVAL $config_ticket_autoclose_hours HOUR"
);

$contact_name = sanitizeInput($row['contact_name']);
$contact_email = sanitizeInput($row['contact_email']);
$ticket_id = intval($row['ticket_id']);
$ticket_prefix = sanitizeInput($row['ticket_prefix']);
$ticket_number = intval($row['ticket_number']);
$ticket_subject = sanitizeInput($row['ticket_subject']);
$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");
$ticket_reply_row = mysqli_fetch_array($sql_ticket_reply);
$ticket_reply = $ticket_reply_row['ticket_reply'];

$subject = "Ticket pending closure - [$ticket_prefix$ticket_number] - $ticket_subject";

$body = "<i style=\'color: #808080\'>##- Please type your reply above this line -##</i><br><br>Hello, $contact_name<br><br>This is an automatic friendly reminder that your ticket regarding \"$ticket_subject\" will be closed, unless you respond.<br><br>--------------------------------<br>$ticket_reply--------------------------------<br><br>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. <br><br>Ticket: $ticket_prefix$ticket_number<br>Subject: $ticket_subject<br>Status: $ticket_status <br>Portal: https://$config_base_url/portal/ticket.php?id=$ticket_id<br><br>--<br>$company_name - Support<br>$config_ticket_from_email<br>$company_phone";
while ($row = mysqli_fetch_array($sql_resolved_tickets_to_close)) {

$data = [
[
'from' => $config_ticket_from_email,
'from_name' => $config_ticket_from_name,
'recipient' => $contact_email,
'recipient_name' => $contact_name,
'subject' => $subject,
'body' => $body
]
];
$mail = addToMailQueue($mysqli, $data);
$ticket_id = $row['ticket_id'];
$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_assigned_to = sanitizeInput($row['ticket_assigned_to']);
$client_id = intval($row['ticket_client_id']);

if ($mail !== true) {
mysqli_query($mysqli,"INSERT INTO notifications SET notification_type = 'Mail', notification = 'Failed to send email to $contact_email'");
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Mail', log_action = 'Error', log_description = 'Failed to send email to $contact_email regarding $subject. $mail'");
}
mysqli_query($mysqli,"UPDATE tickets SET ticket_status = 5, ticket_closed_at = NOW(), ticket_closed_by = $ticket_assigned_to WHERE ticket_id = $ticket_id");

mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Ticket Reply', log_action = 'Create', log_description = 'Auto close chaser email sent to $contact_email for ticket $ticket_prefix$ticket_number - $ticket_subject', log_client_id = $client_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");

}
//TODO: Add client notifs if $config_ticket_client_general_notifications is on
}

if ($config_send_invoice_reminders == 1) {
Expand Down
9 changes: 6 additions & 3 deletions cron_ticket_email_parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,10 @@ function addTicket($contact_id, $contact_name, $contact_email, $client_id, $date
$contact_email_esc = mysqli_real_escape_string($mysqli, $contact_email);
$client_id_esc = intval($client_id);

mysqli_query($mysqli, "INSERT INTO tickets SET ticket_prefix = '$ticket_prefix_esc', ticket_number = $ticket_number, ticket_subject = '$subject_esc', ticket_details = '$message_esc', ticket_priority = 'Low', ticket_status = 1, ticket_created_by = 0, ticket_contact_id = $contact_id, ticket_client_id = $client_id_esc");
//Generate a unique URL key for clients to access
$url_key = randomString(156);

mysqli_query($mysqli, "INSERT INTO tickets SET ticket_prefix = '$ticket_prefix_esc', ticket_number = $ticket_number, ticket_subject = '$subject_esc', ticket_details = '$message_esc', ticket_priority = 'Low', ticket_status = 1, ticket_created_by = 0, ticket_contact_id = $contact_id, ticket_url_key = '$url_key', ticket_client_id = $client_id_esc");
$id = mysqli_insert_id($mysqli);

echo "Created new ticket.<br>";
Expand Down Expand Up @@ -213,7 +216,7 @@ function addReply($from_email, $date, $subject, $ticket_number, $message, $attac
mysqli_query($mysqli, "INSERT INTO notifications SET notification_type = 'Ticket', notification = 'Email parser: $from_email attempted to re-open ticket $config_ticket_prefix_esc$ticket_number_esc (ID $ticket_id_esc) - check inbox manually to see email', notification_action = 'ticket.php?ticket_id=$ticket_id_esc', notification_client_id = $client_id_esc");

$email_subject = "Action required: This ticket is already closed";
$email_body = "Hi there, <br><br>You've tried to reply to a ticket that is closed - we won't see your response. <br><br>Please raise a new ticket by sending a fresh e-mail to our support address below. <br><br>--<br>$company_name - Support<br>$config_ticket_from_email<br>$company_phone";
$email_body = "Hi there, <br><br>You've tried to reply to a ticket that is closed - we won't see your response. <br><br>Please raise a new ticket by sending a new e-mail to our support address below. <br><br>--<br>$company_name - Support<br>$config_ticket_from_email<br>$company_phone";

$data = [
[
Expand Down Expand Up @@ -301,7 +304,7 @@ function addReply($from_email, $date, $subject, $ticket_number, $message, $attac
}
}

mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 2 WHERE ticket_id = $ticket_id AND ticket_client_id = $client_id LIMIT 1");
mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 2, ticket_resolved_at = NULL WHERE ticket_id = $ticket_id AND ticket_client_id = $client_id LIMIT 1");

echo "Updated existing ticket.<br>";
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Ticket', log_action = 'Update', log_description = 'Email parser: Client contact $from_email_esc updated ticket $config_ticket_prefix$ticket_number_esc ($subject)', log_client_id = $client_id");
Expand Down
50 changes: 43 additions & 7 deletions database_updates.php
Original file line number Diff line number Diff line change
Expand Up @@ -2084,16 +2084,52 @@
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.4.2'");
}

// if (CURRENT_DATABASE_VERSION == '1.4.2') {
mysqli_query($mysqli, "ALTER TABLE `settings` ADD `config_ticket_email_parse_unknown_senders` INT(1) NOT NULL DEFAULT '0' AFTER `config_ticket_email_parse`");
if (CURRENT_DATABASE_VERSION == '1.4.2') {
mysqli_query($mysqli, "ALTER TABLE `settings` ADD `config_ticket_email_parse_unknown_senders` INT(1) NOT NULL DEFAULT '0' AFTER `config_ticket_email_parse`");

mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.4.3'");
// }
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.4.3'");
}

if (CURRENT_DATABASE_VERSION == '1.4.3') {

// Add ticket URL key column
mysqli_query($mysqli, "ALTER TABLE `tickets` ADD `ticket_url_key` VARCHAR(200) DEFAULT NULL AFTER `ticket_feedback`");
// Populate pre-existing columns for open tickets
$sql_tickets_1 = mysqli_query($mysqli, "SELECT ticket_id FROM tickets WHERE tickets.ticket_closed_at IS NULL");
foreach ($sql_tickets_1 as $row) {
$ticket_id = intval($row['ticket_id']);
$url_key = randomString(156);
mysqli_query($mysqli, "UPDATE tickets SET ticket_url_key = '$url_key' WHERE ticket_id = '$ticket_id'");
}

// Add ticket resolved at column
mysqli_query($mysqli, "ALTER TABLE `tickets` ADD `ticket_resolved_at` DATETIME DEFAULT NULL AFTER `ticket_updated_at`");
// Populate pre-existing columns for closed tickets
$sql_tickets_2 = mysqli_query($mysqli, "SELECT ticket_id, ticket_updated_at, ticket_closed_at FROM tickets WHERE tickets.ticket_closed_at IS NOT NULL");
foreach ($sql_tickets_2 as $row) {
$ticket_id = intval($row['ticket_id']);
$ticket_updated_at = sanitizeInput($row['ticket_updated_at']); // To keep old updated_at time
$ticket_closed_at = sanitizeInput($row['ticket_closed_at']);
mysqli_query($mysqli, "UPDATE tickets SET ticket_resolved_at = '$ticket_closed_at', ticket_updated_at = '$ticket_updated_at' WHERE ticket_id = '$ticket_id'");
}

// Change ticket status 'Auto close' to 'Resolved'
mysqli_query($mysqli, "UPDATE `ticket_statuses` SET `ticket_status_name` = 'Resolved' WHERE `ticket_statuses`.`ticket_status_id` = 4");

// Auto-close is no longer optional
mysqli_query($mysqli, "ALTER TABLE `settings` DROP `config_ticket_autoclose`");
mysqli_query($mysqli, "UPDATE `settings` SET `config_ticket_autoclose_hours` = '72'");

// DB Version
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.4.4'");


}

// if (CURRENT_DATABASE_VERSION == '1.4.3') {
// // Insert queries here required to update to DB version 1.4.4
// if (CURRENT_DATABASE_VERSION == '1.4.4') {
// // Insert queries here required to update to DB version 1.4.5
// // Then, update the database to the next sequential version
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.4.4'");
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.4.5'");
// }

} else {
Expand Down
2 changes: 1 addition & 1 deletion database_version.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
* It is used in conjunction with database_updates.php
*/

DEFINE("LATEST_DATABASE_VERSION", "1.4.3");
DEFINE("LATEST_DATABASE_VERSION", "1.4.4");
3 changes: 2 additions & 1 deletion db.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1469,7 +1469,6 @@ CREATE TABLE `settings` (
`config_ticket_email_parse` tinyint(1) NOT NULL DEFAULT 0,
`config_ticket_email_parse_unknown_senders` tinyint(1) NOT NULL DEFAULT 0,
`config_ticket_client_general_notifications` tinyint(1) NOT NULL DEFAULT 1,
`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_default_billable` tinyint(1) NOT NULL DEFAULT 0,
Expand Down Expand Up @@ -1846,8 +1845,10 @@ CREATE TABLE `tickets` (
`ticket_onsite` tinyint(1) NOT NULL DEFAULT 0,
`ticket_vendor_ticket_number` varchar(255) DEFAULT NULL,
`ticket_feedback` varchar(200) DEFAULT NULL,
`ticket_url_key` varchar(200) DEFAULT NULL,
`ticket_created_at` datetime NOT NULL DEFAULT current_timestamp(),
`ticket_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
`ticket_resolved_at` datetime DEFAULT NULL,
`ticket_archived_at` datetime DEFAULT NULL,
`ticket_closed_at` datetime DEFAULT NULL,
`ticket_created_by` int(11) NOT NULL,
Expand Down
4 changes: 4 additions & 0 deletions functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,10 @@ function sanitizeForEmail($data)

function timeAgo($datetime)
{
if (is_null($datetime)) {
return "-";
}

$time = strtotime($datetime);
$difference = $time - time(); // Changed to handle future dates

Expand Down
1 change: 0 additions & 1 deletion get_settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@
$config_ticket_email_parse = intval($row['config_ticket_email_parse']);
$config_ticket_email_parse_unknown_senders = intval($row['config_ticket_email_parse_unknown_senders']);
$config_ticket_client_general_notifications = intval($row['config_ticket_client_general_notifications']);
$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_default_billable = intval($row['config_ticket_default_billable']);
Expand Down
Loading
Loading