diff --git a/CHANGELOG.md b/CHANGELOG.md index fdeded17..04a0a3ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,19 @@ # Changelog This file documents all notable changes made to ITFlow. + +## [25.03.4] + +### Fixed +- Ability to remove additional assets from the ticket details screen. +- Fix the ability to remove assets from edit ticket not working when only 1 asset exists. +- Fix Database Backup corruption. +- Client Portal - show ticket number instead of ticket id in ticket listing. +- Add Purchase Reference to copy asset. +- Add Link to asset details from the global search. +- Fix Bulk assign ticket only showing contacts instead of ITFlow users. + + ## [25.03.3] ### Fixed diff --git a/ajax/ajax_asset_copy.php b/ajax/ajax_asset_copy.php index dd648ce8..a491fb4d 100644 --- a/ajax/ajax_asset_copy.php +++ b/ajax/ajax_asset_copy.php @@ -364,6 +364,16 @@ ob_start(); +
+ +
+
+ +
+ +
+
+
diff --git a/client/ticket_view_all.php b/client/ticket_view_all.php index 50812f3b..5c33edf2 100644 --- a/client/ticket_view_all.php +++ b/client/ticket_view_all.php @@ -62,7 +62,7 @@ $all_tickets = mysqli_query($mysqli, "SELECT ticket_id, ticket_prefix, ticket_nu $ticket_contact_name = nullable_htmlentities($row['contact_name']); echo ""; - echo " $ticket_prefix$ticket_id"; + echo " $ticket_prefix$ticket_number"; echo " $ticket_subject"; echo "$ticket_contact_name"; echo "$ticket_status"; diff --git a/global_search.php b/global_search.php index 045c6ed5..7e64d5d3 100644 --- a/global_search.php +++ b/global_search.php @@ -721,7 +721,6 @@ if (isset($_GET['query'])) { } else { $asset_serial_display = $asset_serial; } - $asset_mac = nullable_htmlentities($row['asset_mac']); $asset_uri = nullable_htmlentities($row['asset_uri']); $asset_status = nullable_htmlentities($row['asset_status']); $asset_created_at = nullable_htmlentities($row['asset_created_at']); @@ -746,9 +745,9 @@ if (isset($_GET['query'])) { ?> - + - + diff --git a/includes/app_version.php b/includes/app_version.php index 8789cc27..f7d4a284 100644 --- a/includes/app_version.php +++ b/includes/app_version.php @@ -5,4 +5,4 @@ * Update this file each time we merge develop into master. Format is YY.MM (add a .v if there is more than one release a month. */ -DEFINE("APP_VERSION", "25.03.3"); +DEFINE("APP_VERSION", "25.03.4"); diff --git a/modals/admin_vendor_template_add_modal.php b/modals/admin_vendor_template_add_modal.php index 4e5f5dcb..e8a2ba85 100644 --- a/modals/admin_vendor_template_add_modal.php +++ b/modals/admin_vendor_template_add_modal.php @@ -75,20 +75,23 @@
- +
-
+
- + +
-
- +
+
+ +
diff --git a/modals/ticket_add_watcher_modal.php b/modals/ticket_add_watcher_modal.php index c1c47e53..ab6a1cf3 100644 --- a/modals/ticket_add_watcher_modal.php +++ b/modals/ticket_add_watcher_modal.php @@ -21,7 +21,7 @@
query("SHOW TABLES"); + while ($row = $res->fetch_row()) { $tables[] = $row[0]; } - $sqlScript = ""; foreach ($tables as $table) { + // Table structure + $createRes = $mysqli->query("SHOW CREATE TABLE `$table`"); + $createRow = $createRes->fetch_assoc(); + $createSQL = array_values($createRow)[1]; - // Prepare SQLscript for creating table structure - $query = "SHOW CREATE TABLE $table"; - $result = mysqli_query($mysqli, $query); - $row = mysqli_fetch_row($result); + echo "\n-- ----------------------------\n"; + echo "-- Table structure for `$table`\n"; + echo "-- ----------------------------\n"; + echo "DROP TABLE IF EXISTS `$table`;\n"; + echo $createSQL . ";\n\n"; - $sqlScript .= "\n\n" . $row[1] . ";\n\n"; + // Table data + $dataRes = $mysqli->query("SELECT * FROM `$table`"); + if ($dataRes->num_rows > 0) { + echo "-- Dumping data for table `$table`\n"; + while ($row = $dataRes->fetch_assoc()) { + $columns = array_map(fn($col) => '`' . $mysqli->real_escape_string($col) . '`', array_keys($row)); + $values = array_map(function ($val) use ($mysqli) { + if (is_null($val)) return "NULL"; + return "'" . $mysqli->real_escape_string($val) . "'"; + }, array_values($row)); - - $query = "SELECT * FROM $table"; - $result = mysqli_query($mysqli, $query); - - $columnCount = mysqli_num_fields($result); - - // Prepare SQLscript for dumping data for each table - for ($i = 0; $i < $columnCount; $i ++) { - while ($row = mysqli_fetch_row($result)) { - $sqlScript .= "INSERT INTO $table VALUES("; - for ($j = 0; $j < $columnCount; $j ++) { - - if (isset($row[$j])) { - $sqlScript .= '"' . $row[$j] . '"'; - } else { - $sqlScript .= '""'; - } - if ($j < ($columnCount - 1)) { - $sqlScript .= ','; - } - } - $sqlScript .= ");\n"; + echo "INSERT INTO `$table` (" . implode(", ", $columns) . ") VALUES (" . implode(", ", $values) . ");\n"; } + echo "\n"; } - - $sqlScript .= "\n"; } - if (!empty($sqlScript)) { - - $company_name = $session_company_name; - // Save the SQL script to a backup file - $backup_file_name = date('Y-m-d') . '_ITFlow_backup.sql'; - $fileHandler = fopen($backup_file_name, 'w+'); - $number_of_lines = fwrite($fileHandler, $sqlScript); - fclose($fileHandler); - - // Download the SQL backup file to the browser - header('Content-Description: File Transfer'); - header('Content-Type: application/octet-stream'); - header('Content-Disposition: attachment; filename=' . basename($backup_file_name)); - header('Content-Transfer-Encoding: binary'); - header('Expires: 0'); - header('Cache-Control: must-revalidate'); - header('Pragma: public'); - header('Content-Length: ' . filesize($backup_file_name)); - ob_clean(); - flush(); - readfile($backup_file_name); - exec('rm ' . $backup_file_name); - } - - // Logging - logAction("Database", "Download", "$session_name downloaded the database"); + //FINAL STEP: Re-enable foreign key checks + echo "\nSET foreign_key_checks = 1;\n"; + logAction("Database", "Download", "$session_name downloaded the database."); $_SESSION['alert_message'] = "Database downloaded"; + exit; } if (isset($_POST['backup_master_key'])) { diff --git a/post/user/ticket.php b/post/user/ticket.php index b833774f..c40f46ec 100644 --- a/post/user/ticket.php +++ b/post/user/ticket.php @@ -203,6 +203,10 @@ if (isset($_POST['edit_ticket'])) { $additional_asset_id = intval($additional_asset); mysqli_query($mysqli, "INSERT INTO ticket_assets SET ticket_id = $ticket_id, asset_id = $additional_asset_id"); } + } else { + // If no additional assets are provided, delete them all + // This handles cases where the assets input might be cleared or not set at all. + mysqli_query($mysqli, "DELETE FROM ticket_assets WHERE ticket_id = $ticket_id"); } // Get contact/ticket details after update for logging / email purposes @@ -494,6 +498,41 @@ if (isset($_GET['delete_ticket_watcher'])) { header("Location: " . $_SERVER["HTTP_REFERER"]); } +if (isset($_GET['delete_ticket_additional_asset'])) { + + enforceUserPermission('module_support', 2); + + $asset_id = intval($_GET['delete_ticket_additional_asset']); + $ticket_id = intval($_GET['ticket_id']); + + // Get ticket / asset details for logging + $sql = mysqli_query($mysqli, "SELECT asset_name, ticket_prefix, ticket_number, ticket_status_name, ticket_client_id FROM assets + JOIN tickets ON ticket_id = $ticket_id + JOIN ticket_statuses ON ticket_status = ticket_status_id + WHERE asset_id = $asset_id" + ); + $row = mysqli_fetch_array($sql); + + $ticket_prefix = sanitizeInput($row['ticket_prefix']); + $ticket_number = intval($row['ticket_number']); + $ticket_status_name = sanitizeInput($row['ticket_status_name']); + $asset_name = sanitizeInput($row['asset_name']); + $client_id = intval($row['ticket_client_id']); + + mysqli_query($mysqli, "DELETE FROM ticket_assets WHERE ticket_id = $ticket_id AND asset_id = $asset_id"); + + // History + mysqli_query($mysqli, "INSERT INTO ticket_history SET ticket_history_status = '$ticket_status_name', ticket_history_description = '$session_name removed additional asset $asset_name', ticket_history_ticket_id = $ticket_id"); + + // Logging + logAction("Ticket", "Edit", "$session_name removed asset $asset_name from ticket $ticket_prefix$ticket_number", $client_id, $ticket_id); + + $_SESSION['alert_type'] = "error"; + $_SESSION['alert_message'] = "Removed asset $asset_name from ticket."; + + header("Location: " . $_SERVER["HTTP_REFERER"]); +} + if (isset($_POST['edit_ticket_asset'])) { enforceUserPermission('module_support', 2); diff --git a/ticket.php b/ticket.php index 5155ab17..3b28d0f2 100644 --- a/ticket.php +++ b/ticket.php @@ -1058,6 +1058,11 @@ if (isset($_GET['ticket_id'])) { data-ajax-id=""> + + + + +