+ Leave Blank for Full access to all clients, no affect on users with the admin role.
+
+
diff --git a/admin_users.php b/admin_users.php
index ce764ede..78392192 100644
--- a/admin_users.php
+++ b/admin_users.php
@@ -12,8 +12,9 @@ $url_query_strings_sort = http_build_query($get_copy);
$sql = mysqli_query(
$mysqli,
- "SELECT SQL_CALC_FOUND_ROWS * FROM users, user_settings
+ "SELECT SQL_CALC_FOUND_ROWS * FROM users, user_settings, user_roles
WHERE users.user_id = user_settings.user_id
+ AND user_settings.user_role = user_roles.user_role_id
AND (user_name LIKE '%$q%' OR user_email LIKE '%$q%')
AND user_archived_at IS NULL
ORDER BY $sort $order LIMIT $record_from, $record_to"
@@ -98,13 +99,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
}
$user_config_force_mfa = intval($row['user_config_force_mfa']);
$user_role = $row['user_role'];
- if ($user_role == 3) {
- $user_role_display = "Administrator";
- } elseif ($user_role == 2) {
- $user_role_display = "Technician";
- } else {
- $user_role_display = "Accountant";
- }
+ $user_role_display = nullable_htmlentities($row['user_role_name']);
$user_initials = nullable_htmlentities(initials($user_name));
$sql_last_login = mysqli_query(
@@ -125,9 +120,18 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$last_login = "$log_created_at
$log_user_os
$log_user_browser
$log_ip
";
}
+ // Get User Client Access Permissions
+ $user_client_access_sql = mysqli_query($mysqli,"SELECT client_id FROM user_permissions WHERE user_id = $user_id");
+ $client_access_array = [];
+ while ($row = mysqli_fetch_assoc($user_client_access_sql)) {
+ $client_access_array[] = intval($row['client_id']);
+ }
+
$sql_remember_tokens = mysqli_query($mysqli, "SELECT * FROM remember_tokens WHERE remember_token_user_id = $user_id");
$remember_token_count = mysqli_num_rows($sql_remember_tokens);
+
+
?>
diff --git a/ajax.php b/ajax.php
index 9476b40e..47011ac1 100644
--- a/ajax.php
+++ b/ajax.php
@@ -19,37 +19,22 @@ require_once "rfc6238.php";
* Fetches SSL certificates from remote hosts & returns the relevant info (issuer, expiry, public key)
*/
if (isset($_GET['certificate_fetch_parse_json_details'])) {
+
// PHP doesn't appreciate attempting SSL sockets to non-existent domains
if (empty($_GET['domain'])) {
exit();
}
- $domain = $_GET['domain'];
- // FQDNs in database shouldn't have a URL scheme, adding one
- $domain = "https://".$domain;
+ $name = $_GET['domain'];
- // Parse host and port
- $url = parse_url($domain, PHP_URL_HOST);
- $port = parse_url($domain, PHP_URL_PORT);
- // Default port
- if (!$port) {
- $port = "443";
- }
+ // Get SSL cert for domain (if exists)
+ $certificate = getSSL($name);
- // Get certificate (using verify peer false to allow for self-signed certs)
- $socket = "ssl://$url:$port";
- $get = stream_context_create(array("ssl" => array("capture_peer_cert" => true, "verify_peer" => false,)));
- $read = stream_socket_client($socket, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $get);
- $cert = stream_context_get_params($read);
- $cert_public_key_obj = openssl_x509_parse($cert['options']['ssl']['peer_certificate']);
- openssl_x509_export($cert['options']['ssl']['peer_certificate'], $export);
-
- // Process data
- if ($cert_public_key_obj) {
+ if ($certificate['success'] == "TRUE") {
$response['success'] = "TRUE";
- $response['expire'] = date('Y-m-d', $cert_public_key_obj['validTo_time_t']);
- $response['issued_by'] = strip_tags($cert_public_key_obj['issuer']['O']);
- $response['public_key'] = $export; //nl2br
+ $response['expire'] = $certificate['expire'];
+ $response['issued_by'] = $certificate['issued_by'];
+ $response['public_key'] = $certificate['public_key'];
} else {
$response['success'] = "FALSE";
}
diff --git a/api/v1/contacts/contact_model.php b/api/v1/contacts/contact_model.php
index 8fa13b27..7cb724b4 100644
--- a/api/v1/contacts/contact_model.php
+++ b/api/v1/contacts/contact_model.php
@@ -74,6 +74,14 @@ if (isset($_POST['contact_auth_method'])) {
$auth_method = '';
}
+if (isset($_POST['contact_primary'])) {
+ $primary = intval($_POST['contact_primary']);
+} elseif ($contact_row) {
+ $primary = $contact_row['contact_primary'];
+} else {
+ $primary = '0';
+}
+
if (isset($_POST['contact_important'])) {
$important = intval($_POST['contact_important']);
} elseif ($contact_row) {
diff --git a/api/v1/contacts/create.php b/api/v1/contacts/create.php
index 2599eaa2..cf51f7c9 100644
--- a/api/v1/contacts/create.php
+++ b/api/v1/contacts/create.php
@@ -20,7 +20,7 @@ if (!empty($name) && !empty($email) && !empty($client_id)) {
if (mysqli_num_rows($email_duplication_sql) == 0) {
// Insert contact
- $insert_sql = mysqli_query($mysqli, "INSERT INTO contacts SET contact_name = '$name', contact_title = '$title', contact_department = '$department', contact_email = '$email', contact_phone = '$phone', contact_extension = '$extension', contact_mobile = '$mobile', contact_notes = '$notes', contact_auth_method = '$auth_method', contact_important = '$important', contact_billing = '$billing', contact_technical = '$technical', contact_location_id = $location_id, contact_client_id = $client_id");
+ $insert_sql = mysqli_query($mysqli, "INSERT INTO contacts SET contact_name = '$name', contact_title = '$title', contact_department = '$department', contact_email = '$email', contact_phone = '$phone', contact_extension = '$extension', contact_mobile = '$mobile', contact_notes = '$notes', contact_auth_method = '$auth_method', contact_primary = '$primary', contact_important = '$important', contact_billing = '$billing', contact_technical = '$technical', contact_location_id = $location_id, contact_client_id = $client_id");
// Check insert & get insert ID
if ($insert_sql) {
diff --git a/api/v1/contacts/update.php b/api/v1/contacts/update.php
index 19ae914a..a5049f47 100644
--- a/api/v1/contacts/update.php
+++ b/api/v1/contacts/update.php
@@ -19,7 +19,7 @@ if (!empty($contact_id)) {
require_once 'contact_model.php';
- $update_sql = mysqli_query($mysqli, "UPDATE contacts SET contact_name = '$name', contact_title = '$title', contact_department = '$department', contact_email = '$email', contact_phone = '$phone', contact_extension = '$extension', contact_mobile = '$mobile', contact_notes = '$notes', contact_auth_method = '$auth_method', contact_important = '$important', contact_billing = '$billing', contact_technical = '$technical', contact_location_id = $location_id, contact_client_id = $client_id WHERE contact_id = $contact_id LIMIT 1");
+ $update_sql = mysqli_query($mysqli, "UPDATE contacts SET contact_name = '$name', contact_title = '$title', contact_department = '$department', contact_email = '$email', contact_phone = '$phone', contact_extension = '$extension', contact_mobile = '$mobile', contact_notes = '$notes', contact_auth_method = '$auth_method', contact_primary = '$primary', contact_important = '$important', contact_billing = '$billing', contact_technical = '$technical', contact_location_id = $location_id, contact_client_id = $client_id WHERE contact_id = $contact_id LIMIT 1");
// Check insert & get insert ID
if ($update_sql) {
diff --git a/calendar_events.php b/calendar_events.php
index 68841c31..e8f7eac4 100644
--- a/calendar_events.php
+++ b/calendar_events.php
@@ -180,6 +180,29 @@ while ($row = mysqli_fetch_array($sql)) {
echo "{ id: $event_id, title: $event_title, start: $event_start, color: '$event_color', url: 'ticket.php?ticket_id=$event_id' },";
}
+ // Recurring Tickets
+ $sql = mysqli_query($mysqli, "SELECT * FROM clients
+ LEFT JOIN scheduled_tickets ON client_id = scheduled_ticket_client_id
+ LEFT JOIN users ON scheduled_ticket_assigned_to = user_id"
+ );
+ while ($row = mysqli_fetch_array($sql)) {
+ $event_id = intval($row['scheduled_ticket_id']);
+ $client_id = intval($row['client_id']);
+ $username = $row['user_name'];
+ $frequency = $row['scheduled_ticket_frequency'];
+ if (empty($username)) {
+ $username = "";
+ } else {
+ //Limit to characters and add ...
+ $username = "[". substr($row['user_name'], 0, 9) . "...]";
+ }
+
+ $event_title = json_encode("R Ticket ($frequency) - " . $row['scheduled_ticket_subject'] . " " . $username);
+ $event_start = json_encode($row['scheduled_ticket_next_run']);
+
+ echo "{ id: $event_id, title: $event_title, start: $event_start, color: '$event_color', url: 'client_recurring_tickets.php?client_id=$client_id' },";
+ }
+
//Tickets Scheduled
$sql = mysqli_query($mysqli, "SELECT * FROM clients
LEFT JOIN tickets ON client_id = ticket_client_id
@@ -238,6 +261,14 @@ while ($row = mysqli_fetch_array($sql)) {
?>
],
eventOrder: 'allDay,start,-duration,title',
+
+
+ firstDay: ,
});
calendar.render();
diff --git a/check_login.php b/check_login.php
index a0fd1573..57c5bd36 100644
--- a/check_login.php
+++ b/check_login.php
@@ -10,7 +10,8 @@ if (!isset($_SESSION)) {
session_start();
}
-//Check to see if setup is enabled
+
+// Check to see if setup is enabled
if (!isset($config_enable_setup) || $config_enable_setup == 1) {
header("Location: setup.php");
exit;
@@ -18,13 +19,19 @@ if (!isset($config_enable_setup) || $config_enable_setup == 1) {
// Check user is logged in with a valid session
if (!isset($_SESSION['logged']) || !$_SESSION['logged']) {
- header("Location: login.php");
+ if ($_SERVER["REQUEST_URI"] == "/") {
+ header("Location: login.php");
+ } else {
+ header("Location: login.php?last_visited=" . base64_encode($_SERVER["REQUEST_URI"]) );
+ }
exit;
}
+
// Set Timezone
require_once "inc_set_timezone.php";
+
// User IP & UA
$session_ip = sanitizeInput(getIP());
$session_user_agent = sanitizeInput($_SERVER['HTTP_USER_AGENT']);
@@ -56,9 +63,37 @@ $session_company_country = $row['company_country'];
$session_company_locale = $row['company_locale'];
$session_company_currency = $row['company_currency'];
-//Set Currency Format
+
+// Set Currency Format
$currency_format = numfmt_create($session_company_locale, NumberFormatter::CURRENCY);
+
+try {
+ // Get User Client Access Permissions
+ $user_client_access_sql = "SELECT client_id FROM user_permissions WHERE user_id = $session_user_id";
+ $user_client_access_result = mysqli_query($mysqli, $user_client_access_sql);
+
+ $client_access_array = [];
+ while ($row = mysqli_fetch_assoc($user_client_access_result)) {
+ $client_access_array[] = $row['client_id'];
+ }
+
+ $client_access_string = implode(',', $client_access_array);
+
+ // Role / Client Access Permission Check
+ if ($session_user_role < 3 && !empty($client_access_string)) {
+ $access_permission_query = "AND client_id IN ($client_access_string)";
+ } else {
+ $access_permission_query = "";
+ }
+} catch (Exception $e) {
+ // Handle exception
+ error_log('MySQL error: ' . $e->getMessage());
+ $access_permission_query = ""; // Ensure safe default if query fails
+}
+
+
+// Include the settings vars
require_once "get_settings.php";
@@ -73,15 +108,17 @@ if ($iPod || $iPhone || $iPad) {
$session_map_source = "google";
}
-//Check if mobile device
+
+// Check if mobile device
$session_mobile = isMobile();
-//Get Notification Count for the badge on the top nav
+
+// Get Notification Count for the badge on the top nav
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('notification_id') AS num FROM notifications WHERE (notification_user_id = $session_user_id OR notification_user_id = 0) AND notification_dismissed_at IS NULL"));
$num_notifications = $row['num'];
+
// FORCE MFA Setup
//if ($session_user_config_force_mfa == 1 && $session_token == NULL) {
// header("Location: force_mfa.php");
//}
-
diff --git a/client_documents.php b/client_documents.php
index c826c5d6..f7a7e9bf 100644
--- a/client_documents.php
+++ b/client_documents.php
@@ -33,17 +33,31 @@ if (!empty($_GET['folder_id'])) {
// Set Folder Location Var used when creating folders
$folder_location = 0;
-$sql = mysqli_query(
- $mysqli,
- "SELECT SQL_CALC_FOUND_ROWS * FROM documents
- LEFT JOIN users ON document_created_by = user_id
- WHERE document_client_id = $client_id
- AND document_template = 0
- AND document_folder_id = $folder
- AND document_archived_at IS NULL
- $query_snippet
- ORDER BY $sort $order LIMIT $record_from, $record_to"
-);
+if ($get_folder_id == 0 && $_GET["q"]) {
+ $sql = mysqli_query(
+ $mysqli,
+ "SELECT SQL_CALC_FOUND_ROWS * FROM documents
+ LEFT JOIN users ON document_created_by = user_id
+ WHERE document_client_id = $client_id
+ AND document_template = 0
+
+ AND document_archived_at IS NULL
+ $query_snippet
+ ORDER BY $sort $order LIMIT $record_from, $record_to"
+ );
+}else{
+ $sql = mysqli_query(
+ $mysqli,
+ "SELECT SQL_CALC_FOUND_ROWS * FROM documents
+ LEFT JOIN users ON document_created_by = user_id
+ WHERE document_client_id = $client_id
+ AND document_template = 0
+ AND document_folder_id = $folder
+ AND document_archived_at IS NULL
+ $query_snippet
+ ORDER BY $sort $order LIMIT $record_from, $record_to"
+ );
+}
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
diff --git a/client_events.php b/client_events.php
index 590b202e..f4777ed7 100644
--- a/client_events.php
+++ b/client_events.php
@@ -180,6 +180,29 @@ while ($row = mysqli_fetch_array($sql)) {
echo "{ id: $event_id, title: $event_title, start: $event_start, color: '$event_color', url: 'ticket.php?ticket_id=$event_id' },";
}
+ // Recurring Tickets
+ $sql = mysqli_query($mysqli, "SELECT * FROM clients
+ LEFT JOIN scheduled_tickets ON client_id = scheduled_ticket_client_id
+ LEFT JOIN users ON scheduled_ticket_assigned_to = user_id"
+ );
+ while ($row = mysqli_fetch_array($sql)) {
+ $event_id = intval($row['scheduled_ticket_id']);
+ $client_id = intval($row['client_id']);
+ $username = $row['user_name'];
+ $frequency = $row['scheduled_ticket_frequency'];
+ if (empty($username)) {
+ $username = "";
+ } else {
+ //Limit to characters and add ...
+ $username = "[". substr($row['user_name'], 0, 9) . "...]";
+ }
+
+ $event_title = json_encode("R Ticket ($frequency) - " . $row['scheduled_ticket_subject'] . " " . $username);
+ $event_start = json_encode($row['scheduled_ticket_next_run']);
+
+ echo "{ id: $event_id, title: $event_title, start: $event_start, color: '$event_color', url: 'client_recurring_tickets.php?client_id=$client_id' },";
+ }
+
//Tickets Scheduled
$sql = mysqli_query($mysqli, "SELECT * FROM clients
LEFT JOIN tickets ON client_id = ticket_client_id
diff --git a/client_file_upload_modal.php b/client_file_upload_modal.php
index 68e29748..3fcb869a 100644
--- a/client_file_upload_modal.php
+++ b/client_file_upload_modal.php
@@ -11,7 +11,7 @@
-
+
@@ -47,7 +47,7 @@
-
+
Up to 20 files can be uploaded at once by holding down CTRL and selecting files
diff --git a/client_files.php b/client_files.php
index c9ba024b..f21eca9f 100644
--- a/client_files.php
+++ b/client_files.php
@@ -39,16 +39,29 @@ if ($view == 1) {
// Set Folder Location Var used when creating folders
$folder_location = 1;
-$sql = mysqli_query(
- $mysqli,
- "SELECT SQL_CALC_FOUND_ROWS * FROM files
- WHERE file_client_id = $client_id
- AND file_folder_id = $folder_id
- AND file_archived_at IS NULL
- AND (file_name LIKE '%$q%' OR file_ext LIKE '%$q%' OR file_description LIKE '%$q%')
- $query_images
- ORDER BY $sort $order LIMIT $record_from, $record_to"
-);
+if ($get_folder_id == 0 && $_GET["q"]) {
+ $sql = mysqli_query(
+ $mysqli,
+ "SELECT SQL_CALC_FOUND_ROWS * FROM files
+ WHERE file_client_id = $client_id
+
+ AND file_archived_at IS NULL
+ AND (file_name LIKE '%$q%' OR file_ext LIKE '%$q%' OR file_description LIKE '%$q%')
+ $query_images
+ ORDER BY $sort $order LIMIT $record_from, $record_to"
+ );
+}else{
+ $sql = mysqli_query(
+ $mysqli,
+ "SELECT SQL_CALC_FOUND_ROWS * FROM files
+ WHERE file_client_id = $client_id
+ AND file_folder_id = $folder_id
+ AND file_archived_at IS NULL
+ AND (file_name LIKE '%$q%' OR file_ext LIKE '%$q%' OR file_description LIKE '%$q%')
+ $query_images
+ ORDER BY $sort $order LIMIT $record_from, $record_to"
+ );
+}
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
diff --git a/client_location_add_modal.php b/client_location_add_modal.php
index aa9bd6bf..2cd48607 100644
--- a/client_location_add_modal.php
+++ b/client_location_add_modal.php
@@ -168,10 +168,6 @@
+
diff --git a/client_logins.php b/client_logins.php
index 3e9e7437..5ab1f1ed 100644
--- a/client_logins.php
+++ b/client_logins.php
@@ -89,8 +89,8 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$login_uri = nullable_htmlentities($row['login_uri']);
if (empty($login_uri)) {
$login_uri_display = "-";
- } else {
- $login_uri_display = "$login_uri";
+ } else {
+ $login_uri_display = truncate($login_uri,40) . "";
}
$login_uri_2 = nullable_htmlentities($row['login_uri_2']);
$login_username = nullable_htmlentities(decryptLoginEntry($row['login_username']));
diff --git a/clients.php b/clients.php
index da3bd024..7d06c569 100644
--- a/clients.php
+++ b/clients.php
@@ -44,23 +44,24 @@ $url_query_strings_sort = http_build_query($get_copy);
$sql = mysqli_query(
$mysqli,
"
- SELECT SQL_CALC_FOUND_ROWS clients.*, contacts.*, locations.*, GROUP_CONCAT(tags.tag_name) AS tag_names
+ SELECT SQL_CALC_FOUND_ROWS clients.*, contacts.*, locations.*, GROUP_CONCAT(tag_name)
FROM clients
LEFT JOIN contacts ON clients.client_id = contacts.contact_client_id AND contact_primary = 1
LEFT JOIN locations ON clients.client_id = locations.location_client_id AND location_primary = 1
- LEFT JOIN client_tags ON client_tags.client_tag_client_id = clients.client_id
- LEFT JOIN tags ON tags.tag_id = client_tags.client_tag_tag_id
- WHERE (clients.client_name LIKE '%$q%' OR clients.client_type LIKE '%$q%' OR clients.client_referral LIKE '%$q%'
- OR contacts.contact_email LIKE '%$q%' OR contacts.contact_name LIKE '%$q%' OR contacts.contact_phone LIKE '%$phone_query%'
- OR contacts.contact_mobile LIKE '%$phone_query%' OR locations.location_address LIKE '%$q%'
- OR locations.location_city LIKE '%$q%' OR locations.location_state LIKE '%$q%' OR locations.location_zip LIKE '%$q%'
- OR tags.tag_name LIKE '%$q%' OR clients.client_tax_id_number LIKE '%$q%')
- AND clients.client_$archive_query
- AND DATE(clients.client_created_at) BETWEEN '$dtf' AND '$dtt'
- AND clients.client_lead = $leads
+ LEFT JOIN client_tags ON client_tags.client_id = clients.client_id
+ LEFT JOIN tags ON tags.tag_id = client_tags.tag_id
+ WHERE (client_name LIKE '%$q%' OR client_type LIKE '%$q%' OR client_referral LIKE '%$q%'
+ OR contact_email LIKE '%$q%' OR contact_name LIKE '%$q%' OR contact_phone LIKE '%$phone_query%'
+ OR contact_mobile LIKE '%$phone_query%' OR location_address LIKE '%$q%'
+ OR location_city LIKE '%$q%' OR location_state LIKE '%$q%' OR location_zip LIKE '%$q%'
+ OR tag_name LIKE '%$q%' OR client_tax_id_number LIKE '%$q%')
+ AND client_$archive_query
+ AND DATE(client_created_at) BETWEEN '$dtf' AND '$dtt'
+ AND client_lead = $leads
+ $access_permission_query
$industry_query
$referral_query
- GROUP BY clients.client_id
+ GROUP BY client_id
ORDER BY $sort $order
LIMIT $record_from, $record_to
");
@@ -245,7 +246,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$client_tag_name_display_array = array();
$client_tag_id_array = array();
- $sql_client_tags = mysqli_query($mysqli, "SELECT * FROM client_tags LEFT JOIN tags ON client_tags.client_tag_tag_id = tags.tag_id WHERE client_tags.client_tag_client_id = $client_id ORDER BY tag_name ASC");
+ $sql_client_tags = mysqli_query($mysqli, "SELECT * FROM client_tags LEFT JOIN tags ON client_tags.tag_id = tags.tag_id WHERE client_id = $client_id ORDER BY tag_name ASC");
while ($row = mysqli_fetch_array($sql_client_tags)) {
$client_tag_id = intval($row['tag_id']);
diff --git a/cron.php b/cron.php
index ca64d611..856e7461 100644
--- a/cron.php
+++ b/cron.php
@@ -252,6 +252,7 @@ if (mysqli_num_rows($sql_scheduled_tickets) > 0) {
$details = mysqli_real_escape_string($mysqli, $row['scheduled_ticket_details']);
$priority = sanitizeInput($row['scheduled_ticket_priority']);
$frequency = sanitizeInput(strtolower($row['scheduled_ticket_frequency']));
+ $billable = intval($row['scheduled_ticket_billable']);
$created_id = intval($row['scheduled_ticket_created_by']);
$assigned_id = intval($row['scheduled_ticket_assigned_to']);
$client_id = intval($row['scheduled_ticket_client_id']);
@@ -272,7 +273,7 @@ if (mysqli_num_rows($sql_scheduled_tickets) > 0) {
mysqli_query($mysqli, "UPDATE settings SET config_ticket_next_number = $new_config_ticket_next_number WHERE company_id = 1");
// Raise the ticket
- 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 = '$ticket_status', ticket_created_by = $created_id, ticket_assigned_to = $assigned_id, ticket_contact_id = $contact_id, ticket_client_id = $client_id, ticket_asset_id = $asset_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 = '$ticket_status', ticket_billable = $billable, ticket_created_by = $created_id, ticket_assigned_to = $assigned_id, ticket_contact_id = $contact_id, ticket_client_id = $client_id, ticket_asset_id = $asset_id");
$id = mysqli_insert_id($mysqli);
// Logging
@@ -733,7 +734,7 @@ while ($row = mysqli_fetch_array($sql_recurring_expenses)) {
// TELEMETRY
-if ($config_telemetry > 0 OR $config_telemetry = 2) {
+if ($config_telemetry > 0 OR $config_telemetry == 2) {
$current_version = exec("git rev-parse HEAD");
@@ -979,6 +980,19 @@ if ($config_telemetry > 0 OR $config_telemetry = 2) {
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Cron', log_action = 'Telemetry', log_description = 'Cron sent telemetry results to ITFlow Developers'");
}
+
+// Fetch Updates
+$updates = fetchUpdates();
+
+$update_message = $updates->update_message;
+
+if ($updates->current_version !== $updates->latest_version) {
+ // Send Alert to inform Updates Available
+ mysqli_query($mysqli, "INSERT INTO notifications SET notification_type = 'Update', notification = '$update_message', notification_action = 'admin_update.php'");
+}
+
+
+
/*
* ###############################################################################################################
* FINISH UP
diff --git a/css/ticket_time_tracking.css b/css/ticket_time_tracking.css
deleted file mode 100644
index eb2c2c5c..00000000
--- a/css/ticket_time_tracking.css
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Custom CSS Styling for time tracking */
-
-/* Small bit of space between the ticket status and time tracking inputs */
-.custom-tt-horizontal-spacing {
- width: 20px; /* Adjust the width as needed for smaller spacing */
- display: inline-block;
-}
-
-/* Adjust Hour, min, and second fields to be close together */
-.custom-tt-width {
- width: 50px; /* Adjust the width as needed */
- padding: 0; /* Remove padding to maintain the desired width */
-}
diff --git a/database_updates.php b/database_updates.php
index 43f32d54..39ea33fb 100644
--- a/database_updates.php
+++ b/database_updates.php
@@ -335,7 +335,7 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
if (CURRENT_DATABASE_VERSION == '0.2.0') {
//Insert queries here required to update to DB version 0.2.1
- mysqli_query($mysqli, "ALTER TABLE `vendors`
+ mysqli_query($mysqli, "ALTER TABLE `vendors`
ADD `vendor_hours` VARCHAR(200) NULL DEFAULT NULL AFTER `vendor_website`,
ADD `vendor_sla` VARCHAR(200) NULL DEFAULT NULL AFTER `vendor_hours`,
ADD `vendor_code` VARCHAR(200) NULL DEFAULT NULL AFTER `vendor_sla`,
@@ -343,11 +343,11 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
");
mysqli_query($mysqli, "ALTER TABLE `vendors`
- DROP `vendor_country`,
- DROP `vendor_address`,
- DROP `vendor_city`,
- DROP `vendor_state`,
- DROP `vendor_zip`,
+ DROP `vendor_country`,
+ DROP `vendor_address`,
+ DROP `vendor_city`,
+ DROP `vendor_state`,
+ DROP `vendor_zip`,
DROP `vendor_global`
");
@@ -355,7 +355,7 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
mysqli_query($mysqli, "CREATE TABLE `vendor_templates` (`vendor_template_id` int(11) AUTO_INCREMENT PRIMARY KEY,
`vendor_template_name` varchar(200) NOT NULL,
`vendor_template_description` varchar(200) NULL DEFAULT NULL,
- `vendor_template_phone` varchar(200) NULL DEFAULT NULL,
+ `vendor_template_phone` varchar(200) NULL DEFAULT NULL,
`vendor_template_email` varchar(200) NULL DEFAULT NULL,
`vendor_template_website` varchar(200) NULL DEFAULT NULL,
`vendor_template_hours` varchar(200) NULL DEFAULT NULL,
@@ -397,7 +397,7 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
mysqli_query($mysqli, "CREATE TABLE `interfaces` (`interface_id` int(11) AUTO_INCREMENT PRIMARY KEY,
`interface_number` int(11) NULL DEFAULT NULL,
`interface_description` varchar(200) NULL DEFAULT NULL,
- `interface_connected_asset` varchar(200) NULL DEFAULT NULL,
+ `interface_connected_asset` varchar(200) NULL DEFAULT NULL,
`interface_ip` varchar(200) NULL DEFAULT NULL,
`interface_created_at` datetime DEFAULT CURRENT_TIMESTAMP,
`interface_updated_at` datetime NULL ON UPDATE CURRENT_TIMESTAMP,
@@ -1802,24 +1802,24 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
mysqli_query($mysqli, "UPDATE ticket_statuses SET ticket_status_color = '#28a745' WHERE ticket_status_id = 3"); // On Hold
mysqli_query($mysqli, "UPDATE ticket_statuses SET ticket_status_color = '#343a40' WHERE ticket_status_id = 4"); // Auto Close
mysqli_query($mysqli, "UPDATE ticket_statuses SET ticket_status_color = '#343a40' WHERE ticket_status_id = 5"); // Closed
-
+
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.1.9'");
}
if (CURRENT_DATABASE_VERSION == '1.1.9') {
mysqli_query($mysqli, "ALTER TABLE `settings` ADD `config_login_remember_me_expire` INT(11) NOT NULL DEFAULT 3 AFTER `config_login_key_secret`");
-
+
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.2.0'");
}
if (CURRENT_DATABASE_VERSION == '1.2.0') {
mysqli_query($mysqli, "ALTER TABLE `ticket_templates` ADD `ticket_template_order` INT(11) NOT NULL DEFAULT 0 AFTER `ticket_template_details`");
-
+
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.2.1'");
}
if (CURRENT_DATABASE_VERSION == '1.2.1') {
-
+
// Ticket Templates can have many project templates and Project Template can have have many ticket template, so instead create a many to many table relationship
mysqli_query($mysqli, "ALTER TABLE `ticket_templates` DROP `ticket_template_order`");
mysqli_query($mysqli, "ALTER TABLE `ticket_templates` DROP `ticket_template_project_template_id`");
@@ -1831,61 +1831,121 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
`ticket_template_order` INT(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`ticket_template_id`,`project_template_id`)
)");
-
+
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.2.2'");
}
if (CURRENT_DATABASE_VERSION == '1.2.2') {
-
+
mysqli_query($mysqli, "ALTER TABLE `tasks` DROP `task_description`");
mysqli_query($mysqli, "ALTER TABLE `task_templates` DROP `task_template_description`");
-
+
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.2.3'");
}
if (CURRENT_DATABASE_VERSION == '1.2.3') {
-
+
mysqli_query($mysqli, "ALTER TABLE `projects` ADD `project_manager` INT(11) NOT NULL DEFAULT 0 AFTER `project_due`");
-
+
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.2.4'");
}
if (CURRENT_DATABASE_VERSION == '1.2.4') {
-
+
mysqli_query($mysqli, "ALTER TABLE `settings` ADD `config_project_prefix` VARCHAR(200) NOT NULL DEFAULT 'PRJ-' AFTER `config_default_hourly_rate`");
mysqli_query($mysqli, "ALTER TABLE `settings` ADD `config_project_next_number` INT(11) NOT NULL DEFAULT 1 AFTER `config_project_prefix`");
-
+
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.2.5'");
}
if (CURRENT_DATABASE_VERSION == '1.2.5') {
-
+
mysqli_query($mysqli, "ALTER TABLE `projects` ADD `project_prefix` VARCHAR(200) DEFAULT NULL AFTER `project_id`");
mysqli_query($mysqli, "ALTER TABLE `projects` ADD `project_number` INT(11) NOT NULL DEFAULT 1 AFTER `project_prefix`");
-
+
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.2.6'");
}
if (CURRENT_DATABASE_VERSION == '1.2.6') {
-
+
mysqli_query($mysqli, "ALTER TABLE `domains` ADD `domain_dnshost` INT(11) NOT NULL DEFAULT 0 AFTER `domain_webhost`");
mysqli_query($mysqli, "ALTER TABLE `domains` ADD `domain_mailhost` INT(11) NOT NULL DEFAULT 0 AFTER `domain_dnshost`");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.2.7'");
}
if (CURRENT_DATABASE_VERSION == '1.2.7') {
-
+
mysqli_query($mysqli, "ALTER TABLE `recurring` ADD `recurring_invoice_email_notify` TINYINT(1) NOT NULL DEFAULT 1 AFTER `recurring_note`");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.2.8'");
}
- // if (CURRENT_DATABASE_VERSION == '1.2.8') {
- // // Insert queries here required to update to DB version 1.2.9
+ if (CURRENT_DATABASE_VERSION == '1.2.8') {
+
+ mysqli_query($mysqli, "ALTER TABLE `settings` ADD `config_phone_mask` TINYINT(1) NOT NULL DEFAULT 1 AFTER `config_destructive_deletes_enable`");
+ mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.2.9'");
+ }
+
+ if (CURRENT_DATABASE_VERSION == '1.2.9') {
+
+ mysqli_query($mysqli, "CREATE TABLE `user_permissions` (`user_id` int(11) NOT NULL,`client_id` int(11) NOT NULL, PRIMARY KEY (`user_id`,`client_id`))");
+
+ mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.3.0'");
+ }
+
+ if (CURRENT_DATABASE_VERSION == '1.3.0') {
+
+ mysqli_query($mysqli, "CREATE TABLE `user_roles` (
+ `user_role_id` INT(11) NOT NULL AUTO_INCREMENT,
+ `user_role_name` VARCHAR(200) NOT NULL,
+ `user_role_description` VARCHAR(200) NULL DEFAULT NULL,
+ `user_role_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `user_role_updated_at` DATETIME ON UPDATE CURRENT_TIMESTAMP NULL,
+ `user_role_archived_at` DATETIME NULL,
+ PRIMARY KEY (`user_role_id`)
+ )");
+
+ mysqli_query($mysqli, "INSERT INTO `user_roles` SET user_role_id = 1, user_role_name = 'Accountant', user_role_description = 'Built-in - Limited access to financial-focused modules'");
+ mysqli_query($mysqli, "INSERT INTO `user_roles` SET user_role_id = 2, user_role_name = 'Technician', user_role_description = 'Built-in - Limited access to technical-focused modules'");
+ mysqli_query($mysqli, "INSERT INTO `user_roles` SET user_role_id = 3, user_role_name = 'Administrator', user_role_description = 'Built-in - Full administrative access to all modules (including user management)'");
+
+ mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.3.1'");
+ }
+
+ if (CURRENT_DATABASE_VERSION == '1.3.1') {
+ mysqli_query($mysqli, "ALTER TABLE `user_settings` ADD `user_config_calendar_first_day` TINYINT(1) NOT NULL DEFAULT 0 AFTER `user_config_dashboard_technical_enable`");
+
+ mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.3.2'");
+ }
+
+ if (CURRENT_DATABASE_VERSION == '1.3.2') {
+ mysqli_query($mysqli, "ALTER TABLE `settings` ADD `config_ticket_default_billable` TINYINT(1) NOT NULL DEFAULT 0 AFTER `config_ticket_new_ticket_notification_email`");
+ mysqli_query($mysqli, "ALTER TABLE `scheduled_tickets` ADD `scheduled_ticket_billable` TINYINT(1) NOT NULL DEFAULT 0 AFTER `scheduled_ticket_frequency`");
+ mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.3.3'");
+ }
+
+ if (CURRENT_DATABASE_VERSION == '1.3.3') {
+ // // Insert queries here required to update to DB version 1.3.3
// // Then, update the database to the next sequential version
- // mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.2.9");
+ mysqli_query($mysqli, "CREATE TABLE `location_tags` (`location_id` int(11) NOT NULL,`tag_id` int(11) NOT NULL, PRIMARY KEY (`location_id`,`tag_id`))");
+ mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.3.4'");
+ }
+
+ if (CURRENT_DATABASE_VERSION == '1.3.4') {
+ mysqli_query($mysqli, "ALTER TABLE `client_tags` CHANGE `client_tag_client_id` `client_id` INT(11) NOT NULL");
+ mysqli_query($mysqli, "ALTER TABLE `client_tags` CHANGE `client_tag_tag_id` `tag_id` INT(11) NOT NULL");
+ mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.3.5'");
+ }
+
+ // if (CURRENT_DATABASE_VERSION == '1.3.5') {
+ // // Insert queries here required to update to DB version 1.3.6
+ // // Then, update the database to the next sequential version
+ // mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.3.6'");
// }
} else {
// Up-to-date
}
+
+
+
diff --git a/database_version.php b/database_version.php
index ac7b3dd1..cb57d13f 100644
--- a/database_version.php
+++ b/database_version.php
@@ -5,4 +5,4 @@
* It is used in conjunction with database_updates.php
*/
-DEFINE("LATEST_DATABASE_VERSION", "1.2.8");
+DEFINE("LATEST_DATABASE_VERSION", "1.3.5");
diff --git a/db.sql b/db.sql
index 3b56fcd7..b09d052a 100644
--- a/db.sql
+++ b/db.sql
@@ -250,9 +250,9 @@ DROP TABLE IF EXISTS `client_tags`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `client_tags` (
- `client_tag_client_id` int(11) NOT NULL,
- `client_tag_tag_id` int(11) NOT NULL,
- PRIMARY KEY (`client_tag_client_id`,`client_tag_tag_id`)
+ `client_id` int(11) NOT NULL,
+ `tag_id` int(11) NOT NULL,
+ PRIMARY KEY (`client_id`,`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
@@ -751,6 +751,20 @@ CREATE TABLE `invoices` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
+--
+-- Table structure for table `location_tags`
+--
+
+DROP TABLE IF EXISTS `location_tags`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `location_tags` (
+ `location_id` int(11) NOT NULL,
+ `tag_id` int(11) NOT NULL,
+ PRIMARY KEY (`location_id`,`tag_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
--
-- Table structure for table `locations`
--
@@ -1156,6 +1170,7 @@ CREATE TABLE `scheduled_tickets` (
`scheduled_ticket_details` longtext NOT NULL,
`scheduled_ticket_priority` varchar(200) DEFAULT NULL,
`scheduled_ticket_frequency` varchar(10) NOT NULL,
+ `scheduled_ticket_billable` tinyint(1) NOT NULL DEFAULT 0,
`scheduled_ticket_start_date` date NOT NULL,
`scheduled_ticket_next_run` date NOT NULL,
`scheduled_ticket_created_at` datetime NOT NULL DEFAULT current_timestamp(),
@@ -1341,6 +1356,7 @@ 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_default_billable` tinyint(1) NOT NULL DEFAULT 0,
`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,
@@ -1375,6 +1391,7 @@ CREATE TABLE `settings` (
`config_telemetry` tinyint(1) DEFAULT 0,
`config_timezone` varchar(200) NOT NULL DEFAULT 'America/New_York',
`config_destructive_deletes_enable` tinyint(1) NOT NULL DEFAULT 0,
+ `config_phone_mask` tinyint(1) NOT NULL DEFAULT 1,
PRIMARY KEY (`company_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
@@ -1776,6 +1793,38 @@ CREATE TABLE `trips` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
+--
+-- Table structure for table `user_permissions`
+--
+
+DROP TABLE IF EXISTS `user_permissions`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `user_permissions` (
+ `user_id` int(11) NOT NULL,
+ `client_id` int(11) NOT NULL,
+ PRIMARY KEY (`user_id`,`client_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `user_roles`
+--
+
+DROP TABLE IF EXISTS `user_roles`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `user_roles` (
+ `user_role_id` int(11) NOT NULL AUTO_INCREMENT,
+ `user_role_name` varchar(200) NOT NULL,
+ `user_role_description` varchar(200) DEFAULT NULL,
+ `user_role_created_at` datetime NOT NULL DEFAULT current_timestamp(),
+ `user_role_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
+ `user_role_archived_at` datetime DEFAULT NULL,
+ PRIMARY KEY (`user_role_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
--
-- Table structure for table `user_settings`
--
@@ -1790,6 +1839,7 @@ CREATE TABLE `user_settings` (
`user_config_records_per_page` int(11) NOT NULL DEFAULT 10,
`user_config_dashboard_financial_enable` tinyint(1) NOT NULL DEFAULT 0,
`user_config_dashboard_technical_enable` tinyint(1) NOT NULL DEFAULT 0,
+ `user_config_calendar_first_day` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
@@ -1902,4 +1952,4 @@ CREATE TABLE `vendors` (
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
--- Dump completed on 2024-04-12 19:37:23
+-- Dump completed on 2024-05-31 16:45:46
diff --git a/force_mfa.php b/force_mfa.php
index 0a70186e..05e6d1f2 100644
--- a/force_mfa.php
+++ b/force_mfa.php
@@ -36,8 +36,9 @@ require_once "header.php";
if (!empty($session_token)) {
- //Generate QR Code based off the generated key
- print sprintf('', TokenAuth6238::getBarCodeUrl($session_name, ' ', $session_token, $_SERVER['SERVER_NAME']));
+ // Generate QR Code
+ $data = "otpauth://totp/ITFlow:$session_email?secret=$session_token";
+ print "";
echo "
$session_token
";
}
diff --git a/functions.php b/functions.php
index 12be4fb5..6e0b64f4 100644
--- a/functions.php
+++ b/functions.php
@@ -212,6 +212,16 @@ function truncate($text, $chars)
function formatPhoneNumber($phoneNumber)
{
+ global $mysqli;
+
+ // Get Phone Mask Option
+ $phone_mask = mysqli_fetch_array(mysqli_query($mysqli, "SELECT config_phone_mask FROM settings WHERE company_id = 1"))[0];
+
+ if ($phone_mask == 0) {
+ return $phoneNumber;
+ }
+
+
$phoneNumber = $phoneNumber ? preg_replace('/[^0-9]/', '', $phoneNumber) : "";
if (strlen($phoneNumber) > 10) {
@@ -427,9 +437,18 @@ function getDomainRecords($name)
// Used to automatically attempt to get SSL certificates as part of adding domains
// The logic for the fetch (sync) button on the client_certificates page is in ajax.php, and allows ports other than 443
-function getSSL($name)
+function getSSL($full_name)
{
+ // Parse host and port
+ $name = parse_url("//$full_name", PHP_URL_HOST);
+ $port = parse_url("//$full_name", PHP_URL_PORT);
+
+ // Default port
+ if (!$port) {
+ $port = "443";
+ }
+
$certificate = array();
$certificate['success'] = false;
@@ -442,7 +461,7 @@ function getSSL($name)
}
// Get SSL/TSL certificate (using verify peer false to allow for self-signed certs) for domain on default port
- $socket = "ssl://$name:443";
+ $socket = "ssl://$name:$port";
$get = stream_context_create(array("ssl" => array("capture_peer_cert" => true, "verify_peer" => false,)));
$read = stream_socket_client($socket, $errno, $errstr, 5, STREAM_CLIENT_CONNECT, $get);
@@ -881,7 +900,7 @@ function getSettingValue($mysqli, $setting_name)
function getMonthlyTax($tax_name, $month, $year, $mysqli)
{
// SQL to calculate monthly tax
- $sql = "SELECT SUM(item_tax) AS monthly_tax FROM invoice_items
+ $sql = "SELECT SUM(item_tax) AS monthly_tax FROM invoice_items
LEFT JOIN invoices ON invoice_items.item_invoice_id = invoices.invoice_id
LEFT JOIN payments ON invoices.invoice_id = payments.payment_invoice_id
WHERE YEAR(payments.payment_date) = $year AND MONTH(payments.payment_date) = $month
@@ -898,7 +917,7 @@ function getQuarterlyTax($tax_name, $quarter, $year, $mysqli)
$end_month = $start_month + 2;
// SQL to calculate quarterly tax
- $sql = "SELECT SUM(item_tax) AS quarterly_tax FROM invoice_items
+ $sql = "SELECT SUM(item_tax) AS quarterly_tax FROM invoice_items
LEFT JOIN invoices ON invoice_items.item_invoice_id = invoices.invoice_id
LEFT JOIN payments ON invoices.invoice_id = payments.payment_invoice_id
WHERE YEAR(payments.payment_date) = $year AND MONTH(payments.payment_date) BETWEEN $start_month AND $end_month
@@ -911,7 +930,7 @@ function getQuarterlyTax($tax_name, $quarter, $year, $mysqli)
function getTotalTax($tax_name, $year, $mysqli)
{
// SQL to calculate total tax
- $sql = "SELECT SUM(item_tax) AS total_tax FROM invoice_items
+ $sql = "SELECT SUM(item_tax) AS total_tax FROM invoice_items
LEFT JOIN invoices ON invoice_items.item_invoice_id = invoices.invoice_id
LEFT JOIN payments ON invoices.invoice_id = payments.payment_invoice_id
WHERE YEAR(payments.payment_date) = $year
@@ -1172,3 +1191,34 @@ function getTicketStatusName($ticket_status) {
return "Unknown";
}
+
+
+function fetchUpdates() {
+
+ global $repo_branch;
+
+ // Fetch the latest code changes but don't apply them
+ exec("git fetch", $output, $result);
+ $latest_version = exec("git rev-parse origin/$repo_branch");
+ $current_version = exec("git rev-parse HEAD");
+
+ if ($current_version == $latest_version) {
+ $update_message = "No Updates available";
+ } else {
+ $update_message = "New Updates are Available [$latest_version]";
+ }
+
+
+
+ $updates = new stdClass();
+ $updates->output = $output;
+ $updates->result = $result;
+ $updates->current_version = $current_version;
+ $updates->latest_version = $latest_version;
+ $updates->update_message = $update_message;
+
+
+
+ return $updates;
+
+}
\ No newline at end of file
diff --git a/get_settings.php b/get_settings.php
index 0b53b9bc..58d5b3a6 100644
--- a/get_settings.php
+++ b/get_settings.php
@@ -72,6 +72,7 @@ $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_default_billable = intval($row['config_ticket_default_billable']);
// Cron
$config_enable_cron = intval($row['config_enable_cron']);
diff --git a/global_search.php b/global_search.php
index bc1d0984..96f653cb 100644
--- a/global_search.php
+++ b/global_search.php
@@ -24,6 +24,7 @@ if (isset($_GET['query'])) {
LEFT JOIN locations ON clients.client_id = locations.location_client_id AND location_primary = 1
WHERE client_archived_at IS NULL
AND client_name LIKE '%$query%'
+ $access_permission_query
ORDER BY client_id DESC LIMIT 5"
);
@@ -35,6 +36,7 @@ if (isset($_GET['query'])) {
OR contact_email LIKE '%$query%'
OR contact_phone LIKE '%$phone_query%'
OR contact_mobile LIKE '%$phone_query%')
+ $access_permission_query
ORDER BY contact_id DESC LIMIT 5"
);
@@ -43,6 +45,7 @@ if (isset($_GET['query'])) {
WHERE vendor_archived_at IS NULL
AND vendor_template = 0
AND (vendor_name LIKE '%$query%' OR vendor_phone LIKE '%$phone_query%')
+ $access_permission_query
ORDER BY vendor_id DESC LIMIT 5"
);
@@ -50,6 +53,7 @@ if (isset($_GET['query'])) {
LEFT JOIN clients ON domain_client_id = client_id
WHERE domain_archived_at IS NULL
AND domain_name LIKE '%$query%'
+ $access_permission_query
ORDER BY domain_id DESC LIMIT 5"
);
@@ -63,6 +67,7 @@ if (isset($_GET['query'])) {
LEFT JOIN clients on document_client_id = clients.client_id
WHERE document_archived_at IS NULL
AND MATCH(document_content_raw) AGAINST ('$query')
+ $access_permission_query
ORDER BY document_id DESC LIMIT 5"
);
@@ -72,6 +77,7 @@ if (isset($_GET['query'])) {
WHERE file_archived_at IS NULL
AND (file_name LIKE '%$query%'
OR file_description LIKE '%$query%')
+ $access_permission_query
ORDER BY file_id DESC LIMIT 5"
);
@@ -81,6 +87,7 @@ if (isset($_GET['query'])) {
WHERE ticket_archived_at IS NULL
AND (ticket_subject LIKE '%$query%'
OR ticket_number = '$ticket_num_query')
+ $access_permission_query
ORDER BY ticket_id DESC LIMIT 5"
);
@@ -88,6 +95,7 @@ if (isset($_GET['query'])) {
LEFT JOIN clients ON scheduled_ticket_client_id = client_id
WHERE scheduled_ticket_subject LIKE '%$query%'
OR scheduled_ticket_details LIKE '%$query%'
+ $access_permission_query
ORDER BY scheduled_ticket_id DESC LIMIT 5"
);
@@ -96,6 +104,7 @@ if (isset($_GET['query'])) {
LEFT JOIN clients ON login_client_id = client_id
WHERE login_archived_at IS NULL
AND (login_name LIKE '%$query%' OR login_description LIKE '%$query%')
+ $access_permission_query
ORDER BY login_id DESC LIMIT 5"
);
@@ -104,6 +113,7 @@ if (isset($_GET['query'])) {
LEFT JOIN categories ON invoice_category_id = category_id
WHERE invoice_archived_at IS NULL
AND (CONCAT(invoice_prefix,invoice_number) LIKE '%$query%' OR invoice_scope LIKE '%$query%')
+ $access_permission_query
ORDER BY invoice_number DESC LIMIT 5"
);
@@ -113,6 +123,7 @@ if (isset($_GET['query'])) {
LEFT JOIN clients ON asset_client_id = client_id
WHERE asset_archived_at IS NULL
AND (asset_name LIKE '%$query%' OR asset_description LIKE '%$query%' OR asset_type LIKE '%$query%' OR asset_make LIKE '%$query%' OR asset_model LIKE '%$query%' OR asset_serial LIKE '%$query%' OR asset_os LIKE '%$query%' OR asset_ip LIKE '%$query%' OR asset_nat_ip LIKE '%$query%' OR asset_mac LIKE '%$query%' OR asset_status LIKE '%$query%')
+ $access_permission_query
ORDER BY asset_name DESC LIMIT 5"
);
@@ -121,6 +132,7 @@ if (isset($_GET['query'])) {
LEFT JOIN clients ON ticket_client_id = client_id
WHERE ticket_reply_archived_at IS NULL
AND (ticket_reply LIKE '%$query%')
+ $access_permission_query
ORDER BY ticket_id DESC, ticket_reply_id ASC LIMIT 20"
);
diff --git a/guest_header.php b/guest_header.php
index 9010d39a..ab0eff7d 100644
--- a/guest_header.php
+++ b/guest_header.php
@@ -15,6 +15,12 @@ $user_agent = sanitizeInput($_SERVER['HTTP_USER_AGENT']);
$os = sanitizeInput(getOS($user_agent));
$browser = sanitizeInput(getWebBrowser($user_agent));
+// Get Company Name
+$sql = mysqli_query($mysqli, "SELECT company_name FROM companies WHERE company_id = 1");
+$row = mysqli_fetch_array($sql);
+
+$session_company_name = $row['company_name'];
+
?>
@@ -25,7 +31,7 @@ $browser = sanitizeInput(getWebBrowser($user_agent));
-
+
-
-
-purify($row['ticket_details']);
$ticket_priority = nullable_htmlentities($row['ticket_priority']);
@@ -181,7 +176,7 @@ if (isset($_GET['ticket_id'])) {
// Client Tags
$client_tag_name_display_array = array();
$client_tag_id_array = array();
- $sql_client_tags = mysqli_query($mysqli, "SELECT * FROM client_tags LEFT JOIN tags ON client_tags.client_tag_tag_id = tags.tag_id WHERE client_tags.client_tag_client_id = $client_id ORDER BY tag_name ASC");
+ $sql_client_tags = mysqli_query($mysqli, "SELECT * FROM client_tags LEFT JOIN tags ON client_tags.tag_id = tags.tag_id WHERE client_id = $client_id ORDER BY tag_name ASC");
while ($row = mysqli_fetch_array($sql_client_tags)) {
$client_tag_id = intval($row['tag_id']);
@@ -206,6 +201,22 @@ if (isset($_GET['ticket_id'])) {
$row = mysqli_fetch_array($ticket_responses_sql);
$ticket_responses = intval($row['ticket_responses']);
+ $ticket_all_comments_sql = mysqli_query($mysqli, "SELECT COUNT(ticket_reply_id) AS ticket_all_comments_count FROM ticket_replies WHERE ticket_reply_archived_at IS NULL AND ticket_reply_ticket_id = $ticket_id");
+ $row = mysqli_fetch_array($ticket_all_comments_sql);
+ $ticket_all_comments_count = intval($row['ticket_all_comments_count']);
+
+ $ticket_internal_notes_sql = mysqli_query($mysqli, "SELECT COUNT(ticket_reply_id) AS ticket_internal_notes_count FROM ticket_replies WHERE ticket_reply_archived_at IS NULL AND ticket_reply_type = 'Internal' AND ticket_reply_ticket_id = $ticket_id");
+ $row = mysqli_fetch_array($ticket_internal_notes_sql);
+ $ticket_internal_notes_count = intval($row['ticket_internal_notes_count']);
+
+ $ticket_public_comments_sql = mysqli_query($mysqli, "SELECT COUNT(ticket_reply_id) AS ticket_public_comments_count FROM ticket_replies WHERE ticket_reply_archived_at IS NULL AND (ticket_reply_type = 'Public' OR ticket_reply_type = 'Client') AND ticket_reply_ticket_id = $ticket_id");
+ $row = mysqli_fetch_array($ticket_public_comments_sql);
+ $ticket_public_comments_count = intval($row['ticket_public_comments_count']);
+
+ $ticket_events_sql = mysqli_query($mysqli, "SELECT COUNT(ticket_reply_id) AS ticket_events_count FROM ticket_replies WHERE ticket_reply_archived_at IS NULL AND ticket_reply_type = 'Event' AND ticket_reply_ticket_id = $ticket_id");
+ $row = mysqli_fetch_array($ticket_events_sql);
+ $ticket_events_count = intval($row['ticket_events_count']);
+
// Get & format asset warranty expiry
$date = date('Y-m-d H:i:s');
@@ -371,13 +382,6 @@ if (isset($_GET['ticket_id'])) {
-
- Total time worked:
-
-
@@ -404,18 +408,33 @@ if (isset($_GET['ticket_id'])) {
-
+
Tasks Completed%
/
-
+
+
+ Total time worked:
+
+
+
+
+
+ 0) { ?>
+
+
+
+
+
@@ -451,7 +470,7 @@ if (isset($_GET['ticket_id'])) {
-
+
Close
@@ -513,28 +532,39 @@ if (isset($_GET['ticket_id'])) {
+