Merge branch 'master' into techbar
This commit is contained in:
@@ -93,6 +93,12 @@ if (isset($_GET['archived'])) {
|
||||
echo 'btn-default';
|
||||
} ?>">Payment
|
||||
Method</a>
|
||||
<a href="?category=Ticket"
|
||||
class="btn <?php if ($category == 'Ticket') {
|
||||
echo 'btn-primary';
|
||||
} else {
|
||||
echo 'btn-default';
|
||||
} ?>">Ticket</a>
|
||||
<a href="?archived=1"
|
||||
class="btn <?php if (isset($_GET['archived'])) {
|
||||
echo 'btn-primary';
|
||||
@@ -125,7 +131,7 @@ if (isset($_GET['archived'])) {
|
||||
$category_id = intval($row['category_id']);
|
||||
$category_name = nullable_htmlentities($row['category_name']);
|
||||
$category_color = nullable_htmlentities($row['category_color']);
|
||||
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<td><a class="text-dark" href="#" data-toggle="modal"
|
||||
@@ -170,7 +176,7 @@ if (isset($_GET['archived'])) {
|
||||
</tr>
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
include "admin_category_edit_modal.php";
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ function countFilesInDirectory($dir) {
|
||||
// Function to compare two arrays recursively and return the differences
|
||||
function arrayDiffRecursive($array1, $array2) {
|
||||
$diff = array();
|
||||
|
||||
|
||||
foreach ($array1 as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
if (!isset($array2[$key]) || !is_array($array2[$key])) {
|
||||
@@ -56,7 +56,7 @@ function arrayDiffRecursive($array1, $array2) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $diff;
|
||||
}
|
||||
|
||||
@@ -64,17 +64,17 @@ function arrayDiffRecursive($array1, $array2) {
|
||||
function loadTableStructuresFromSQLDumpURL($fileURL) {
|
||||
$context = stream_context_create(array('http' => array('header' => 'Accept: application/octet-stream')));
|
||||
$fileContent = file_get_contents($fileURL, false, $context);
|
||||
|
||||
|
||||
if ($fileContent === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
$structure = array();
|
||||
$queries = explode(";", $fileContent);
|
||||
|
||||
|
||||
foreach ($queries as $query) {
|
||||
$query = trim($query);
|
||||
|
||||
|
||||
if (!empty($query)) {
|
||||
if (preg_match("/^CREATE TABLE `(.*)` \((.*)\)$/s", $query, $matches)) {
|
||||
$tableName = $matches[1];
|
||||
@@ -83,7 +83,7 @@ function loadTableStructuresFromSQLDumpURL($fileURL) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $structure;
|
||||
}
|
||||
|
||||
@@ -91,31 +91,31 @@ function loadTableStructuresFromSQLDumpURL($fileURL) {
|
||||
function fetchDatabaseStructureFromServer() {
|
||||
|
||||
global $mysqli;
|
||||
|
||||
|
||||
$tables = array();
|
||||
|
||||
|
||||
// Fetch table names
|
||||
$result = $mysqli->query("SHOW TABLES");
|
||||
|
||||
|
||||
if ($result->num_rows > 0) {
|
||||
while ($row = $result->fetch_row()) {
|
||||
$tableName = $row[0];
|
||||
$tables[$tableName] = array();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Fetch table structures
|
||||
foreach ($tables as $tableName => &$table) {
|
||||
$result = $mysqli->query("SHOW CREATE TABLE `$tableName`");
|
||||
|
||||
|
||||
if ($result->num_rows > 0) {
|
||||
$row = $result->fetch_row();
|
||||
$table['structure'] = $row[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//$mysqli->close();
|
||||
|
||||
|
||||
return $tables;
|
||||
}
|
||||
|
||||
@@ -185,11 +185,12 @@ while ($row = $tablesResult->fetch_row()) {
|
||||
//Get loaded PHP modules
|
||||
$loadedModules = get_loaded_extensions();
|
||||
|
||||
//Get Versions
|
||||
//Get Server Info / Service versions
|
||||
$phpVersion = phpversion();
|
||||
$mysqlVersion = $mysqli->server_version;
|
||||
$operatingSystem = shell_exec('uname -a');
|
||||
$operatingSystem = php_uname();
|
||||
$webServer = $_SERVER['SERVER_SOFTWARE'];
|
||||
$errorLog = ini_get('error_log');
|
||||
|
||||
?>
|
||||
|
||||
@@ -198,20 +199,43 @@ $webServer = $_SERVER['SERVER_SOFTWARE'];
|
||||
<h3 class="card-title"><i class="fas fa-fw fa-bug mr-2"></i>Debug</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<h3>Database Structure Check</h3>
|
||||
|
||||
|
||||
<h3>Server Info</h3>
|
||||
|
||||
<?php
|
||||
echo "PHP version: " . $phpVersion . "<br>";
|
||||
echo "MySQL Version: " . $mysqlVersion . "<br>";
|
||||
echo "Operating System: " . $operatingSystem . "<br>";
|
||||
echo "Web Server: " . $webServer . "<br>";
|
||||
echo "PHP Error Log: " . $errorLog
|
||||
?>
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>File System</h3>
|
||||
<?php
|
||||
$result = countFilesInDirectory($folderPath);
|
||||
|
||||
$totalFiles = $result['count'];
|
||||
$totalSizeMB = round($result['size'] / (1024 * 1024), 2);
|
||||
|
||||
echo "Total number of files in $folderPath and its subdirectories: " . $totalFiles . "<br>";
|
||||
echo "Total size of files in $folderPath and its subdirectories: " . $totalSizeMB . " MB";
|
||||
?>
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>Database Structure Check</h3>
|
||||
|
||||
<h4>Database stats</h4>
|
||||
|
||||
|
||||
<?php
|
||||
echo "Number of tables: " . $numTables . "<br>";
|
||||
echo "Total number of fields: " . $numFields . "<br>";
|
||||
echo "Total number of rows: " . $numRows . "<br>";
|
||||
echo "Current Database Version: " . CURRENT_DATABASE_VERSION . "<br>";
|
||||
?>
|
||||
|
||||
|
||||
<hr>
|
||||
|
||||
<h4>Table Stats</h4>
|
||||
@@ -255,34 +279,8 @@ $webServer = $_SERVER['SERVER_SOFTWARE'];
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>Versions</h3>
|
||||
|
||||
<?php
|
||||
echo "PHP version: " . $phpVersion . "<br>";
|
||||
echo "MySQL Version: " . $mysqlVersion . "<br>";
|
||||
echo "Operating System: " . $operatingSystem . "<br>";
|
||||
echo "Web Server: " . $webServer;
|
||||
|
||||
|
||||
?>
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>File System</h3>
|
||||
<?php
|
||||
$result = countFilesInDirectory($folderPath);
|
||||
|
||||
$totalFiles = $result['count'];
|
||||
$totalSizeMB = round($result['size'] / (1024 * 1024), 2);
|
||||
|
||||
echo "Total number of files in $folderPath and its subdirectories: " . $totalFiles . "<br>";
|
||||
echo "Total size of files in $folderPath and its subdirectories: " . $totalSizeMB . " MB";
|
||||
?>
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>PHP Modules Installed</h3>
|
||||
|
||||
|
||||
<?php
|
||||
foreach ($loadedModules as $module) {
|
||||
echo $module . "<br>";
|
||||
@@ -311,7 +309,7 @@ $webServer = $_SERVER['SERVER_SOFTWARE'];
|
||||
//Output the result
|
||||
echo $phpinfo;
|
||||
?>
|
||||
|
||||
|
||||
<hr>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
<select class="form-control select2" name="type" required>
|
||||
<option value="">- Type -</option>
|
||||
<option value="1">Client Tag</option>
|
||||
<option value="2">Location Tag</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
<select class="form-control select2" name="type" required>
|
||||
<option value="">- Type -</option>
|
||||
<option value="1" <?php if ($tag_type == 1) { echo "selected"; } ?>>Client Tag</option>
|
||||
<option value="2" <?php if ($tag_type == 2) { echo "selected"; } ?>>Location Tag</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -62,6 +62,13 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
$tag_id = intval($row['tag_id']);
|
||||
$tag_name = nullable_htmlentities($row['tag_name']);
|
||||
$tag_type = intval($row['tag_type']);
|
||||
if ( $tag_type == 1) {
|
||||
$tag_type_display = "Client Tag";
|
||||
} elseif ( $tag_type == 2) {
|
||||
$tag_type_display = "Location Tag";
|
||||
} else {
|
||||
$tag_type_display = "Unknown Tag";
|
||||
}
|
||||
$tag_color = nullable_htmlentities($row['tag_color']);
|
||||
$tag_icon = nullable_htmlentities($row['tag_icon']);
|
||||
|
||||
@@ -72,7 +79,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<span class='badge text-light p-2 mr-1' style="background-color: <?php echo $tag_color; ?>"><i class="fa fa-fw fa-<?php echo $tag_icon; ?> mr-2"></i><?php echo $tag_name; ?></span>
|
||||
</a>
|
||||
</td>
|
||||
<td><?php echo $tag_type; ?></td>
|
||||
<td><?php echo $tag_type_display; ?></td>
|
||||
<td>
|
||||
<div class="dropdown dropleft text-center">
|
||||
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
|
||||
|
||||
@@ -3,19 +3,12 @@ require_once "inc_all_admin.php";
|
||||
|
||||
require_once "database_version.php";
|
||||
|
||||
require_once "config.php";
|
||||
|
||||
$updates = fetchUpdates();
|
||||
|
||||
// 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]";
|
||||
}
|
||||
$latest_version = $updates->latest_version;
|
||||
$current_version = $updates->current_version;
|
||||
$result = $updates->result;
|
||||
|
||||
$git_log = shell_exec("git log $repo_branch..origin/$repo_branch --pretty=format:'<tr><td>%h</td><td>%ar</td><td>%s</td></tr>'");
|
||||
|
||||
|
||||
@@ -55,13 +55,42 @@
|
||||
</div>
|
||||
<select class="form-control select2" name="role" required>
|
||||
<option value="">- Role -</option>
|
||||
<option value="3">Administrator</option>
|
||||
<option value="2">Technician</option>
|
||||
<option value="1">Accountant</option>
|
||||
<?php
|
||||
$sql_user_roles = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE user_role_archived_at IS NULL");
|
||||
while ($row = mysqli_fetch_array($sql_user_roles)) {
|
||||
$user_role_id = intval($row['user_role_id']);
|
||||
$user_role_name = nullable_htmlentities($row['user_role_name']);
|
||||
|
||||
?>
|
||||
<option value="<?php echo $user_role_id; ?>"><?php echo $user_role_name; ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Restrict Client Access</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-users"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="clients[]" data-placeholder="Restrict Client Access" multiple>
|
||||
<?php
|
||||
|
||||
$sql_client_select = mysqli_query($mysqli, "SELECT * FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_client_select)) {
|
||||
$client_id = intval($row['client_id']);
|
||||
$client_name = nullable_htmlentities($row['client_name']);
|
||||
|
||||
?>
|
||||
<option value="<?php echo $client_id; ?>"><?php echo $client_name; ?></option>
|
||||
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
<small class="text-muted">Leave Blank for Full access to all clients, no affect on users with the admin role.</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Avatar</label>
|
||||
<input type="file" class="form-control-file" accept="image/*;capture=camera" name="file">
|
||||
|
||||
@@ -67,23 +67,43 @@
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="role" required>
|
||||
<option value="">- Role -</option>
|
||||
<option <?php if ($user_role == 3) {
|
||||
echo "selected";
|
||||
} ?> value="3">Administrator
|
||||
</option>
|
||||
<option <?php if ($user_role == 2) {
|
||||
echo "selected";
|
||||
} ?> value="2">Technician
|
||||
</option>
|
||||
<option <?php if ($user_role == 1) {
|
||||
echo "selected";
|
||||
} ?> value="1">Accountant
|
||||
</option>
|
||||
<?php
|
||||
$sql_user_roles = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE user_role_archived_at IS NULL");
|
||||
while ($row = mysqli_fetch_array($sql_user_roles)) {
|
||||
$user_role_id = intval($row['user_role_id']);
|
||||
$user_role_name = nullable_htmlentities($row['user_role_name']);
|
||||
|
||||
?>
|
||||
<option <?php if ($user_role == $user_role_id) {echo "selected";} ?> value="<?php echo $user_role_id; ?>"><?php echo $user_role_name; ?></option>
|
||||
<?php } ?>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Restrict Client Access</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-users"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="clients[]" data-placeholder="Restrict Client Access" multiple>
|
||||
<?php
|
||||
|
||||
$sql_client_select = mysqli_query($mysqli, "SELECT * FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_client_select)) {
|
||||
$client_id_select = intval($row['client_id']);
|
||||
$client_name_select = nullable_htmlentities($row['client_name']);
|
||||
|
||||
?>
|
||||
<option <?php if (in_array($client_id_select, $client_access_array)) { echo "selected"; } ?> value="<?php echo $client_id_select; ?>"><?php echo $client_name_select; ?></option>
|
||||
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
<small class="text-muted">Leave Blank for Full access to all clients, no affect on users with the admin role.</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Avatar</label>
|
||||
<input type="file" class="form-control-file" accept="image/*;capture=camera" name="file">
|
||||
|
||||
@@ -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<small class='text-secondary'><div class='mt-1'>$log_user_os</div><div class='mt-1'>$log_user_browser</div><div class='mt-1'><i class='fa fa-fw fa-globe'></i> $log_ip</div></small>";
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<td class="text-center">
|
||||
|
||||
31
ajax.php
31
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";
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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',
|
||||
|
||||
<?php
|
||||
// User preference for Calendar start day (Sunday/Monday)
|
||||
// Fetch User Dashboard Settings
|
||||
$row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT user_config_calendar_first_day FROM user_settings WHERE user_id = $session_user_id"));
|
||||
$user_config_calendar_first_day = intval($row['user_config_calendar_first_day']);
|
||||
?>
|
||||
firstDay: <?php echo $user_config_calendar_first_day ?>,
|
||||
});
|
||||
|
||||
calendar.render();
|
||||
|
||||
@@ -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");
|
||||
//}
|
||||
|
||||
|
||||
@@ -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()"));
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
|
||||
<div class="modal-body bg-white">
|
||||
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label>Description</label>
|
||||
<div class="input-group">
|
||||
@@ -47,7 +47,7 @@
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<input type="file" class="form-control-file" name="file[]" multiple id="fileInput" accept=".jpg, .jpeg, .gif, .png, .webp, .pdf, .txt, .md, .doc, .docx, .odt, .csv, .xls, .xlsx, .ods, .pptx, .odp, .zip, .tar, .gz, .xml, .msg, .json, .wav, .mp3, .ogg, .mov, .mp4, .av1, .ovpn, .cfg, .ps1, .vsdx, .drawio, .pfx">
|
||||
<input type="file" class="form-control-file" name="file[]" multiple id="fileInput" accept=".jpg, .jpeg, .gif, .png, .webp, .pdf, .txt, .md, .doc, .docx, .odt, .csv, .xls, .xlsx, .ods, .pptx, .odp, .zip, .tar, .gz, .xml, .msg, .json, .wav, .mp3, .ogg, .mov, .mp4, .av1, .ovpn, .cfg, .ps1, .vsdx, .drawio, .pfx, .unf">
|
||||
</div>
|
||||
<small class="text-secondary">Up to 20 files can be uploaded at once by holding down CTRL and selecting files</small>
|
||||
|
||||
|
||||
@@ -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()"));
|
||||
|
||||
|
||||
@@ -168,10 +168,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<textarea class="form-control" rows="6" name="notes" placeholder="Notes, eg Parking Info, Building Access etc"></textarea>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-notes">
|
||||
@@ -180,6 +176,27 @@
|
||||
<textarea class="form-control" rows="12" name="notes" placeholder="Notes, eg Parking Info, Building Access etc"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Tags</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-tags"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="tags[]" data-placeholder="Add some tags" multiple>
|
||||
<?php
|
||||
|
||||
$sql_tags_select = mysqli_query($mysqli, "SELECT * FROM tags WHERE tag_type = 2 ORDER BY tag_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_tags_select)) {
|
||||
$tag_id_select = intval($row['tag_id']);
|
||||
$tag_name_select = nullable_htmlentities($row['tag_name']);
|
||||
?>
|
||||
<option value="<?php echo $tag_id_select; ?>"><?php echo $tag_name_select; ?></option>
|
||||
<?php } ?>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -194,6 +194,27 @@
|
||||
<textarea class="form-control" rows="12" name="notes" placeholder="Notes, eg Parking Info, Building Access etc"><?php echo $location_notes; ?></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Tags</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-tags"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="tags[]" data-placeholder="Add some tags" multiple>
|
||||
<?php
|
||||
|
||||
$sql_tags_select = mysqli_query($mysqli, "SELECT * FROM tags WHERE tag_type = 2 ORDER BY tag_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_tags_select)) {
|
||||
$tag_id_select = intval($row['tag_id']);
|
||||
$tag_name_select = nullable_htmlentities($row['tag_name']);
|
||||
?>
|
||||
<option value="<?php echo $tag_id_select; ?>" <?php if (in_array($tag_id_select, $location_tag_id_array)) { echo "selected"; } ?>><?php echo $tag_name_select; ?></option>
|
||||
<?php } ?>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -12,10 +12,13 @@ $url_query_strings_sort = http_build_query($get_copy);
|
||||
|
||||
$sql = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT SQL_CALC_FOUND_ROWS * FROM locations
|
||||
"SELECT SQL_CALC_FOUND_ROWS locations.*, GROUP_CONCAT(tag_name) FROM locations
|
||||
LEFT JOIN location_tags ON location_tags.location_id = locations.location_id
|
||||
LEFT JOIN tags ON tags.tag_id = location_tags.tag_id
|
||||
WHERE location_client_id = $client_id
|
||||
AND location_$archive_query
|
||||
AND (location_name LIKE '%$q%' OR location_description LIKE '%$q%' OR location_address LIKE '%$q%' OR location_phone LIKE '%$phone_query%')
|
||||
AND (location_name LIKE '%$q%' OR location_description LIKE '%$q%' OR location_address LIKE '%$q%' OR location_phone LIKE '%$phone_query%' OR tag_name LIKE '%$q%')
|
||||
GROUP BY location_id
|
||||
ORDER BY location_primary DESC, $sort $order LIMIT $record_from, $record_to"
|
||||
);
|
||||
|
||||
@@ -118,6 +121,29 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
$location_primary_display = "";
|
||||
}
|
||||
|
||||
// Tags
|
||||
|
||||
$location_tag_name_display_array = array();
|
||||
$location_tag_id_array = array();
|
||||
$sql_location_tags = mysqli_query($mysqli, "SELECT * FROM location_tags LEFT JOIN tags ON location_tags.tag_id = tags.tag_id WHERE location_tags.location_id = $location_id ORDER BY tag_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_location_tags)) {
|
||||
|
||||
$location_tag_id = intval($row['tag_id']);
|
||||
$location_tag_name = nullable_htmlentities($row['tag_name']);
|
||||
$location_tag_color = nullable_htmlentities($row['tag_color']);
|
||||
if (empty($location_tag_color)) {
|
||||
$location_tag_color = "dark";
|
||||
}
|
||||
$location_tag_icon = nullable_htmlentities($row['tag_icon']);
|
||||
if (empty($location_tag_icon)) {
|
||||
$location_tag_icon = "tag";
|
||||
}
|
||||
|
||||
$location_tag_id_array[] = $location_tag_id;
|
||||
$location_tag_name_display_array[] = "<a href='client_locations.php?client_id=$client_id&q=$location_tag_name'><span class='badge text-light p-1 mr-1' style='background-color: $location_tag_color;'><i class='fa fa-fw fa-$location_tag_icon mr-2'></i>$location_tag_name</span></a>";
|
||||
}
|
||||
$location_tags_display = implode('', $location_tag_name_display_array);
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
@@ -128,6 +154,12 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<div <?php if($location_primary) { echo "class='text-bold'"; } ?>><?php echo $location_name; ?></div>
|
||||
<div><small class="text-secondary"><?php echo $location_description; ?></small></div>
|
||||
<div><?php echo $location_primary_display; ?></div>
|
||||
<?php
|
||||
if (!empty($location_tags_display)) { ?>
|
||||
<div class="mt-1">
|
||||
<?php echo $location_tags_display; ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
@@ -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<button class='btn btn-sm clipboardjs' type='button' data-clipboard-text='$login_uri'><i class='far fa-copy text-secondary'></i></button>";
|
||||
} else {
|
||||
$login_uri_display = truncate($login_uri,40) . "<button class='btn btn-sm clipboardjs' type='button' data-clipboard-text='$login_uri'><i class='far fa-copy text-secondary'></i></button>";
|
||||
}
|
||||
$login_uri_2 = nullable_htmlentities($row['login_uri_2']);
|
||||
$login_username = nullable_htmlentities(decryptLoginEntry($row['login_username']));
|
||||
|
||||
27
clients.php
27
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']);
|
||||
|
||||
18
cron.php
18
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
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
58
db.sql
58
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
|
||||
|
||||
@@ -36,8 +36,9 @@ require_once "header.php";
|
||||
|
||||
if (!empty($session_token)) {
|
||||
|
||||
//Generate QR Code based off the generated key
|
||||
print sprintf('<img src="%s"/>', TokenAuth6238::getBarCodeUrl($session_name, ' ', $session_token, $_SERVER['SERVER_NAME']));
|
||||
// Generate QR Code
|
||||
$data = "otpauth://totp/ITFlow:$session_email?secret=$session_token";
|
||||
print "<img src='plugins/barcode/barcode.php?f=png&s=qr&d=$data'>";
|
||||
|
||||
echo "<p class='text-secondary'>$session_token</p>";
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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']);
|
||||
|
||||
@@ -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"
|
||||
);
|
||||
|
||||
|
||||
@@ -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'];
|
||||
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
@@ -25,7 +31,7 @@ $browser = sanitizeInput(getWebBrowser($user_agent));
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<meta name="robots" content="noindex">
|
||||
|
||||
<title><?php echo nullable_htmlentities($config_app_name); ?></title>
|
||||
<title><?php echo nullable_htmlentities($session_company_name); ?></title>
|
||||
|
||||
<!--
|
||||
Favicon
|
||||
|
||||
@@ -12,6 +12,10 @@ require_once "top_nav.php";
|
||||
|
||||
// Get Main Side Bar Badge Counts
|
||||
|
||||
// Active Clients Count
|
||||
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('client_id') AS num FROM clients WHERE client_archived_at IS NULL"));
|
||||
$num_active_clients = $row['num'];
|
||||
|
||||
// Active Ticket Count
|
||||
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('ticket_id') AS num FROM tickets WHERE ticket_archived_at IS NULL AND ticket_closed_at IS NULL AND ticket_status != 4"));
|
||||
$num_active_tickets = $row['num'];
|
||||
|
||||
@@ -6,14 +6,22 @@ require_once "functions.php";
|
||||
|
||||
require_once "check_login.php";
|
||||
|
||||
require_once "header.php";
|
||||
|
||||
require_once "top_nav.php";
|
||||
|
||||
|
||||
if (isset($_GET['client_id'])) {
|
||||
$client_id = intval($_GET['client_id']);
|
||||
|
||||
// Check to see if the logged in user has permission to access this client (Admins have access to all no matter what perms are set)
|
||||
if(!in_array($client_id, $client_access_array) AND !empty($client_access_string) AND $session_user_role < 3) {
|
||||
// Logging
|
||||
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Client', log_action = 'Access', log_description = '$session_name was denied permission from accessing client', log_ip = '$session_ip', log_user_agent = '$session_user_agent', log_client_id = $client_id, log_user_id = $session_user_id, log_entity_id = $client_id");
|
||||
|
||||
$_SESSION['alert_type'] = "error";
|
||||
$_SESSION['alert_message'] = "Access Denied - You do not have permission to access that client!";
|
||||
|
||||
echo "<script>window.history.back();</script>";
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
$sql = mysqli_query($mysqli, "UPDATE clients SET client_accessed_at = NOW() WHERE client_id = $client_id");
|
||||
|
||||
$sql = mysqli_query(
|
||||
@@ -69,7 +77,7 @@ if (isset($_GET['client_id'])) {
|
||||
|
||||
$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']);
|
||||
@@ -231,6 +239,10 @@ if (isset($_GET['client_id'])) {
|
||||
}
|
||||
}
|
||||
|
||||
require_once "header.php";
|
||||
|
||||
require_once "top_nav.php";
|
||||
|
||||
require_once "client_side_nav.php";
|
||||
|
||||
require_once "inc_wrapper.php";
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
// ticketCounter.js
|
||||
(function() {
|
||||
function getRunningTicketCount() {
|
||||
let count = 0;
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
let key = localStorage.key(i);
|
||||
if (key.includes("ticket-timer-running")) {
|
||||
let isRunning = JSON.parse(localStorage.getItem(key));
|
||||
if (isRunning) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
function updateTicketCountDisplay() {
|
||||
let count = getRunningTicketCount();
|
||||
let countDisplay = document.getElementById("runningTicketsCount");
|
||||
if (countDisplay) {
|
||||
countDisplay.innerText = count;
|
||||
}
|
||||
if (count == 0) {
|
||||
countDisplay.classList.remove('badge-danger');
|
||||
} else {
|
||||
//check to see if more than one ticket
|
||||
if (count > 1) {
|
||||
countDisplay.classList.add('badge-danger');
|
||||
}
|
||||
//if count is one, check to see if its open in the current window by looking at the post variable ticket_id in url
|
||||
if (count == 1) {
|
||||
let urlParams = new URLSearchParams(window.location.search);
|
||||
let ticketID = urlParams.get('ticket_id');
|
||||
console.log(ticketID);
|
||||
// If ticket number equals one in local storage, then add badge-danger class
|
||||
if (localStorage.getItem("ticket-timer-running-") == ticketID) {
|
||||
countDisplay.classList.add('badge-danger');
|
||||
} else {
|
||||
countDisplay.classList.remove('badge-danger');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getElapsedSeconds(ticketID) {
|
||||
let storedStartTime = parseInt(localStorage.getItem(ticketID + "-startTime") || "0");
|
||||
let pausedTime = parseInt(localStorage.getItem(ticketID + "-pausedTime") || "0");
|
||||
if (!storedStartTime) return pausedTime;
|
||||
let timeSinceStart = Math.floor((Date.now() - storedStartTime) / 1000);
|
||||
return pausedTime + timeSinceStart;
|
||||
}
|
||||
|
||||
function formatTime(seconds) {
|
||||
let hours = Math.floor(seconds / 3600);
|
||||
let minutes = Math.floor((seconds % 3600) / 60);
|
||||
let secs = seconds % 60;
|
||||
return `${hours}h ${minutes}m ${secs}s`;
|
||||
}
|
||||
|
||||
function loadOpenTickets() {
|
||||
let openTicketsContainer = document.getElementById('openTicketsContainer');
|
||||
openTicketsContainer.innerHTML = ''; // Clear existing content
|
||||
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
let key = localStorage.key(i);
|
||||
|
||||
if (key.startsWith("ticket-timer-running-")) {
|
||||
let ticketID = key.replace("ticket-timer-running-", "");
|
||||
let isRunning = JSON.parse(localStorage.getItem(key));
|
||||
|
||||
let ticketDiv = document.createElement('div');
|
||||
ticketDiv.classList.add('card', 'card-outline', 'mb-3');
|
||||
// Add class based on ticket status
|
||||
ticketDiv.classList.add(isRunning ? 'card-info' : 'card-warning');
|
||||
ticketDiv.id = 'ticket-' + ticketID;
|
||||
|
||||
let elapsedSecs = getElapsedSeconds(ticketID);
|
||||
let timeString = formatTime(elapsedSecs);
|
||||
|
||||
ticketDiv.innerHTML = `
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Ticket ID: ${ticketID}</h3>
|
||||
<a href="/ticket.php?ticket_id=${ticketID}" class="btn btn-primary float-right">View Ticket</a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p id="time-${ticketID}">Total Time: ${timeString}</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
openTicketsContainer.appendChild(ticketDiv);
|
||||
}
|
||||
}
|
||||
|
||||
requestAnimationFrame(() => updateRunningTickets());
|
||||
}
|
||||
|
||||
function updateRunningTickets() {
|
||||
let runningTickets = document.querySelectorAll('[id^="ticket-"]');
|
||||
runningTickets.forEach(ticket => {
|
||||
let ticketID = ticket.id.replace("ticket-", "");
|
||||
let isRunning = JSON.parse(localStorage.getItem("ticket-timer-running-" + ticketID));
|
||||
|
||||
if (isRunning) {
|
||||
let updatedTime = formatTime(getElapsedSeconds(ticketID));
|
||||
document.getElementById('time-' + ticketID).innerText = 'Total Time: ' + updatedTime;
|
||||
}
|
||||
});
|
||||
|
||||
requestAnimationFrame(updateRunningTickets);
|
||||
}
|
||||
|
||||
function clearAllTimers() {
|
||||
// Collect keys to be removed
|
||||
let keysToRemove = [];
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
let key = localStorage.key(i);
|
||||
if (key.startsWith("ticket-timer-running-") || key.endsWith("-startTime") || key.endsWith("-pausedTime")) {
|
||||
keysToRemove.push(key);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove collected keys
|
||||
keysToRemove.forEach(key => localStorage.removeItem(key));
|
||||
|
||||
// Update the display and redirect
|
||||
updateTicketCountDisplay();
|
||||
window.location.href = "/tickets.php";
|
||||
}
|
||||
|
||||
// Initial update on script load
|
||||
updateTicketCountDisplay();
|
||||
|
||||
// update every 10 seconds
|
||||
setInterval(updateTicketCountDisplay, 10000);
|
||||
|
||||
// Add event listener to modal
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
let modal = document.getElementById('openTicketsModal');
|
||||
if (modal) {
|
||||
$('#openTicketsModal').on('show.bs.modal', loadOpenTickets);
|
||||
}
|
||||
});
|
||||
|
||||
// Add event listener to clear all timers button
|
||||
document.getElementById('clearAllTimers').addEventListener('click', clearAllTimers);
|
||||
|
||||
})();
|
||||
@@ -19,6 +19,7 @@ function populateRecurringTicketEditModal(client_id, ticket_id) {
|
||||
document.getElementById("editHeader").innerText = " Edit Recurring ticket: " + ticket.scheduled_ticket_subject;
|
||||
document.getElementById("editTicketId").value = ticket_id;
|
||||
document.getElementById("editClientId").value = client_id;
|
||||
document.getElementById("editTicketBillable").value = ticket.scheduled_ticket_billable;
|
||||
document.getElementById("editTicketSubject").value = ticket.scheduled_ticket_subject;
|
||||
document.getElementById("editTicketNextRun").value = ticket.scheduled_ticket_next_run;
|
||||
tinyMCE.get('editTicketDetails').setContent(ticket.scheduled_ticket_details);
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
// Ticket.php - Changes the wording of the "Respond" button to "Add note" if reply is not a public update (based on checkbox)
|
||||
|
||||
// Get Internal/Public Checkbox
|
||||
let checkbox = document.getElementById('ticket_reply_type_checkbox');
|
||||
|
||||
// Get Respond button
|
||||
let respond = document.getElementById('ticket_add_reply');
|
||||
|
||||
// When checkbox is checked/unchecked, update button wording
|
||||
checkbox.addEventListener('change', e => {
|
||||
if (e.target.checked) {
|
||||
// Public reply
|
||||
respond.innerHTML = "<i class=\"fas fa-paper-plane mr-2\"></i>Respond";
|
||||
|
||||
} else {
|
||||
// Internal note
|
||||
respond.innerHTML = "<i class=\"fas fa-sticky-note mr-2\"></i>Add note";
|
||||
}
|
||||
});
|
||||
@@ -8,8 +8,6 @@
|
||||
var ticketID = getCurrentTicketID();
|
||||
var elapsedSecs = getElapsedSeconds();
|
||||
|
||||
updateRunningTicketsCount();
|
||||
|
||||
function getCurrentTicketID() {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
return urlParams.get('ticket_id');
|
||||
@@ -55,7 +53,6 @@
|
||||
timerInterval = setInterval(countTime, 1000);
|
||||
isPaused = false;
|
||||
document.getElementById("startStopTimer").innerText = "Pause";
|
||||
updateRunningTicketsCount();
|
||||
localStorage.setItem("ticket-timer-running-" + ticketID, "true");
|
||||
|
||||
}
|
||||
@@ -70,7 +67,6 @@
|
||||
localStorage.removeItem(getLocalStorageKey("startTime"));
|
||||
isPaused = true;
|
||||
document.getElementById("startStopTimer").innerText = "Start";
|
||||
updateRunningTicketsCount();
|
||||
localStorage.setItem("ticket-timer-running-" + ticketID, "false");
|
||||
|
||||
}
|
||||
@@ -91,7 +87,6 @@
|
||||
document.getElementById("startStopTimer").innerText = "Start";
|
||||
}
|
||||
localStorage.setItem("ticket-timer-running-" + ticketID, "false");
|
||||
updateRunningTicketsCount();
|
||||
}
|
||||
|
||||
function forceResetTimer() {
|
||||
@@ -102,7 +97,7 @@
|
||||
displayTime();
|
||||
document.getElementById("startStopTimer").innerText = "Start";
|
||||
}
|
||||
|
||||
|
||||
function handleInputFocus() {
|
||||
if (!isPaused) {
|
||||
pauseTimer();
|
||||
@@ -114,7 +109,7 @@
|
||||
const minutes = parseInt(document.getElementById("minutes").value, 10) || 0;
|
||||
const seconds = parseInt(document.getElementById("seconds").value, 10) || 0;
|
||||
elapsedSecs = (hours * 3600) + (minutes * 60) + seconds;
|
||||
|
||||
|
||||
// Update local storage so the manually entered time is retained even if the page is reloaded.
|
||||
if (!timerInterval) {
|
||||
localStorage.setItem(getLocalStorageKey("pausedTime"), elapsedSecs.toString());
|
||||
@@ -125,18 +120,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
function updateRunningTicketsCount() {
|
||||
let runningTickets = parseInt(document.getElementById('runningTicketsCount').innerText, 10);
|
||||
|
||||
if (!isPaused && timerInterval) {
|
||||
runningTickets += 1;
|
||||
} else {
|
||||
runningTickets = Math.max(0, runningTickets - 1);
|
||||
}
|
||||
|
||||
document.getElementById('runningTicketsCount').innerText = runningTickets.toString();
|
||||
}
|
||||
|
||||
// Function to check status and pause timer
|
||||
function checkStatusAndPauseTimer() {
|
||||
var status = document.querySelector('select[name="status"]').value;
|
||||
@@ -148,7 +131,7 @@
|
||||
document.getElementById("hours").addEventListener('change', updateTimeFromInput);
|
||||
document.getElementById("minutes").addEventListener('change', updateTimeFromInput);
|
||||
document.getElementById("seconds").addEventListener('change', updateTimeFromInput);
|
||||
|
||||
|
||||
document.getElementById("hours").addEventListener('focus', handleInputFocus);
|
||||
document.getElementById("minutes").addEventListener('focus', handleInputFocus);
|
||||
document.getElementById("seconds").addEventListener('focus', handleInputFocus);
|
||||
@@ -184,11 +167,11 @@
|
||||
} else if (localStorage.getItem(getLocalStorageKey("startTime"))) {
|
||||
startTimer();
|
||||
}
|
||||
|
||||
|
||||
// Check and pause timer if status is pending
|
||||
checkStatusAndPauseTimer();
|
||||
} catch (error) {
|
||||
console.error("There was an issue initializing the timer:", error);
|
||||
}
|
||||
});
|
||||
})();
|
||||
})();
|
||||
|
||||
10
login.php
10
login.php
@@ -159,7 +159,7 @@ if (isset($_POST['login'])) {
|
||||
if (isset($_POST['remember_me'])) {
|
||||
// TODO: Record the UA and IP a token is generated from so that can be shown later on
|
||||
$newRememberToken = bin2hex(random_bytes(64));
|
||||
setcookie('rememberme', $newRememberToken, time() + 86400*2, "/", null, true, true);
|
||||
setcookie('rememberme', $newRememberToken, time() + 86400*$config_login_remember_me_expire, "/", null, true, true);
|
||||
mysqli_query($mysqli, "INSERT INTO remember_tokens SET remember_token_user_id = $user_id, remember_token_token = '$newRememberToken'");
|
||||
|
||||
$extended_log .= ", generated a new remember-me token";
|
||||
@@ -218,9 +218,11 @@ if (isset($_POST['login'])) {
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
header("Location: $config_start_page");
|
||||
|
||||
if ($_GET['last_visited']) {
|
||||
header("Location: ".$_SERVER["REQUEST_SCHEME"] . "://" . $config_base_url . base64_decode($_GET['last_visited']) );
|
||||
} else {
|
||||
header("Location: $config_start_page");
|
||||
}
|
||||
} else {
|
||||
|
||||
// MFA is configured and needs to be confirmed, or was unsuccessful
|
||||
|
||||
3352
plugins/barcode/barcode.php
Normal file
3352
plugins/barcode/barcode.php
Normal file
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,7 @@ if (isset($_GET['ai_reword'])) {
|
||||
$inputJSON = file_get_contents('php://input');
|
||||
$input = json_decode($inputJSON, TRUE); // Convert JSON into array.
|
||||
|
||||
$promptText = "You are an experienced technician at a help desk, training a new technician. You are helping rewrite response for clarity and professionalism, but dont make it too wordy.";
|
||||
$promptText = "reword with html format";
|
||||
$userText = $input['text'];
|
||||
|
||||
// Preparing the data for the OpenAI Chat API request.
|
||||
|
||||
@@ -65,7 +65,7 @@ if (isset($_POST['add_client'])) {
|
||||
if (isset($_POST['tags'])) {
|
||||
foreach($_POST['tags'] as $tag) {
|
||||
$tag = intval($tag);
|
||||
mysqli_query($mysqli, "INSERT INTO client_tags SET client_tag_client_id = $client_id, client_tag_tag_id = $tag");
|
||||
mysqli_query($mysqli, "INSERT INTO client_tags SET client_id = $client_id, tag_id = $tag");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,12 +135,12 @@ if (isset($_POST['edit_client'])) {
|
||||
|
||||
// Tags
|
||||
// Delete existing tags
|
||||
mysqli_query($mysqli, "DELETE FROM client_tags WHERE client_tag_client_id = $client_id");
|
||||
mysqli_query($mysqli, "DELETE FROM client_tags WHERE client_id = $client_id");
|
||||
|
||||
// Add new tags
|
||||
foreach($_POST['tags'] as $tag) {
|
||||
$tag = intval($tag);
|
||||
mysqli_query($mysqli, "INSERT INTO client_tags SET client_tag_client_id = $client_id, client_tag_tag_id = $tag");
|
||||
mysqli_query($mysqli, "INSERT INTO client_tags SET client_id = $client_id, tag_id = $tag");
|
||||
}
|
||||
|
||||
// Logging
|
||||
@@ -297,6 +297,9 @@ if (isset($_GET['delete_client'])) {
|
||||
mysqli_query($mysqli, "DELETE FROM trips WHERE trip_client_id = $client_id");
|
||||
mysqli_query($mysqli, "DELETE FROM vendors WHERE vendor_client_id = $client_id");
|
||||
|
||||
// Delete tags
|
||||
mysqli_query($mysqli, "DELETE FROM client_tags WHERE client_id = $client_id");
|
||||
|
||||
//Delete Client Files
|
||||
removeDirectory('uploads/clients/$client_id');
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ if (isset($_POST['upload_files'])) {
|
||||
'size' => $_FILES['file']['size'][$i]
|
||||
];
|
||||
|
||||
if ($file_reference_name = checkFileUpload($single_file, array('jpg', 'jpeg', 'gif', 'png', 'webp', 'pdf', 'txt', 'md', 'doc', 'docx', 'odt', 'csv', 'xls', 'xlsx', 'ods', 'pptx', 'odp', 'zip', 'tar', 'gz', 'xml', 'msg', 'json', 'wav', 'mp3', 'ogg', 'mov', 'mp4', 'av1', 'ovpn', 'cfg', 'ps1', 'vsdx', 'drawio', 'pfx', 'pages', 'numbers'))) {
|
||||
if ($file_reference_name = checkFileUpload($single_file, array('jpg', 'jpeg', 'gif', 'png', 'webp', 'pdf', 'txt', 'md', 'doc', 'docx', 'odt', 'csv', 'xls', 'xlsx', 'ods', 'pptx', 'odp', 'zip', 'tar', 'gz', 'xml', 'msg', 'json', 'wav', 'mp3', 'ogg', 'mov', 'mp4', 'av1', 'ovpn', 'cfg', 'ps1', 'vsdx', 'drawio', 'pfx', 'pages', 'numbers', 'unf'))) {
|
||||
|
||||
$file_tmp_path = $_FILES['file']['tmp_name'][$i];
|
||||
|
||||
|
||||
@@ -19,6 +19,14 @@ if(isset($_POST['add_location'])){
|
||||
|
||||
$location_id = mysqli_insert_id($mysqli);
|
||||
|
||||
// Add Tags
|
||||
if (isset($_POST['tags'])) {
|
||||
foreach($_POST['tags'] as $tag) {
|
||||
$tag = intval($tag);
|
||||
mysqli_query($mysqli, "INSERT INTO location_tags SET location_id = $location_id, tag_id = $tag");
|
||||
}
|
||||
}
|
||||
|
||||
// Update Primay location in clients if primary location is checked
|
||||
if ($location_primary == 1) {
|
||||
mysqli_query($mysqli,"UPDATE locations SET location_primary = 0 WHERE location_client_id = $client_id");
|
||||
@@ -82,6 +90,16 @@ if(isset($_POST['edit_location'])){
|
||||
mysqli_query($mysqli,"UPDATE locations SET location_primary = 1 WHERE location_id = $location_id");
|
||||
}
|
||||
|
||||
// Tags
|
||||
// Delete existing tags
|
||||
mysqli_query($mysqli, "DELETE FROM location_tags WHERE location_id = $location_id");
|
||||
|
||||
// Add new tags
|
||||
foreach($_POST['tags'] as $tag) {
|
||||
$tag = intval($tag);
|
||||
mysqli_query($mysqli, "INSERT INTO location_tags SET location_id = $location_id, tag_id = $tag");
|
||||
}
|
||||
|
||||
//Check to see if a file is attached
|
||||
if($_FILES['file']['tmp_name'] != ''){
|
||||
|
||||
@@ -174,6 +192,10 @@ if(isset($_GET['delete_location'])){
|
||||
|
||||
mysqli_query($mysqli,"DELETE FROM locations WHERE location_id = $location_id");
|
||||
|
||||
// Tags
|
||||
// Delete existing tags
|
||||
mysqli_query($mysqli, "DELETE FROM location_tags WHERE location_id = $location_id");
|
||||
|
||||
//Logging
|
||||
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Location', log_action = 'Delete', log_description = '$session_name deleted location $location_name', log_ip = '$session_ip', log_user_agent = '$session_user_agent', log_client_id = $client_id, log_user_id = $session_user_id, log_entity_id = $location_id");
|
||||
|
||||
|
||||
@@ -144,11 +144,18 @@ if (isset($_POST['edit_your_user_password'])) {
|
||||
header('Location: post.php?logout');
|
||||
}
|
||||
|
||||
if (isset($_POST['edit_your_user_browser_extention'])) {
|
||||
if (isset($_POST['edit_your_user_preferences'])) {
|
||||
|
||||
// CSRF Check
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$calendar_first_day = intval($_POST['calendar_first_day']);
|
||||
|
||||
// Calendar
|
||||
if (isset($calendar_first_day)) {
|
||||
mysqli_query($mysqli, "UPDATE user_settings SET user_config_calendar_first_day = $calendar_first_day WHERE user_id = $session_user_id");
|
||||
}
|
||||
|
||||
// Enable extension access, only if it isn't already setup (user doesn't have cookie)
|
||||
if (isset($_POST['extension']) && $_POST['extension'] == 'Yes') {
|
||||
if (!isset($_COOKIE['user_extension_key'])) {
|
||||
|
||||
@@ -36,6 +36,7 @@ if (isset($_POST['add_quote'])) {
|
||||
if (isset($_POST['add_quote_copy'])) {
|
||||
|
||||
$quote_id = intval($_POST['quote_id']);
|
||||
$client_id = intval($_POST['client']);
|
||||
$date = sanitizeInput($_POST['date']);
|
||||
$expire = sanitizeInput($_POST['expire']);
|
||||
|
||||
@@ -51,7 +52,6 @@ if (isset($_POST['add_quote_copy'])) {
|
||||
$quote_currency_code = sanitizeInput($row['quote_currency_code']);
|
||||
$quote_scope = sanitizeInput($row['quote_scope']);
|
||||
$quote_note = sanitizeInput($row['quote_note']);
|
||||
$client_id = intval($row['quote_client_id']);
|
||||
$category_id = intval($row['quote_category_id']);
|
||||
|
||||
//Generate a unique URL key for clients to access
|
||||
@@ -80,7 +80,7 @@ if (isset($_POST['add_quote_copy'])) {
|
||||
}
|
||||
|
||||
//Logging
|
||||
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Quote', log_action = 'Create', log_description = 'Copied Quote', log_ip = '$session_ip', log_user_agent = '$session_user_agent', log_user_id = $session_user_id");
|
||||
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Quote', log_action = 'Create', log_description = 'Copied Quote', log_ip = '$session_ip', log_user_agent = '$session_user_agent', log_client_id = $client_id, log_user_id = $session_user_id");
|
||||
|
||||
$_SESSION['alert_message'] = "Quote copied";
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ $subject = sanitizeInput($_POST['subject']);
|
||||
$priority = sanitizeInput($_POST['priority']);
|
||||
$details = mysqli_real_escape_string($mysqli, $_POST['details']);
|
||||
$frequency = sanitizeInput($_POST['frequency']);
|
||||
$billable = intval($_POST['billable']);
|
||||
|
||||
$asset_id = "0";
|
||||
if (isset($_POST['asset'])) {
|
||||
|
||||
@@ -286,11 +286,12 @@ if (isset($_POST['edit_ticket_settings'])) {
|
||||
$config_ticket_prefix = sanitizeInput($_POST['config_ticket_prefix']);
|
||||
$config_ticket_next_number = intval($_POST['config_ticket_next_number']);
|
||||
$config_ticket_email_parse = intval($_POST['config_ticket_email_parse']);
|
||||
$config_ticket_default_billable = intval($_POST['config_ticket_default_billable']);
|
||||
$config_ticket_autoclose = intval($_POST['config_ticket_autoclose']);
|
||||
$config_ticket_autoclose_hours = intval($_POST['config_ticket_autoclose_hours']);
|
||||
$config_ticket_new_ticket_notification_email = sanitizeInput($_POST['config_ticket_new_ticket_notification_email']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_ticket_prefix = '$config_ticket_prefix', config_ticket_next_number = $config_ticket_next_number, config_ticket_email_parse = $config_ticket_email_parse, config_ticket_autoclose = $config_ticket_autoclose, config_ticket_autoclose_hours = $config_ticket_autoclose_hours, config_ticket_new_ticket_notification_email = '$config_ticket_new_ticket_notification_email' WHERE company_id = 1");
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_ticket_prefix = '$config_ticket_prefix', config_ticket_next_number = $config_ticket_next_number, config_ticket_email_parse = $config_ticket_email_parse, config_ticket_autoclose = $config_ticket_autoclose, config_ticket_autoclose_hours = $config_ticket_autoclose_hours, config_ticket_new_ticket_notification_email = '$config_ticket_new_ticket_notification_email', config_ticket_default_billable = $config_ticket_default_billable WHERE company_id = 1");
|
||||
|
||||
//Logging
|
||||
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Settings', log_action = 'Modify', log_description = '$session_name modified ticket settings', log_ip = '$session_ip', log_user_agent = '$session_user_agent', log_user_id = $session_user_id");
|
||||
@@ -316,8 +317,9 @@ if (isset($_POST['edit_default_settings'])) {
|
||||
$calendar = intval($_POST['calendar']);
|
||||
$net_terms = intval($_POST['net_terms']);
|
||||
$hourly_rate = floatval($_POST['hourly_rate']);
|
||||
$phone_mask = intval($_POST['phone_mask']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_start_page = '$start_page', config_default_expense_account = $expense_account, config_default_payment_account = $payment_account, config_default_payment_method = '$payment_method', config_default_expense_payment_method = '$expense_payment_method', config_default_transfer_from_account = $transfer_from_account, config_default_transfer_to_account = $transfer_to_account, config_default_calendar = $calendar, config_default_net_terms = $net_terms, config_default_hourly_rate = $hourly_rate WHERE company_id = 1");
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_start_page = '$start_page', config_default_expense_account = $expense_account, config_default_payment_account = $payment_account, config_default_payment_method = '$payment_method', config_default_expense_payment_method = '$expense_payment_method', config_default_transfer_from_account = $transfer_from_account, config_default_transfer_to_account = $transfer_to_account, config_default_calendar = $calendar, config_default_net_terms = $net_terms, config_default_hourly_rate = $hourly_rate, config_phone_mask = $phone_mask WHERE company_id = 1");
|
||||
|
||||
//Logging
|
||||
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Settings', log_action = 'Modify', log_description = '$session_name modified default settings', log_ip = '$session_ip', log_user_agent = '$session_user_agent', log_user_id = $session_user_id");
|
||||
|
||||
@@ -188,6 +188,7 @@ if (isset($_POST['edit_ticket'])) {
|
||||
$ticket_id = intval($_POST['ticket_id']);
|
||||
$contact_id = intval($_POST['contact']);
|
||||
$notify = intval($_POST['contact_notify']);
|
||||
$category = intval($_POST['category']);
|
||||
$subject = sanitizeInput($_POST['subject']);
|
||||
$billable = intval($_POST['billable']);
|
||||
$priority = sanitizeInput($_POST['priority']);
|
||||
@@ -200,7 +201,7 @@ if (isset($_POST['edit_ticket'])) {
|
||||
$client_id = intval($_POST['client_id']);
|
||||
$ticket_number = sanitizeInput($_POST['ticket_number']);
|
||||
|
||||
mysqli_query($mysqli, "UPDATE tickets SET ticket_subject = '$subject', ticket_priority = '$priority', ticket_billable = $billable, ticket_details = '$details', ticket_vendor_ticket_number = '$vendor_ticket_number', ticket_contact_id = $contact_id, ticket_vendor_id = $vendor_id, ticket_location_id = $location_id, ticket_asset_id = $asset_id, ticket_project_id = $project_id WHERE ticket_id = $ticket_id");
|
||||
mysqli_query($mysqli, "UPDATE tickets SET ticket_category = $category, ticket_subject = '$subject', ticket_priority = '$priority', ticket_billable = $billable, ticket_details = '$details', ticket_vendor_ticket_number = '$vendor_ticket_number', ticket_contact_id = $contact_id, ticket_vendor_id = $vendor_id, ticket_location_id = $location_id, ticket_asset_id = $asset_id, ticket_project_id = $project_id WHERE ticket_id = $ticket_id");
|
||||
|
||||
// Notify new contact if selected
|
||||
if ($notify && !empty($config_smtp_host)) {
|
||||
@@ -1104,9 +1105,14 @@ if (isset($_POST['add_ticket_reply'])) {
|
||||
|
||||
$client_id = intval($_POST['client_id']);
|
||||
|
||||
if (isset($_POST['public_reply_type'])) {
|
||||
$send_email = 0;
|
||||
|
||||
if ($_POST['public_reply_type'] == 1 ){
|
||||
$ticket_reply_type = 'Public';
|
||||
} else {
|
||||
} elseif ($_POST['public_reply_type'] == 2 ) {
|
||||
$ticket_reply_type = 'Public';
|
||||
$send_email = 1;
|
||||
} else {
|
||||
$ticket_reply_type = 'Internal';
|
||||
}
|
||||
|
||||
@@ -1156,7 +1162,7 @@ if (isset($_POST['add_ticket_reply'])) {
|
||||
$company_phone = sanitizeInput(formatPhoneNumber($row['company_phone']));
|
||||
|
||||
// Send e-mail to client if public update & email is set up
|
||||
if ($ticket_reply_type == 'Public' && !empty($config_smtp_host)) {
|
||||
if ($ticket_reply_type == 'Public' && $send_email == 1 && !empty($config_smtp_host)) {
|
||||
|
||||
if (filter_var($contact_email, FILTER_VALIDATE_EMAIL)) {
|
||||
|
||||
@@ -1596,7 +1602,7 @@ if (isset($_POST['add_recurring_ticket'])) {
|
||||
}
|
||||
|
||||
// Add scheduled ticket
|
||||
mysqli_query($mysqli, "INSERT INTO scheduled_tickets SET scheduled_ticket_subject = '$subject', scheduled_ticket_details = '$details', scheduled_ticket_priority = '$priority', scheduled_ticket_frequency = '$frequency', scheduled_ticket_start_date = '$start_date', scheduled_ticket_next_run = '$start_date', scheduled_ticket_assigned_to = $assigned_to, scheduled_ticket_created_by = $session_user_id, scheduled_ticket_client_id = $client_id, scheduled_ticket_contact_id = $contact_id, scheduled_ticket_asset_id = $asset_id");
|
||||
mysqli_query($mysqli, "INSERT INTO scheduled_tickets SET scheduled_ticket_subject = '$subject', scheduled_ticket_details = '$details', scheduled_ticket_priority = '$priority', scheduled_ticket_frequency = '$frequency', scheduled_ticket_billable = $billable, scheduled_ticket_start_date = '$start_date', scheduled_ticket_next_run = '$start_date', scheduled_ticket_assigned_to = $assigned_to, scheduled_ticket_created_by = $session_user_id, scheduled_ticket_client_id = $client_id, scheduled_ticket_contact_id = $contact_id, scheduled_ticket_asset_id = $asset_id");
|
||||
|
||||
$scheduled_ticket_id = mysqli_insert_id($mysqli);
|
||||
|
||||
@@ -1625,7 +1631,7 @@ if (isset($_POST['edit_recurring_ticket'])) {
|
||||
}
|
||||
|
||||
// Edit scheduled ticket
|
||||
mysqli_query($mysqli, "UPDATE scheduled_tickets SET scheduled_ticket_subject = '$subject', scheduled_ticket_details = '$details', scheduled_ticket_priority = '$priority', scheduled_ticket_frequency = '$frequency', scheduled_ticket_next_run = '$next_run_date', scheduled_ticket_assigned_to = $assigned_to, scheduled_ticket_asset_id = $asset_id, scheduled_ticket_contact_id = $contact_id WHERE scheduled_ticket_id = $scheduled_ticket_id");
|
||||
mysqli_query($mysqli, "UPDATE scheduled_tickets SET scheduled_ticket_subject = '$subject', scheduled_ticket_details = '$details', scheduled_ticket_priority = '$priority', scheduled_ticket_frequency = '$frequency', scheduled_ticket_billable = $billable, scheduled_ticket_next_run = '$next_run_date', scheduled_ticket_assigned_to = $assigned_to, scheduled_ticket_asset_id = $asset_id, scheduled_ticket_contact_id = $contact_id WHERE scheduled_ticket_id = $scheduled_ticket_id");
|
||||
|
||||
// Logging
|
||||
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Recurring Ticket', log_action = 'Modify', log_description = '$session_name modified recurring ticket for $subject - $frequency', log_ip = '$session_ip', log_user_agent = '$session_user_agent', log_client_id = $client_id, log_user_id = $session_user_id, log_entity_id = $scheduled_ticket_id");
|
||||
|
||||
@@ -18,6 +18,14 @@ if (isset($_POST['add_user'])) {
|
||||
|
||||
$user_id = mysqli_insert_id($mysqli);
|
||||
|
||||
// Add Client Access Permissions if set
|
||||
if (!empty($_POST['clients'])) {
|
||||
foreach($_POST['clients'] as $client_id) {
|
||||
$client_id = intval($client_id);
|
||||
mysqli_query($mysqli,"INSERT INTO user_permissions SET user_id = $user_id, client_id = $client_id");
|
||||
}
|
||||
}
|
||||
|
||||
if (!file_exists("uploads/users/$user_id/")) {
|
||||
mkdir("uploads/users/$user_id");
|
||||
}
|
||||
@@ -105,6 +113,15 @@ if (isset($_POST['edit_user'])) {
|
||||
$user_id = intval($_POST['user_id']);
|
||||
$new_password = trim($_POST['new_password']);
|
||||
|
||||
// Update Client Access
|
||||
mysqli_query($mysqli,"DELETE FROM user_permissions WHERE user_id = $user_id");
|
||||
if (!empty($_POST['clients'])) {
|
||||
foreach($_POST['clients'] as $client_id) {
|
||||
$client_id = intval($client_id);
|
||||
mysqli_query($mysqli,"INSERT INTO user_permissions SET user_id = $user_id, client_id = $client_id");
|
||||
}
|
||||
}
|
||||
|
||||
// Get current Avatar
|
||||
$sql = mysqli_query($mysqli, "SELECT user_avatar FROM users WHERE user_id = $user_id");
|
||||
$row = mysqli_fetch_array($sql);
|
||||
|
||||
@@ -11,6 +11,28 @@
|
||||
<input type="hidden" name="quote_id" value="<?php echo $quote_id; ?>">
|
||||
<div class="modal-body bg-white">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Client <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-users"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="client" required>
|
||||
<?php
|
||||
|
||||
$sql_client_select = mysqli_query($mysqli, "SELECT * FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_client_select)) {
|
||||
$client_id_select = intval($row['client_id']);
|
||||
$client_name_select = nullable_htmlentities($row['client_name']);
|
||||
|
||||
?>
|
||||
<option <?php if ($client_id == $client_id_select) { echo "selected"; } ?> value="<?php echo $client_id_select; ?>"><?php echo $client_name_select; ?></option>
|
||||
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Set Date for New Quote <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<?php if (isset($client_id)) { ?>
|
||||
<input type="hidden" name="client" value="<?php echo $client_id; ?>>">
|
||||
<?php } ?>
|
||||
<input type="hidden" name="billable" value="0">
|
||||
|
||||
<div class="modal-body bg-white">
|
||||
|
||||
@@ -86,6 +87,15 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($config_module_enable_accounting) { ?>
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" name="billable" <?php if ($config_ticket_default_billable == 1) { echo "checked"; } ?> value="1" id="billable">
|
||||
<label class="custom-control-label" for="billable">Mark Billable</label>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="scheduled_ticket_id" id="editTicketId">
|
||||
<input type="hidden" name="client" id="editClientId">
|
||||
<input type="hidden" name="billable" value="0">
|
||||
|
||||
<div class="modal-body bg-white">
|
||||
|
||||
@@ -73,6 +74,15 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($config_module_enable_accounting) { ?>
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" name="billable" id="editTicketBillable" value="1">
|
||||
<label class="custom-control-label" for="editTicketBillable">Mark Billable</label>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-edit-contacts">
|
||||
|
||||
@@ -50,7 +50,7 @@ if (isset($_GET['year'])) {
|
||||
|
||||
$sql_ticket_years = mysqli_query($mysqli, "SELECT DISTINCT YEAR(ticket_created_at) AS ticket_year FROM tickets ORDER BY ticket_year DESC");
|
||||
|
||||
$sql_clients = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients ORDER BY client_name ASC");
|
||||
$sql_clients = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC");
|
||||
|
||||
?>
|
||||
|
||||
@@ -79,6 +79,7 @@ $sql_clients = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients
|
||||
<th>Client</th>
|
||||
<th class="text-right">Tickets raised</th>
|
||||
<th class="text-right">Tickets closed</th>
|
||||
<th class="text-right">Time worked <i>(H:M:S)</i></th>
|
||||
<th class="text-right">Avg time to close</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -101,6 +102,11 @@ $sql_clients = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients
|
||||
// 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_closed_at IS NOT NULL");
|
||||
|
||||
// Calculate total time tracked towards tickets in the period
|
||||
$sql_time = mysqli_query($mysqli, "SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(ticket_reply_time_worked))) as total_time FROM ticket_replies LEFT JOIN tickets ON tickets.ticket_id = ticket_replies.ticket_reply_ticket_id WHERE YEAR(ticket_created_at) = $year AND ticket_client_id = $client_id AND ticket_reply_time_worked IS NOT NULL");
|
||||
$row = mysqli_fetch_array($sql_time);
|
||||
$ticket_total_time_worked = nullable_htmlentities($row['total_time']);
|
||||
|
||||
if ($ticket_raised_count > 0) {
|
||||
|
||||
// Calculate average time to solve
|
||||
@@ -120,6 +126,7 @@ $sql_clients = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients
|
||||
<td><?php echo $client_name; ?></td>
|
||||
<td class="text-right"><?php echo $ticket_raised_count; ?></td>
|
||||
<td class="text-right"><?php echo $ticket_closed_count; ?></td>
|
||||
<td class="text-right"><?php echo $ticket_total_time_worked; ?></td>
|
||||
<td class="text-right"><?php echo secondsToTime($total); ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
|
||||
@@ -58,14 +58,6 @@ class TokenAuth6238 {
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function getBarCodeUrl($username, $domain, $secretkey, $issuer) {
|
||||
$url = "https://chart.apis.google.com/chart";
|
||||
$url = $url."?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/";
|
||||
$url = $url.$username . "@" . $domain . "%3Fsecret%3D" . $secretkey . '%26issuer%3D' . rawurlencode($issuer);
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
private static function oath_hotp ($key, $counter, $debug=false) {
|
||||
$result = "";
|
||||
$orgcounter = $counter;
|
||||
|
||||
@@ -218,6 +218,28 @@ require_once "inc_all_admin.php";
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Phone Mask</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-phone"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="phone_mask">
|
||||
<?php
|
||||
$sql = mysqli_query($mysqli, "SELECT config_phone_mask FROM settings WHERE company_id = 1");
|
||||
while ($row = mysqli_fetch_array($sql)) {
|
||||
$phone_mask = intval($row['config_phone_mask']);
|
||||
} ?>
|
||||
<option <?php if ($phone_mask == 1) {
|
||||
echo "selected";
|
||||
}?> value=1>Enable</option>
|
||||
<option <?php if ($phone_mask == 0) {
|
||||
echo "selected";
|
||||
}?> value=0>Disabled</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<button type="submit" name="edit_default_settings" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button>
|
||||
@@ -228,4 +250,3 @@ require_once "inc_all_admin.php";
|
||||
|
||||
<?php
|
||||
require_once "footer.php";
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ require_once "inc_all_admin.php";
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<input type="hidden" name="config_ticket_email_parse" value="0">
|
||||
<input type="hidden" name="config_ticket_autoclose" value="0">
|
||||
<input type="hidden" name="config_ticket_default_billable" value="0">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Ticket Prefix</label>
|
||||
@@ -39,6 +40,15 @@ require_once "inc_all_admin.php";
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($config_module_enable_accounting) { ?>
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" name="config_ticket_default_billable" <?php if ($config_ticket_default_billable == 1) { echo "checked"; } ?> value="1" id="ticketBillableSwitch<?php echo $ticket_id; ?>">
|
||||
<label class="custom-control-label" for="ticketBillableSwitch<?php echo $ticket_id; ?>">Default to Billable <small class="text-secondary">(This will check the billable box on all new tickets)</small></label>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" name="config_ticket_autoclose" <?php if($config_ticket_autoclose == 1){ echo "checked"; } ?> value="1" id="ticketAutoCloseSwitch">
|
||||
|
||||
@@ -302,6 +302,11 @@ if (isset($_POST['add_company_settings'])) {
|
||||
mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'Auto Close', ticket_status_color = '#343a40'"); // 4
|
||||
mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'Closed', ticket_status_color = '#343a40'"); // 5
|
||||
|
||||
// Add default roles
|
||||
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)'");
|
||||
|
||||
|
||||
$_SESSION['alert_message'] = "Company <strong>$name</strong> created!";
|
||||
|
||||
@@ -843,8 +848,9 @@ if (isset($_POST['add_telemetry'])) {
|
||||
<ul>
|
||||
<li>Please take a look over the install <a href="https://docs.itflow.org/installation">docs</a>, if you haven't already</li>
|
||||
<li>Don't hesitate to reach out on the <a href="https://forum.itflow.org/t/support" target="_blank">forums</a> if you need any assistance</li>
|
||||
<li><i>Your PHP Error log is at: <?php echo ini_get('error_log') ?></i></li>
|
||||
</ul>
|
||||
<br><p>A database must be created before proceeding - click on the button below to get started</p>
|
||||
<br><p>A database must be created before proceeding - click on the button below to get started.</p>
|
||||
<br><hr>
|
||||
<p class="text-muted">ITFlow is <b>free software</b>: you can redistribute and/or modify it under the terms of the <a href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank">GNU General Public License</a>. <br> It is distributed in the hope that it will be useful, but <b>without any warranty</b>; without even the implied warranty of merchantability or fitness for a particular purpose.</p>
|
||||
<?php
|
||||
|
||||
@@ -20,7 +20,12 @@
|
||||
<li class="nav-item">
|
||||
<a href="clients.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "clients.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-user-friends"></i>
|
||||
<p>Clients</p>
|
||||
<p>
|
||||
Clients
|
||||
<?php if ($num_active_clients) { ?>
|
||||
<span class="right badge text-light"><?php echo $num_active_clients; ?></span>
|
||||
<?php } ?>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<?php if ($session_user_role >= 2 && $config_module_enable_ticketing == 1) { ?>
|
||||
|
||||
221
ticket.php
221
ticket.php
@@ -1,13 +1,6 @@
|
||||
<?php
|
||||
require_once "inc_all.php";
|
||||
|
||||
?>
|
||||
|
||||
<!-- Custom styling of time tracking elements -->
|
||||
<link rel="stylesheet" type="text/css" href="css/ticket_time_tracking.css">
|
||||
|
||||
<?php
|
||||
|
||||
// Initialize the HTML Purifier to prevent XSS
|
||||
require "plugins/htmlpurifier/HTMLPurifier.standalone.php";
|
||||
|
||||
@@ -30,6 +23,7 @@ if (isset($_GET['ticket_id'])) {
|
||||
LEFT JOIN projects ON ticket_project_id = project_id
|
||||
LEFT JOIN invoices ON ticket_invoice_id = invoice_id
|
||||
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
|
||||
LEFT JOIN categories ON ticket_category = category_id
|
||||
WHERE ticket_id = $ticket_id LIMIT 1"
|
||||
);
|
||||
|
||||
@@ -54,7 +48,8 @@ if (isset($_GET['ticket_id'])) {
|
||||
|
||||
$ticket_prefix = nullable_htmlentities($row['ticket_prefix']);
|
||||
$ticket_number = intval($row['ticket_number']);
|
||||
$ticket_category = nullable_htmlentities($row['ticket_category']);
|
||||
$ticket_category = intval($row['ticket_category']);
|
||||
$ticket_category_display = htmlentities($row['category_name']);
|
||||
$ticket_subject = nullable_htmlentities($row['ticket_subject']);
|
||||
$ticket_details = $purifier->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'])) {
|
||||
</div>
|
||||
<?php }
|
||||
|
||||
// Time tracking
|
||||
if ($ticket_total_reply_time) { ?>
|
||||
<div class="mt-1">
|
||||
<i class="far fa-fw fa-clock text-secondary mr-2"></i>Total time worked: <?php echo $ticket_total_reply_time; ?>
|
||||
</div>
|
||||
<?php }
|
||||
|
||||
// Billable
|
||||
if ($config_module_enable_accounting) { ?>
|
||||
<?php if($invoice_id) { ?>
|
||||
@@ -404,18 +408,33 @@ if (isset($_GET['ticket_id'])) {
|
||||
</div>
|
||||
|
||||
<div class="col-sm-3">
|
||||
<?php if($task_count) { ?>
|
||||
<?php if ($task_count) { ?>
|
||||
Tasks Completed<span class="float-right text-bold"><?php echo $tasks_completed_percent; ?>%</span>
|
||||
<div class="progress mt-2" style="height: 20px;">
|
||||
<div class="progress-bar" style="width: <?php echo $tasks_completed_percent; ?>%;"><?php echo $completed_task_count; ?> / <?php echo $task_count; ?></div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<?php if($ticket_collaborators) { ?>
|
||||
<?php
|
||||
// Time tracking
|
||||
if ($ticket_total_reply_time) { ?>
|
||||
<div class="mt-1">
|
||||
<i class="far fa-fw fa-clock text-secondary mr-2"></i>Total time worked: <?php echo $ticket_total_reply_time; ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<?php if ($ticket_collaborators) { ?>
|
||||
<div class="mt-2">
|
||||
<i class="fas fa-fw fa-users mr-2 text-secondary"></i><?php echo $ticket_collaborators; ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<?php if ($ticket_category > 0) { ?>
|
||||
<div class="mt-2">
|
||||
<i class="fas fa-fw fa-layer-group mr-2 text-secondary"></i><?php echo $ticket_category_display; ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-sm-3">
|
||||
@@ -451,7 +470,7 @@ if (isset($_GET['ticket_id'])) {
|
||||
<?php }
|
||||
|
||||
if (empty($ticket_closed_at)) { ?>
|
||||
<?php if($task_count == $completed_task_count) { ?>
|
||||
<?php if ($task_count == $completed_task_count) { ?>
|
||||
<a href="post.php?close_ticket=<?php echo $ticket_id; ?>" class="btn btn-dark btn-sm confirm-link" id="ticket_close">
|
||||
<i class="fas fa-fw fa-gavel mr-2"></i>Close
|
||||
</a>
|
||||
@@ -513,28 +532,39 @@ if (isset($_GET['ticket_id'])) {
|
||||
|
||||
<!-- Only show ticket reply modal if status is not closed -->
|
||||
<?php if (empty($ticket_closed_at)) { ?>
|
||||
|
||||
<form class="mb-3 d-print-none" action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="ticket_id" id="ticket_id" value="<?php echo $ticket_id; ?>">
|
||||
<input type="hidden" name="client_id" id="client_id" value="<?php echo $client_id; ?>">
|
||||
|
||||
<div class="form-group">
|
||||
<div class="btn-group btn-group-toggle" data-toggle="buttons">
|
||||
<label class="btn btn-light active">
|
||||
<input type="radio" name="public_reply_type" value="2" checked>Public Comment & Email
|
||||
</label>
|
||||
<label class="btn btn-light">
|
||||
<input type="radio" name="public_reply_type" value="1">Public Comment
|
||||
</label>
|
||||
<label class="btn btn-light">
|
||||
<input type="radio" name="public_reply_type" value="0">Internal Note
|
||||
</label>
|
||||
</div>
|
||||
<?php if ($config_ai_enable) { ?>
|
||||
<div class="form-group">
|
||||
<textarea class="form-control tinymceai" id="textInput" name="ticket_reply" placeholder="Type a response"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<button id="rewordButton" class="btn btn-secondary" type="button"><i class="fas fa-fw fa-robot mr-2"></i>AI Reword</button>
|
||||
<button id="undoButton" class="btn btn-secondary" type="button" style="display:none;"><i class="fas fa-fw fa-redo-alt mr-2"></i>Undo</button>
|
||||
</div>
|
||||
<?php } else { ?>
|
||||
<div class="form-group">
|
||||
<textarea class="form-control tinymce" name="ticket_reply" placeholder="Type a response"></textarea>
|
||||
</div>
|
||||
<div class="float-right">
|
||||
<button id="rewordButton" class="btn btn-secondary" type="button"><i class="fas fa-fw fa-robot mr-2"></i>AI Reword</button>
|
||||
<button id="undoButton" class="btn btn-secondary" type="button" style="display:none;"><i class="fas fa-fw fa-redo-alt mr-2"></i>Undo</button>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<textarea class="form-control tinymce<?php if ($config_ai_enable) { echo "ai"; } ?>" id="textInput" name="ticket_reply" placeholder="Type a response"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="col-md-2">
|
||||
<div class="col-md-4">
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-thermometer-half"></i></span>
|
||||
@@ -554,69 +584,32 @@ if (isset($_GET['ticket_id'])) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="custom-tt-horizontal-spacing"></div> <!-- Add custom class for smaller spacing -->
|
||||
|
||||
<!-- Time Tracking -->
|
||||
<div class="col-sm-3 col-lg-2">
|
||||
<div class="col-md-6">
|
||||
<div class="input-group mb-3">
|
||||
<div class="form-row">
|
||||
|
||||
<div class="input-group custom-tt-width">
|
||||
<input type="text" class="form-control" inputmode="numeric" id="hours" name="hours" placeholder="Hrs" min="0" max="23" pattern="0?[0-9]|1[0-9]|2[0-3]">
|
||||
</div>
|
||||
|
||||
<div class="input-group custom-tt-width">
|
||||
<input type="text" class="form-control" inputmode="numeric" id="minutes" name="minutes" placeholder="Mins" min="0" max="59" pattern="[0-5]?[0-9]">
|
||||
</div>
|
||||
|
||||
<div class="input-group custom-tt-width">
|
||||
<input type="text" class="form-control" inputmode="numeric" id="seconds" name="seconds" placeholder="Secs" min="0" max="59" pattern="[0-5]?[0-9]">
|
||||
</div>
|
||||
|
||||
<div class="input-group pr-0 col-2">
|
||||
<input type="text" class="form-control" inputmode="numeric" id="hours" name="hours" placeholder="Hrs" min="0" max="23" pattern="0?[0-9]|1[0-9]|2[0-3]">
|
||||
</div>
|
||||
|
||||
<div class="input-group px-0 col-2">
|
||||
<input type="text" class="form-control" inputmode="numeric" id="minutes" name="minutes" placeholder="Mins" min="0" max="59" pattern="[0-5]?[0-9]">
|
||||
</div>
|
||||
|
||||
<div class="input-group px-0 col-2">
|
||||
<input type="text" class="form-control" inputmode="numeric" id="seconds" name="seconds" placeholder="Secs" min="0" max="59" pattern="[0-5]?[0-9]">
|
||||
</div>
|
||||
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-success" id="startStopTimer"><i class="fas fa-fw fa-pause"></i></button>
|
||||
<button type="button" class="btn btn-danger" id="resetTimer"><i class="fas fa-fw fa-redo-alt"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Timer Controls -->
|
||||
<div class="col-sm-2">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-success" id="startStopTimer"><i class="fas fa-fw fa-pause"></i></button>
|
||||
<button type="button" class="btn btn-danger" id="resetTimer"><i class="fas fa-fw fa-redo-alt"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<?php
|
||||
// Set the initial ticket response type (private/internal note)
|
||||
// Future updates of the wording/icon are done by Javascript
|
||||
|
||||
// Public responses by default (maybe configurable in future?)
|
||||
$ticket_reply_button_wording = "Respond";
|
||||
$ticket_reply_button_check = "checked";
|
||||
$ticket_reply_button_icon = "paper-plane";
|
||||
|
||||
// Internal responses by default if 1) the contact email is empty or 2) the contact email matches the agent responding
|
||||
if (empty($contact_email) || $contact_email == $session_email) {
|
||||
// Internal
|
||||
$ticket_reply_button_wording = "Add note";
|
||||
$ticket_reply_button_check = "";
|
||||
$ticket_reply_button_icon = "sticky-note";
|
||||
} ?>
|
||||
|
||||
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="ticket_reply_type_checkbox" name="public_reply_type" value="1" <?php echo $ticket_reply_button_check ?>>
|
||||
<label class="custom-control-label" for="ticket_reply_type_checkbox">Public Update<br><small class="text-secondary">(Emails contact)</small></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-2">
|
||||
<button type="submit" id="ticket_add_reply" name="add_ticket_reply" class="btn btn-primary text-bold"><i class="fas fa-<?php echo $ticket_reply_button_icon ?> mr-2"></i><?php echo $ticket_reply_button_wording ?></button>
|
||||
<div class="float-right">
|
||||
<button type="submit" id="ticket_add_reply" name="add_ticket_reply" class="btn btn-primary btn-block text-bold"><i class="fas fa-check mr-2"></i>Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -625,7 +618,52 @@ if (isset($_GET['ticket_id'])) {
|
||||
<!-- End IF for reply modal -->
|
||||
<?php } ?>
|
||||
|
||||
<?php if($ticket_responses) { ?><h5 class="mb-4">Responses (<?php echo $ticket_responses; ?>)</h5><?php } ?>
|
||||
<!-- Ticket Responses -->
|
||||
<ul class="nav nav-tabs" id="ticketComments">
|
||||
<li class="nav-item">
|
||||
<button class="nav-link active" id="all-comments-tab" data-toggle="tab" data-target="#allComments" type="button">
|
||||
All Comments
|
||||
<span class="right badge badge-pill badge-dark ml-2"><?php echo $ticket_all_comments_count; ?></span>
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<button class="nav-link" id="public-comments-tab" data-toggle="tab" data-target="#publicComments" type="button">
|
||||
Public
|
||||
<span class="right badge badge-pill badge-dark ml-2"><?php echo $ticket_public_comments_count; ?></span>
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<button class="nav-link" id="notes-tab" data-toggle="tab" data-target="#notes" type="button">
|
||||
Internal Notes
|
||||
<span class="right badge badge-pill badge-dark ml-2"><?php echo $ticket_internal_notes_count; ?></span>
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<button class="nav-link" id="public-comments-tab" data-toggle="tab" data-target="#publicComments" type="button">
|
||||
Client Communication
|
||||
<span class="right badge badge-pill badge-dark ml-2"><?php echo $ticket_public_comments_count; ?></span>
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item ml-auto">
|
||||
<button class="nav-link" id="events-tab" data-toggle="tab" data-target="#events" type="button">
|
||||
Events
|
||||
<span class="right badge badge-pill badge-dark ml-2"><?php echo $ticket_responses; ?></span>
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<button class="nav-link" id="tasks-tab" data-toggle="tab" data-target="#tasks" type="button">
|
||||
Tasks
|
||||
<span class="right badge badge-pill badge-dark ml-2"><?php echo $task_count; ?></span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content" id="myTabContent">
|
||||
<div class="tab-pane fade show active" id="allComments">All Comments</div>
|
||||
<div class="tab-pane fade" id="publicComments">Public Comments</div>
|
||||
<div class="tab-pane fade" id="notes">Internal Notes</div>
|
||||
<div class="tab-pane fade" id="events">Events</div>
|
||||
<div class="tab-pane fade" id="tasks">Tasks</div>
|
||||
</div>
|
||||
|
||||
<!-- Ticket replies -->
|
||||
<?php
|
||||
@@ -837,7 +875,7 @@ if (isset($_GET['ticket_id'])) {
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<?php if($task_completed_at) { ?>
|
||||
<?php if ($task_completed_at) { ?>
|
||||
<i class="far fa-fw fa-check-square text-primary"></i>
|
||||
<?php } else { ?>
|
||||
<a href="post.php?complete_task=<?php echo $task_id; ?>">
|
||||
@@ -1099,7 +1137,6 @@ require_once "footer.php";
|
||||
|
||||
<!-- Ticket collision detect JS (jQuery is called in footer, so collision detection script MUST be below it) -->
|
||||
<script src="js/ticket_collision_detection.js"></script>
|
||||
<script src="js/ticket_button_respond_note.js"></script>
|
||||
<?php } ?>
|
||||
|
||||
<script src="js/pretty_content.js"></script>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="billable" value="0">
|
||||
<div class="modal-body bg-white">
|
||||
|
||||
<?php if (isset($_GET['client_id'])) { ?>
|
||||
@@ -139,6 +140,15 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($config_module_enable_accounting) { ?>
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" name="billable" <?php if ($config_ticket_default_billable == 1) { echo "checked"; } ?> value="1" id="billableSwitch">
|
||||
<label class="custom-control-label" for="billableSwitch">Mark Billable</label>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
</div>
|
||||
|
||||
<?php if (isset($_GET['client_id'])) { ?>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
|
||||
<input type="hidden" name="ticket_number" value="<?php echo "$ticket_prefix$ticket_number"; ?>">
|
||||
<input type="hidden" name="contact_notify" value="0"> <!-- Default 0 -->
|
||||
<input type="hidden" name="billable" value="0">
|
||||
<div class="modal-body bg-white">
|
||||
|
||||
<ul class="nav nav-pills nav-justified mb-3">
|
||||
@@ -55,37 +56,57 @@
|
||||
<textarea class="form-control tinymce" rows="8" name="details"><?php echo $ticket_details; ?></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Priority <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-thermometer-half"></i></span>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="form-group">
|
||||
<label>Priority <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-thermometer-half"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="priority" required>
|
||||
<option <?php if ($ticket_priority == 'Low') { echo "selected"; } ?> >Low</option>
|
||||
<option <?php if ($ticket_priority == 'Medium') { echo "selected"; } ?> >Medium</option>
|
||||
<option <?php if ($ticket_priority == 'High') { echo "selected"; } ?> >High</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<div class="form-group">
|
||||
<label>Category</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-layer-group"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="category">
|
||||
<option value="">- Ticket Category -</option>
|
||||
<?php
|
||||
$sql_categories = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Ticket' AND categories.category_archived_at IS NULL");
|
||||
while ($row = mysqli_fetch_array($sql_categories)) {
|
||||
$category_id = intval($row['category_id']);
|
||||
$category_name = nullable_htmlentities($row['category_name']);
|
||||
|
||||
?>
|
||||
<option <?php if ($ticket_category == $category_id) {echo "selected";} ?> value="<?php echo $category_id; ?>"><?php echo $category_name; ?></option>
|
||||
<?php } ?>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<select class="form-control select2" name="priority" required>
|
||||
<option <?php if ($ticket_priority == 'Low') { echo "selected"; } ?> >Low</option>
|
||||
<option <?php if ($ticket_priority == 'Medium') { echo "selected"; } ?> >Medium</option>
|
||||
<option <?php if ($ticket_priority == 'High') { echo "selected"; } ?> >High</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($config_module_enable_accounting) {
|
||||
?>
|
||||
<?php if ($config_module_enable_accounting) { ?>
|
||||
<div class="form-group">
|
||||
<label>Billable</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-money-bill"></i></span>
|
||||
</div>
|
||||
<select class="form-control" name="billable">
|
||||
<option <?php if ($ticket_billable == 1) { echo "selected"; } ?> value="1">Yes</option>
|
||||
<option <?php if ($ticket_billable == 0) { echo "selected"; } ?> value="0">No</option>
|
||||
</select>
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" name="billable" <?php if ($ticket_billable == 1) { echo "checked"; } ?> value="1" id="billableSwitch<?php echo $ticket_id; ?>">
|
||||
<label class="custom-control-label" for="billableSwitch<?php echo $ticket_id; ?>">Mark Billable</label>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-contacts<?php echo $ticket_id; ?>">
|
||||
|
||||
25
tickets.php
25
tickets.php
@@ -284,7 +284,7 @@ $user_active_assigned_tickets = intval($row['total_tickets_assigned']);
|
||||
</td>
|
||||
<th><a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=ticket_number&order=<?php echo $disp; ?>">Number</a>
|
||||
</th>
|
||||
<th><a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=ticket_subject&order=<?php echo $disp; ?>">Subject</a>
|
||||
<th><a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=ticket_subject&order=<?php echo $disp; ?>">Subject / Tasks</a>
|
||||
</th>
|
||||
<th><a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=client_name&order=<?php echo $disp; ?>">Client / Contact</a>
|
||||
</th>
|
||||
@@ -395,6 +395,23 @@ $user_active_assigned_tickets = intval($row['total_tickets_assigned']);
|
||||
$ticket_reply_created_at_time_ago = timeAgo($ticket_reply_created_at);
|
||||
}
|
||||
|
||||
|
||||
// Get Tasks
|
||||
$sql_tasks = mysqli_query( $mysqli, "SELECT * FROM tasks WHERE task_ticket_id = $ticket_id ORDER BY task_created_at ASC");
|
||||
$task_count = mysqli_num_rows($sql_tasks);
|
||||
// Get Completed Task Count
|
||||
$sql_tasks_completed = mysqli_query($mysqli,
|
||||
"SELECT * FROM tasks
|
||||
WHERE task_ticket_id = $ticket_id
|
||||
AND task_completed_at IS NOT NULL"
|
||||
);
|
||||
$completed_task_count = mysqli_num_rows($sql_tasks_completed);
|
||||
|
||||
// Tasks Completed Percent
|
||||
if($task_count) {
|
||||
$tasks_completed_percent = round(($completed_task_count / $task_count) * 100);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<tr class="<?php if(empty($ticket_closed_at) && empty($ticket_updated_at)) { echo "text-bold"; }?> <?php if (empty($ticket_closed_at) && $ticket_reply_type == "Client") { echo "table-warning"; } ?>">
|
||||
@@ -418,6 +435,12 @@ $user_active_assigned_tickets = intval($row['total_tickets_assigned']);
|
||||
<!-- Ticket Subject -->
|
||||
<td>
|
||||
<a href="ticket.php?ticket_id=<?php echo $ticket_id; ?>"><?php echo $ticket_subject; ?></a>
|
||||
|
||||
<?php if($task_count) { ?>
|
||||
<div class="progress mt-2" style="height: 20px;">
|
||||
<div class="progress-bar" style="width: <?php echo $tasks_completed_percent; ?>%;"><?php echo $completed_task_count; ?> / <?php echo $task_count; ?></div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</td>
|
||||
|
||||
<!-- Ticket Contact -->
|
||||
|
||||
20
top_nav.php
20
top_nav.php
@@ -29,18 +29,6 @@
|
||||
<!-- Right navbar links -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<?php if ($config_module_enable_ticketing == 1) { ?>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#" data-toggle="modal" data-target="#openTicketsModal">
|
||||
<i class="fas fa-hourglass-half"></i>
|
||||
<span class="badge" id="runningTicketsCount">0</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
|
||||
<!-- New Notifications Dropdown -->
|
||||
<?php
|
||||
$sql_notifications = mysqli_query($mysqli, "SELECT * FROM notifications
|
||||
@@ -84,7 +72,7 @@
|
||||
<small class="text-secondary"><?php echo $notification; ?></small>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
<?php } ?>
|
||||
|
||||
<div class="dropdown-divider"></div>
|
||||
@@ -114,7 +102,7 @@
|
||||
<?php } ?>
|
||||
<!-- End New Notifications Dropdown -->
|
||||
|
||||
|
||||
|
||||
<li class="nav-item dropdown user-menu">
|
||||
<a href="#" class="nav-link" data-toggle="dropdown">
|
||||
<?php if (empty($session_avatar)) { ?>
|
||||
@@ -151,7 +139,7 @@
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<?php if ($config_module_enable_ticketing == 1) {
|
||||
<?php if ($config_module_enable_ticketing == 1) {
|
||||
include_once "top_nav_tickets_modal.php";
|
||||
} ?>
|
||||
<!-- /.navbar -->
|
||||
<!-- /.navbar -->
|
||||
|
||||
@@ -1,30 +1,46 @@
|
||||
<?php
|
||||
require_once "inc_all_user.php";
|
||||
|
||||
$row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT user_config_calendar_first_day FROM user_settings WHERE user_id = $session_user_id"));
|
||||
$user_config_calendar_first_day = intval($row['user_config_calendar_first_day']);
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-3">
|
||||
<h3 class="card-title"><i class="fas fa-fw fa-globe mr-2"></i>Browser Extension</h3>
|
||||
<h3 class="card-title"><i class="fas fa-fw fa-globe mr-2"></i>Preferences</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Calendar starts on<strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-calendar-day"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="calendar_first_day" required>
|
||||
<option <?php if ($user_config_calendar_first_day == '0') { echo "selected"; } ?> value="0" >Sunday</option>
|
||||
<option <?php if ($user_config_calendar_first_day == '1') { echo "selected"; } ?> value="1" >Monday</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($session_user_role > 1) { ?>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" name="extension" id="extension" value="Yes" <?php if (isset($_COOKIE['user_extension_key'])) {echo "checked";} ?>>
|
||||
<input disabled="disabled" type="checkbox" class="form-check-input" name="extension" id="extension" value="Yes" <?php if (isset($_COOKIE['user_extension_key'])) {echo "checked";} ?>>
|
||||
<label class="form-check-label" for="extension">Enable Browser Extention?</label>
|
||||
<p class="small">Note: You must log out and back in again for these changes take effect.</p>
|
||||
<p class="small">Not currently in use / Note: You must log out and back in again for these changes take effect.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
<button type="submit" name="edit_your_user_browser_extension" class="btn btn-primary btn-block mt-3"><i class="fas fa-check mr-2"></i>Save</button>
|
||||
<button type="submit" name="edit_your_user_preferences" class="btn btn-primary btn-block mt-3"><i class="fas fa-check mr-2"></i>Save</button>
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
@@ -59,10 +59,12 @@ $remember_token_count = mysqli_num_rows($sql_remember_tokens);
|
||||
|
||||
if (!empty($session_token)) {
|
||||
|
||||
//Generate QR Code based off the generated key
|
||||
print sprintf('<img src="%s"/>', TokenAuth6238::getBarCodeUrl($session_name, ' ', $session_token, $_SERVER['SERVER_NAME']));
|
||||
// Generate QR Code
|
||||
$data = "otpauth://totp/ITFlow:$session_email?secret=$session_token";
|
||||
print "<img src='plugins/barcode/barcode.php?f=png&s=qr&d=$data'>";
|
||||
|
||||
echo "<p class='text-secondary'>$session_token</p>";
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
Reference in New Issue
Block a user