rename /user/ to /agent/ and update links to use agent/ instead

This commit is contained in:
johnnyq
2025-09-23 18:04:23 -04:00
parent 6b6c70f1df
commit edabc5c33f
373 changed files with 93 additions and 21 deletions

128
agent/accounts.php Normal file
View File

@@ -0,0 +1,128 @@
<?php
// Default Column Sortby Filter
$sort = "account_name";
$order = "ASC";
require_once "includes/inc_all.php";
// Perms
enforceUserPermission('module_financial');
$sql = mysqli_query(
$mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM accounts
WHERE (account_name LIKE '%$q%')
AND account_archived_at IS NULL
ORDER BY $sort $order LIMIT $record_from, $record_to"
);
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?>
<div class="card card-dark">
<div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fa fa-fw fa-piggy-bank mr-2"></i>Accounts</h3>
<div class="card-tools">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addAccountModal"><i class="fas fa-plus mr-2"></i>New Account</button>
</div>
</div>
<div class="card-body">
<form autocomplete="off">
<div class="input-group">
<input type="search" class="form-control col-md-4" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search Accounts">
<div class="input-group-append">
<button class="btn btn-primary"><i class="fa fa-search"></i></button>
</div>
</div>
</form>
<hr>
<div class="table-responsive-sm">
<table class="table table-striped table-borderless table-hover">
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
<tr>
<th>
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=account_name&order=<?php echo $disp; ?>">
Name <?php if ($sort == 'account_name') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=account_currency_code&order=<?php echo $disp; ?>">
Currency <?php if ($sort == 'account_currency_code') { echo $order_icon; } ?>
</a>
</th>
<th class="text-right">Balance</th>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql)) {
$account_id = intval($row['account_id']);
$account_name = nullable_htmlentities($row['account_name']);
$opening_balance = floatval($row['opening_balance']);
$account_currency_code = nullable_htmlentities($row['account_currency_code']);
$account_notes = nullable_htmlentities($row['account_notes']);
$sql_payments = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS total_payments FROM payments WHERE payment_account_id = $account_id");
$row = mysqli_fetch_array($sql_payments);
$total_payments = floatval($row['total_payments']);
$sql_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS total_revenues FROM revenues WHERE revenue_account_id = $account_id");
$row = mysqli_fetch_array($sql_revenues);
$total_revenues = floatval($row['total_revenues']);
$sql_expenses = mysqli_query($mysqli, "SELECT SUM(expense_amount) AS total_expenses FROM expenses WHERE expense_account_id = $account_id");
$row = mysqli_fetch_array($sql_expenses);
$total_expenses = floatval($row['total_expenses']);
$balance = $opening_balance + $total_payments + $total_revenues - $total_expenses;
?>
<tr>
<td>
<a class="text-dark ajax-modal" href="#"
data-modal-url="modals/account/account_edit.php?id=<?= $account_id ?>">
<?php echo $account_name; ?>
</a>
</td>
<td><?php echo $account_currency_code; ?></td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $balance, $account_currency_code); ?></td>
<td>
<div class="dropdown dropleft text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i>
</button>
<div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/account/account_edit.php?id=<?= $account_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit
</a>
<?php if ($balance == 0 && $account_id != $config_stripe_account) { //Cannot Archive an Account until it reaches 0 Balance and cant be selected as an online account ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger" href="post.php?archive_account=<?php echo $account_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</a>
<?php } ?>
</div>
</div>
</td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
<?php require_once "../includes/filter_footer.php"; ?>
</div>
</div>
<?php
require_once "modals/account/account_add.php";
require_once "../includes/footer.php";

677
agent/ajax.php Normal file
View File

@@ -0,0 +1,677 @@
<?php
/*
* ajax.php
* Similar to post.php, but for requests using Asynchronous JavaScript
* Always returns data in JSON format, unless otherwise specified
*/
require_once "../config.php";
require_once "../functions.php";
require_once "../includes/check_login.php";
require_once "../plugins/totp/totp.php";
/*
* Fetches SSL certificates from remote hosts & returns the relevant info (issuer, expiry, public key)
*/
if (isset($_GET['certificate_fetch_parse_json_details'])) {
enforceUserPermission('module_support');
// PHP doesn't appreciate attempting SSL sockets to non-existent domains
if (empty($_GET['domain'])) {
exit();
}
$name = $_GET['domain'];
// Get SSL cert for domain (if exists)
$certificate = getSSL($name);
if ($certificate['success'] == "TRUE") {
$response['success'] = "TRUE";
$response['expire'] = $certificate['expire'];
$response['issued_by'] = $certificate['issued_by'];
$response['public_key'] = $certificate['public_key'];
} else {
$response['success'] = "FALSE";
}
echo json_encode($response);
}
/*
* Looks up info on the ticket number provided, used to populate the ticket merge modal
*/
if (isset($_GET['merge_ticket_get_json_details'])) {
enforceUserPermission('module_support');
$merge_into_ticket_number = intval($_GET['merge_into_ticket_number']);
$sql = mysqli_query($mysqli, "SELECT ticket_id, ticket_number, ticket_prefix, ticket_subject, ticket_priority, ticket_status, ticket_status_name, client_name, contact_name FROM tickets
LEFT JOIN clients ON ticket_client_id = client_id
LEFT JOIN contacts ON ticket_contact_id = contact_id
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
WHERE ticket_number = $merge_into_ticket_number");
if (mysqli_num_rows($sql) == 0) {
//Do nothing.
echo "No ticket found!";
} else {
//Return ticket, client and contact details for the given ticket number
$response = mysqli_fetch_array($sql);
echo json_encode($response);
}
}
if (isset($_POST['client_set_notes'])) {
enforceUserPermission('module_client', 2);
$client_id = intval($_POST['client_id']);
$notes = sanitizeInput($_POST['notes']);
// Update notes
mysqli_query($mysqli, "UPDATE clients SET client_notes = '$notes' WHERE client_id = $client_id");
// Logging
logAction("Client", "Edit", "$session_name edited client notes", $client_id);
}
if (isset($_POST['contact_set_notes'])) {
enforceUserPermission('module_client', 2);
$contact_id = intval($_POST['contact_id']);
$notes = sanitizeInput($_POST['notes']);
// Get Contact Details and Client ID for Logging
$sql = mysqli_query($mysqli,"SELECT contact_name, contact_client_id
FROM contacts WHERE contact_id = $contact_id"
);
$row = mysqli_fetch_array($sql);
$contact_name = sanitizeInput($row['contact_name']);
$client_id = intval($row['contact_client_id']);
// Update notes
mysqli_query($mysqli, "UPDATE contacts SET contact_notes = '$notes' WHERE contact_id = $contact_id");
// Logging
logAction("Contact", "Edit", "$session_name edited contact notes for $contact_name", $client_id, $contact_id);
}
if (isset($_POST['asset_set_notes'])) {
enforceUserPermission('module_support', 2);
$asset_id = intval($_POST['asset_id']);
$notes = sanitizeInput($_POST['notes']);
// Get Asset Details and Client ID for Logging
$sql = mysqli_query($mysqli,"SELECT asset_name, asset_client_id
FROM assets WHERE asset_id = $asset_id"
);
$row = mysqli_fetch_array($sql);
$asset_name = sanitizeInput($row['asset_name']);
$client_id = intval($row['asset_client_id']);
// Update notes
mysqli_query($mysqli, "UPDATE assets SET asset_notes = '$notes' WHERE asset_id = $asset_id");
// Logging
logAction("Asset", "Edit", "$session_name edited asset notes for $asset_name", $client_id, $asset_id);
}
/*
* Ticketing Collision Detection/Avoidance
* Called upon loading a ticket, and every 2 mins thereafter
* Is used in conjunction with ticket_query_views to show who is currently viewing a ticket
*/
if (isset($_GET['ticket_add_view'])) {
$ticket_id = intval($_GET['ticket_id']);
mysqli_query($mysqli, "INSERT INTO ticket_views SET view_ticket_id = $ticket_id, view_user_id = $session_user_id, view_timestamp = NOW()");
}
/*
* Ticketing Collision Detection/Avoidance
* Returns formatted text of the agents currently viewing a ticket
* Called upon loading a ticket, and every 2 mins thereafter
*/
if (isset($_GET['ticket_query_views'])) {
$ticket_id = intval($_GET['ticket_id']);
$query = mysqli_query($mysqli, "SELECT user_name FROM ticket_views LEFT JOIN users ON view_user_id = user_id WHERE view_ticket_id = $ticket_id AND view_user_id != $session_user_id AND view_timestamp > DATE_SUB(NOW(), INTERVAL 2 MINUTE)");
while ($row = mysqli_fetch_array($query)) {
$users[] = $row['user_name'];
}
if (!empty($users)) {
$users = array_unique($users);
if (count($users) > 1) {
// Multiple viewers
$response['message'] = "<i class='fas fa-fw fa-eye mr-2'></i>" . nullable_htmlentities(implode(", ", $users) . " are viewing this ticket.");
} else {
// Single viewer
$response['message'] = "<i class='fas fa-fw fa-eye mr-2'></i>" . nullable_htmlentities(implode("", $users) . " is viewing this ticket.");
}
} else {
// No viewers
$response['message'] = "";
}
echo json_encode($response);
}
/*
* Generates public/guest links for sharing credentials/docs
*/
if (isset($_GET['share_generate_link'])) {
enforceUserPermission('module_support', 2);
$item_encrypted_username = ''; // Default empty
$item_encrypted_credential = ''; // Default empty
$client_id = intval($_GET['client_id']);
$item_type = sanitizeInput($_GET['type']);
$item_id = intval($_GET['id']);
$item_email = sanitizeInput($_GET['contact_email']);
$item_note = sanitizeInput($_GET['note']);
$item_view_limit = intval($_GET['views']);
$item_view_limit_wording = "";
if ($item_view_limit == 1) {
$item_view_limit_wording = " and may only be viewed <strong>once</strong>, before the link is destroyed.";
}
$item_expires = sanitizeInput($_GET['expires']);
$item_expires_friendly = "never"; // default never
if ($item_expires == "1 HOUR") {
$item_expires_friendly = "1 hour";
} elseif ($item_expires == "24 HOUR") {
$item_expires_friendly = "1 day";
} elseif ($item_expires == "168 HOUR") {
$item_expires_friendly = "1 week";
} elseif ($item_expires == "730 HOUR") {
$item_expires_friendly = "1 month";
}
$item_key = randomString(156);
if ($item_type == "Document") {
$row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT document_name FROM documents WHERE document_id = $item_id AND document_client_id = $client_id LIMIT 1"));
$item_name = sanitizeInput($row['document_name']);
}
if ($item_type == "File") {
$row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT file_name FROM files WHERE file_id = $item_id AND file_client_id = $client_id LIMIT 1"));
$item_name = sanitizeInput($row['file_name']);
}
if ($item_type == "Credential") {
$credential = mysqli_query($mysqli, "SELECT credential_name, credential_username, credential_password FROM credentials WHERE credential_id = $item_id AND credential_client_id = $client_id LIMIT 1");
$row = mysqli_fetch_array($credential);
$item_name = sanitizeInput($row['credential_name']);
// Decrypt & re-encrypt username/password for sharing
$credential_encryption_key = randomString();
$credential_username_cleartext = decryptCredentialEntry($row['credential_username']);
$iv = randomString();
$username_ciphertext = openssl_encrypt($credential_username_cleartext, 'aes-128-cbc', $credential_encryption_key, 0, $iv);
$item_encrypted_username = $iv . $username_ciphertext;
$credential_password_cleartext = decryptCredentialEntry($row['credential_password']);
$iv = randomString();
$password_ciphertext = openssl_encrypt($credential_password_cleartext, 'aes-128-cbc', $credential_encryption_key, 0, $iv);
$item_encrypted_credential = $iv . $password_ciphertext;
}
// Insert entry into DB
$sql = mysqli_query($mysqli, "INSERT INTO shared_items SET item_active = 1, item_key = '$item_key', item_type = '$item_type', item_related_id = $item_id, item_encrypted_username = '$item_encrypted_username', item_encrypted_credential = '$item_encrypted_credential', item_note = '$item_note', item_recipient = '$item_email', item_views = 0, item_view_limit = $item_view_limit, item_expire_at = NOW() + INTERVAL + $item_expires, item_client_id = $client_id");
$share_id = $mysqli->insert_id;
// Return URL
if ($item_type == "Credential") {
$url = "https://$config_base_url/guest/guest_view_item.php?id=$share_id&key=$item_key&ek=$credential_encryption_key";
}
else {
$url = "https://$config_base_url/guest/guest_view_item.php?id=$share_id&key=$item_key";
}
$sql = mysqli_query($mysqli,"SELECT * FROM companies WHERE company_id = 1");
$row = mysqli_fetch_array($sql);
$company_name = sanitizeInput($row['company_name']);
$company_phone = sanitizeInput(formatPhoneNumber($row['company_phone'], $row['company_phone_country_code']));
// Sanitize Config vars from get_settings.php
$config_ticket_from_name = sanitizeInput($config_ticket_from_name);
$config_ticket_from_email = sanitizeInput($config_ticket_from_email);
$config_mail_from_name = sanitizeInput($config_mail_from_name);
$config_mail_from_email = sanitizeInput($config_mail_from_email);
// Send user e-mail, if specified
if(!empty($config_smtp_host) && filter_var($item_email, FILTER_VALIDATE_EMAIL)){
$subject = "Time sensitive - $company_name secure link enclosed";
if ($item_expires_friendly == "never") {
$subject = "$company_name secure link enclosed";
}
$body = "Hello,<br><br>$session_name from $company_name sent you a time sensitive secure link regarding \"$item_name\".<br><br>The link will expire in <strong>$item_expires_friendly</strong>$item_view_limit_wording.<br><br><strong><a href=\'$url\'>Click here to access your secure content</a></strong><br><br>--<br>$company_name - Support<br>$config_ticket_from_email<br>$company_phone";
// Add the intended recipient disclosure
$body .= "<br><br><em>This email and any attachments are confidential and intended for the specified recipient(s) only. If you are not the intended recipient, please notify the sender and delete this email. Unauthorized use, disclosure, or distribution is prohibited.</em>";
$data = [
[
'from' => $config_mail_from_email,
'from_name' => $config_mail_from_name,
'recipient' => $item_email,
'recipient_name' => $item_email,
'subject' => $subject,
'body' => $body
]
];
addToMailQueue($data);
}
echo json_encode($url);
// Logging
logAction("Share", "Create", "$session_name created shared link for $item_type - $item_name", $client_id, $item_id);
}
/*
* Returns sorted list of active clients
*/
if (isset($_GET['get_active_clients'])) {
enforceUserPermission('module_client');
$client_sql = mysqli_query(
$mysqli,
"SELECT client_id, client_name FROM clients
WHERE client_archived_at IS NULL
$access_permission_query
ORDER BY client_accessed_at DESC"
);
while ($row = mysqli_fetch_array($client_sql)) {
$response['clients'][] = $row;
}
echo json_encode($response);
}
/*
* Returns ordered list of active contacts for a specified client
*/
if (isset($_GET['get_client_contacts'])) {
enforceUserPermission('module_client');
$client_id = intval($_GET['client_id']);
$contact_sql = mysqli_query(
$mysqli,
"SELECT contact_id, contact_name, contact_primary, contact_important, contact_technical FROM contacts
LEFT JOIN clients on contact_client_id = client_id
WHERE contacts.contact_archived_at IS NULL AND contact_client_id = $client_id
$access_permission_query
ORDER BY contact_primary DESC, contact_technical DESC, contact_important DESC, contact_name"
);
while ($row = mysqli_fetch_array($contact_sql)) {
$response['contacts'][] = $row;
}
echo json_encode($response);
}
/*
* Returns ordered list of active assets for a specified client
*/
if (isset($_GET['get_client_assets'])) {
enforceUserPermission('module_client');
$client_id = intval($_GET['client_id']);
$asset_sql = mysqli_query(
$mysqli,
"SELECT asset_id, asset_name, contact_name FROM assets
LEFT JOIN clients on asset_client_id = client_id
LEFT JOIN contacts ON contact_id = asset_contact_id
WHERE assets.asset_archived_at IS NULL AND asset_client_id = $client_id
$access_permission_query
ORDER BY asset_important DESC, asset_name"
);
while ($row = mysqli_fetch_array($asset_sql)) {
$response['assets'][] = $row;
}
echo json_encode($response);
}
/*
* Returns locations for a specified client
*/
if (isset($_GET['get_client_locations'])) {
enforceUserPermission('module_client');
$client_id = intval($_GET['client_id']);
$locations_sql = mysqli_query(
$mysqli,
"SELECT location_id, location_name FROM locations
LEFT JOIN clients on location_client_id = client_id
WHERE locations.location_archived_at IS NULL AND location_client_id = $client_id
$access_permission_query
ORDER BY location_primary DESC, location_name ASC"
);
while ($row = mysqli_fetch_array($locations_sql)) {
$response['locations'][] = $row;
}
echo json_encode($response);
}
/*
* Returns ordered list of vendors for a specified client
*/
if (isset($_GET['get_client_vendors'])) {
enforceUserPermission('module_client');
$client_id = intval($_GET['client_id']);
$vendors_sql = mysqli_query(
$mysqli,
"SELECT vendor_id, vendor_name FROM vendors
LEFT JOIN clients on vendor_client_id = client_id
WHERE vendors.vendor_archived_at IS NULL AND vendor_client_id = $client_id
$access_permission_query
ORDER BY vendor_name ASC"
);
while ($row = mysqli_fetch_array($vendors_sql)) {
$response['vendors'][] = $row;
}
echo json_encode($response);
}
/*
* NEW TOTP getter for client login/passwords page
* When provided with a login ID, checks permissions and returns the 6-digit code
*/
if (isset($_GET['get_totp_token_via_id'])) {
enforceUserPermission('module_credential');
$credential_id = intval($_GET['credential_id']);
$sql = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT credential_name, credential_otp_secret, credential_client_id FROM credentials WHERE credential_id = $credential_id"));
$name = sanitizeInput($sql['credential_name']);
$totp_secret = $sql['credential_otp_secret'];
$client_id = intval($sql['credential_client_id']);
$otp = TokenAuth6238::getTokenCode(strtoupper($totp_secret));
echo json_encode($otp);
// Logging
// Only log the TOTP view if the user hasn't already viewed this specific login entry recently, this prevents logs filling if a user hovers across an entry a few times
$check_recent_totp_view_logged_sql = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT(log_id) AS recent_totp_view FROM logs WHERE log_type = 'Credential' AND log_action = 'View TOTP' AND log_user_id = $session_user_id AND log_entity_id = $credential_id AND log_client_id = $client_id AND log_created_at > (NOW() - INTERVAL 5 MINUTE)"));
$recent_totp_view_logged_count = intval($check_recent_totp_view_logged_sql['recent_totp_view']);
if ($recent_totp_view_logged_count == 0) {
// Logging
logAction("Credential", "View TOTP", "$session_name viewed credential TOTP code for $name", $client_id, $credential_id);
}
}
if (isset($_GET['get_readable_pass'])) {
echo json_encode(GenerateReadablePassword(4));
}
/*
* ITFlow - POST request handler for client tickets
*/
if (isset($_POST['update_kanban_status_position'])) {
// Update multiple ticket status kanban orders
enforceUserPermission('module_support', 2);
$positions = $_POST['positions'];
foreach ($positions as $position) {
$status_id = intval($position['status_id']);
$kanban = intval($position['status_kanban']);
mysqli_query($mysqli, "UPDATE ticket_statuses SET ticket_status_order = $kanban WHERE ticket_status_id = $status_id");
}
// return a response
echo json_encode(['status' => 'success']);
exit;
}
if (isset($_POST['update_kanban_ticket'])) {
// Update ticket kanban order and status
enforceUserPermission('module_support', 2);
// all tickets on the column
$positions = $_POST['positions'];
foreach ($positions as $position) {
$ticket_id = intval($position['ticket_id']);
$kanban = intval($position['ticket_order']); // ticket kanban position
$status = intval($position['ticket_status']); // ticket statuses
$oldStatus = intval($position['ticket_oldStatus']); // ticket old status if moved
$statuses['Closed'] = 5;
$statuses['Resolved'] = 4;
// Continue if status is null / Closed
if ($status === null || $status === $statuses['Closed']) {
continue;
}
if ($oldStatus === false) {
// if ticket was not moved, just uptdate the order on kanban
mysqli_query($mysqli, "UPDATE tickets SET ticket_order = $kanban WHERE ticket_id = $ticket_id");
customAction('ticket_update', $ticket_id);
} else {
// If the ticket was moved from a resolved status to another status, we need to update ticket_resolved_at
if ($oldStatus === $statuses['Resolved']) {
mysqli_query($mysqli, "UPDATE tickets SET ticket_order = $kanban, ticket_status = $status, ticket_resolved_at = NULL WHERE ticket_id = $ticket_id");
customAction('ticket_update', $ticket_id);
} elseif ($status === $statuses['Resolved']) {
// If the ticket was moved to a resolved status, we need to update ticket_resolved_at
mysqli_query($mysqli, "UPDATE tickets SET ticket_order = $kanban, ticket_status = $status, ticket_resolved_at = NOW() WHERE ticket_id = $ticket_id");
customAction('ticket_update', $ticket_id);
// Client notification email
if (!empty($config_smtp_host) && $config_ticket_client_general_notifications == 1) {
// Get details
$ticket_sql = mysqli_query($mysqli, "SELECT contact_name, contact_email, ticket_prefix, ticket_number, ticket_subject, ticket_status_name, ticket_assigned_to, ticket_url_key, ticket_client_id FROM tickets
LEFT JOIN clients ON ticket_client_id = client_id
LEFT JOIN contacts ON ticket_contact_id = contact_id
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
WHERE ticket_id = $ticket_id
");
$row = mysqli_fetch_array($ticket_sql);
$contact_name = sanitizeInput($row['contact_name']);
$contact_email = sanitizeInput($row['contact_email']);
$ticket_prefix = sanitizeInput($row['ticket_prefix']);
$ticket_number = intval($row['ticket_number']);
$ticket_subject = sanitizeInput($row['ticket_subject']);
$client_id = intval($row['ticket_client_id']);
$ticket_assigned_to = intval($row['ticket_assigned_to']);
$ticket_status = sanitizeInput($row['ticket_status_name']);
$url_key = sanitizeInput($row['ticket_url_key']);
// Sanitize Config vars from get_settings.php
$config_ticket_from_name = sanitizeInput($config_ticket_from_name);
$config_ticket_from_email = sanitizeInput($config_ticket_from_email);
$config_base_url = sanitizeInput($config_base_url);
// Get Company Info
$sql = mysqli_query($mysqli, "SELECT company_name, company_phone, company_phone_country_code FROM companies WHERE company_id = 1");
$row = mysqli_fetch_array($sql);
$company_name = sanitizeInput($row['company_name']);
$company_phone = sanitizeInput(formatPhoneNumber($row['company_phone'], $row['company_phone_country_code']));
// EMAIL
$subject = "Ticket resolved - [$ticket_prefix$ticket_number] - $ticket_subject | (pending closure)";
$body = "<i style=\'color: #808080\'>##- Please type your reply above this line -##</i><br><br>Hello $contact_name,<br><br>Your ticket regarding $ticket_subject has been marked as solved and is pending closure.<br><br>If your request/issue is resolved, you can simply ignore this email. If you need further assistance, please reply or <a href=\'https://$config_base_url/guest/guest_view_ticket.php?ticket_id=$ticket_id&url_key=$url_key\'>re-open</a> to let us know! <br><br>Ticket: $ticket_prefix$ticket_number<br>Subject: $ticket_subject<br>Status: $ticket_status<br>Portal: <a href=\'https://$config_base_url/guest/guest_view_ticket.php?ticket_id=$ticket_id&url_key=$url_key\'>View ticket</a><br><br>--<br>$company_name - Support<br>$config_ticket_from_email<br>$company_phone";
// Check email valid
if (filter_var($contact_email, FILTER_VALIDATE_EMAIL)) {
$data = [];
// Email Ticket Contact
// Queue Mail
$data[] = [
'from' => $config_ticket_from_email,
'from_name' => $config_ticket_from_name,
'recipient' => $contact_email,
'recipient_name' => $contact_name,
'subject' => $subject,
'body' => $body
];
}
// Also Email all the watchers
$sql_watchers = mysqli_query($mysqli, "SELECT watcher_email FROM ticket_watchers WHERE watcher_ticket_id = $ticket_id");
$body .= "<br><br>----------------------------------------<br>YOU ARE A COLLABORATOR ON THIS TICKET";
while ($row = mysqli_fetch_array($sql_watchers)) {
$watcher_email = sanitizeInput($row['watcher_email']);
// Queue Mail
$data[] = [
'from' => $config_ticket_from_email,
'from_name' => $config_ticket_from_name,
'recipient' => $watcher_email,
'recipient_name' => $watcher_email,
'subject' => $subject,
'body' => $body
];
}
addToMailQueue($data);
}
//End Mail IF
} else {
// If the ticket was moved from any status to another status
mysqli_query($mysqli, "UPDATE tickets SET ticket_order = $kanban, ticket_status = $status WHERE ticket_id = $ticket_id");
customAction('ticket_update', $ticket_id);
}
}
}
// return a response
echo json_encode(['status' => 'success','payload' => $positions]);
exit;
}
if (isset($_POST['update_ticket_tasks_order'])) {
// Update multiple ticket tasks order
enforceUserPermission('module_support', 2);
$positions = $_POST['positions'];
$ticket_id = intval($_POST['ticket_id']);
foreach ($positions as $position) {
$id = intval($position['id']);
$order = intval($position['order']);
mysqli_query($mysqli, "UPDATE tasks SET task_order = $order WHERE task_ticket_id = $ticket_id AND task_id = $id");
}
// return a response
echo json_encode(['status' => 'success']);
exit;
}
if (isset($_POST['update_task_templates_order'])) {
// Update multiple task templates order
enforceUserPermission('module_support', 2);
$positions = $_POST['positions'];
$ticket_template_id = intval($_POST['ticket_template_id']);
foreach ($positions as $position) {
$id = intval($position['id']);
$order = intval($position['order']);
mysqli_query($mysqli, "UPDATE task_templates SET task_template_order = $order WHERE task_template_ticket_template_id = $ticket_template_id AND task_template_id = $id");
}
// return a response
echo json_encode(['status' => 'success']);
exit;
}
if (isset($_POST['update_quote_items_order'])) {
// Update multiple quote items order
enforceUserPermission('module_sales', 2);
$positions = $_POST['positions'];
$quote_id = intval($_POST['quote_id']);
foreach ($positions as $position) {
$id = intval($position['id']);
$order = intval($position['order']);
mysqli_query($mysqli, "UPDATE invoice_items SET item_order = $order WHERE item_quote_id = $quote_id AND item_id = $id");
}
// return a response
echo json_encode(['status' => 'success']);
exit;
}
if (isset($_POST['update_invoice_items_order'])) {
// Update multiple invoice items order
enforceUserPermission('module_sales', 2);
$positions = $_POST['positions'];
$invoice_id = intval($_POST['invoice_id']);
foreach ($positions as $position) {
$id = intval($position['id']);
$order = intval($position['order']);
mysqli_query($mysqli, "UPDATE invoice_items SET item_order = $order WHERE item_invoice_id = $invoice_id AND item_id = $id");
}
// return a response
echo json_encode(['status' => 'success']);
exit;
}
if (isset($_POST['update_recurring_invoice_items_order'])) {
// Update multiple recurring invoice items order
enforceUserPermission('module_sales', 2);
$positions = $_POST['positions'];
$recurring_invoice_id = intval($_POST['recurring_invoice_id']);
foreach ($positions as $position) {
$id = intval($position['id']);
$order = intval($position['order']);
mysqli_query($mysqli, "UPDATE invoice_items SET item_order = $order WHERE item_recurring_invoice_id = $recurring_invoice_id AND item_id = $id");
}
// return a response
echo json_encode(['status' => 'success']);
exit;
}

1228
agent/asset_details.php Normal file

File diff suppressed because it is too large Load Diff

741
agent/assets.php Normal file
View File

@@ -0,0 +1,741 @@
<?php
// Default Column Sortby Filter
$sort = "asset_name";
$order = "ASC";
// If client_id is in URI then show client Side Bar and client header
if (isset($_GET['client_id'])) {
require_once "includes/inc_all_client.php";
$client_query = "AND asset_client_id = $client_id";
$client_url = "client_id=$client_id&";
// Overide Filter Header Archived
if (isset($_GET['archived']) && $_GET['archived'] == 1) {
$archived = 1;
$archive_query = "asset_archived_at IS NOT NULL";
} else {
$archived = 0;
$archive_query = "asset_archived_at IS NULL";
}
} else {
require_once "includes/inc_client_overview_all.php";
$client_query = '';
$client_url = '';
// Overide Filter Header Archived
if (isset($_GET['archived']) && $_GET['archived'] == 1) {
$archived = 1;
$archive_query = "(client_archived_at IS NOT NULL OR asset_archived_at IS NOT NULL)";
} else {
$archived = 0;
$archive_query = "(client_archived_at IS NULL AND asset_archived_at IS NULL)";
}
}
// Perms
enforceUserPermission('module_support');
//Asset Type from GET
if (isset($_GET['type']) && ($_GET['type']) == 'workstation') {
$type_query = "asset_type = 'desktop' OR asset_type = 'laptop'";
} elseif (isset($_GET['type']) && ($_GET['type']) == 'server') {
$type_query = "asset_type = 'server'";
} elseif (isset($_GET['type']) && ($_GET['type']) == 'virtual') {
$type_query = "asset_type = 'Virtual Machine'";
} elseif (isset($_GET['type']) && ($_GET['type']) == 'network') {
$type_query = "asset_type = 'Firewall/Router' OR asset_type = 'Switch' OR asset_type = 'Access Point'";
} elseif (isset($_GET['type']) && ($_GET['type']) == 'other') {
$type_query = "asset_type NOT LIKE 'laptop' AND asset_type NOT LIKE 'desktop' AND asset_type NOT LIKE 'server' AND asset_type NOT LIKE 'virtual machine' AND asset_type NOT LIKE 'firewall/router' AND asset_type NOT LIKE 'switch' AND asset_type NOT LIKE 'access point'";
} else {
$type_query = "asset_type LIKE '%'";
$_GET['type'] = '';
}
if (!$client_url) {
// Client Filter
if (isset($_GET['client']) & !empty($_GET['client'])) {
$client_query = 'AND (asset_client_id = ' . intval($_GET['client']) . ')';
$client = intval($_GET['client']);
} else {
// Default - any
$client_query = '';
$client = '';
}
}
// Location Filter
if ($client_url && isset($_GET['location']) && !empty($_GET['location'])) {
$location_query = 'AND (asset_location_id = ' . intval($_GET['location']) . ')';
$location_filter = intval($_GET['location']);
} else {
// Default - any
$location_query = '';
$location_filter = 0;
}
//Get Asset Counts
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "
SELECT
COUNT(*) AS all_count,
SUM(CASE WHEN asset_type IN ('laptop', 'desktop') THEN 1 ELSE 0 END) AS workstation_count,
SUM(CASE WHEN asset_type = 'server' THEN 1 ELSE 0 END) AS server_count,
SUM(CASE WHEN asset_type = 'virtual machine' THEN 1 ELSE 0 END) AS virtual_count,
SUM(CASE WHEN asset_type IN ('Firewall/Router', 'switch', 'access point') THEN 1 ELSE 0 END) AS network_count,
SUM(CASE WHEN asset_type NOT IN ('laptop', 'desktop', 'server', 'virtual machine', 'Firewall/Router', 'switch', 'access point') THEN 1 ELSE 0 END) AS other_count
FROM (
SELECT assets.* FROM assets
LEFT JOIN clients ON client_id = asset_client_id
LEFT JOIN contacts ON asset_contact_id = contact_id
LEFT JOIN locations ON asset_location_id = location_id
LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1
WHERE $archive_query
$access_permission_query
$client_query
) AS filtered_assets;
"));
//All Asset Count
$all_count = intval($row['all_count']);
//Workstation Count
$workstation_count = intval($row['workstation_count']);
//Server Count
$server_count = intval($row['server_count']);
//Virtual Server Count
$virtual_count = intval($row['virtual_count']);
//Network Device Count
$network_count = intval($row['network_count']);
//Other Count
$other_count = intval($row['other_count']);
//Rebuild URL
$url_query_strings_sort = http_build_query($get_copy);
$sql = mysqli_query(
$mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM assets
LEFT JOIN clients ON asset_client_id = client_id
LEFT JOIN contacts ON asset_contact_id = contact_id
LEFT JOIN locations ON asset_location_id = location_id
LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1
WHERE $archive_query
AND (asset_name LIKE '%$q%' OR asset_description LIKE '%$q%' OR asset_type LIKE '%$q%' OR interface_ip LIKE '%$q%' OR interface_ipv6 LIKE '%$q%' OR interface_mac LIKE '%$q%' OR asset_make LIKE '%$q%' OR asset_model LIKE '%$q%' OR asset_serial LIKE '%$q%' OR asset_os LIKE '%$q%' OR contact_name LIKE '%$q%' OR location_name LIKE '%$q%' OR client_name LIKE '%$q%')
AND ($type_query)
$access_permission_query
$location_query
$client_query
ORDER BY $sort $order LIMIT $record_from, $record_to"
);
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
// OS typeahead suggestions
$os_sql = mysqli_query($mysqli, "SELECT DISTINCT asset_os AS label FROM assets WHERE asset_archived_at IS NULL");
if ($os_sql && mysqli_num_rows($os_sql) > 0) {
$os_arr = [];
while ($row = mysqli_fetch_assoc($os_sql)) {
// jQuery UI Autocomplete expects {label: "...", value: "..."}
$label = $row['label'];
$os_arr[] = ['label' => $label, 'value' => $label];
}
$json_os = json_encode($os_arr);
}
?>
<div class="col-sm-12 mb-3">
<div class="btn-toolbar">
<div class="btn-group btn-block">
<?php if($all_count) { ?>
<a href="?<?php echo $url_query_strings_sort; ?>&type=" class="btn <?php if ($_GET['type'] == 'all' || empty($_GET['type'])) { echo 'btn-primary'; } else { echo 'btn-default'; } ?>">All Assets<span class="right badge badge-light ml-2"><?php echo $all_count; ?></span></a>
<?php } ?>
<?php
if ($workstation_count > 0) { ?>
<a href="?<?php echo $url_query_strings_sort; ?>&type=workstation" class="btn <?php if ($_GET['type'] == 'workstation') { echo 'btn-primary'; } else { echo 'btn-default'; } ?>"><i class="fa fa-fw fa-desktop mr-2"></i>Workstations<span class="right badge badge-light ml-2"><?php echo $workstation_count; ?></span></a>
<?php
}
if ($server_count > 0) { ?>
<a href="?<?php echo $url_query_strings_sort; ?>&type=server" class="btn <?php if ($_GET['type'] == 'server') { echo 'btn-primary'; } else { echo 'btn-default'; } ?>"><i class="fa fa-fw fa-server mr-2"></i>Servers<span class="right badge badge-light ml-2"><?php echo $server_count; ?></span></a>
<?php
}
if ($virtual_count > 0) { ?>
<a href="?<?php echo $url_query_strings_sort; ?>&type=virtual" class="btn <?php if ($_GET['type'] == 'virtual') { echo 'btn-primary'; } else { echo 'btn-default'; } ?>"><i class="fa fa-fw fa-cloud mr-2"></i>Virtual<span class="right badge badge-light ml-2"><?php echo $virtual_count; ?></span></a>
<?php
}
if ($network_count > 0) { ?>
<a href="?<?php echo $url_query_strings_sort; ?>&type=network" class="btn <?php if ($_GET['type'] == 'network') { echo 'btn-primary'; } else { echo 'btn-default'; } ?>"><i class="fa fa-fw fa-network-wired mr-2"></i>Network<span class="right badge badge-light ml-2"><?php echo $network_count; ?></span></a>
<?php
}
if ($other_count > 0) { ?>
<a href="?<?php echo $url_query_strings_sort; ?>&type=other" class="btn <?php if ($_GET['type'] == 'other') { echo 'btn-primary'; } else { echo 'btn-default'; } ?>"><i class="fa fa-fw fa-tag mr-2"></i>Other<span class="right badge badge-light ml-2"><?php echo $other_count; ?></span></a>
<?php
} ?>
</div>
</div>
</div>
<div class="card card-dark">
<div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fas fa-fw fa-desktop mr-2"></i>Assets</h3>
<div class="card-tools">
<?php if (lookupUserPermission("module_support") >= 2) { ?>
<div class="btn-group">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addAssetModal">
<i class="fas fa-plus mr-2"></i>New <?php if (!empty($_GET['type'])) { echo ucwords(strip_tags(nullable_htmlentities($_GET['type']))); } else { echo "Asset"; } ?>
</button>
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<?php if ($client_url) { ?>
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#importAssetModal">
<i class="fa fa-fw fa-upload mr-2"></i>Import
</a>
<div class="dropdown-divider"></div>
<?php } ?>
<?php if ($num_rows[0] > 0) { ?>
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#exportAssetModal">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
<?php } ?>
</div>
</div>
<?php } ?>
</div>
</div>
<div class="card-body">
<form autocomplete="off">
<?php if ($client_url) { ?>
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<?php } ?>
<input type="hidden" name="type" value="<?php echo stripslashes(nullable_htmlentities($_GET['type'])); ?>">
<input type="hidden" name="archived" value="<?php echo $archived; ?>">
<div class="row">
<div class="col-md-4">
<div class="input-group mb-3 mb-md-0">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search <?php if (!empty($_GET['type'])) { echo ucwords(stripslashes(nullable_htmlentities($_GET['type']))); } else { echo "Asset"; } ?>s">
<div class="input-group-append">
<button class="btn btn-dark"><i class="fa fa-search"></i></button>
</div>
</div>
</div>
<?php if ($client_url) { ?>
<div class="col-md-2">
<div class="input-group mb-3 mb-md-0">
<select class="form-control select2" name="location" onchange="this.form.submit()">
<option value="">- All Locations -</option>
<?php
$sql_locations_filter = mysqli_query($mysqli, "
SELECT DISTINCT location_id, location_name
FROM locations
WHERE location_client_id = $client_id
AND ( EXISTS (SELECT 1 FROM assets WHERE asset_location_id = location_id AND $archive_query) OR location_id = $location_filter)
ORDER BY location_name ASC
");
while ($row = mysqli_fetch_array($sql_locations_filter)) {
$location_id = intval($row['location_id']);
$location_name = nullable_htmlentities($row['location_name']);
?>
<option <?php if ($location_filter == $location_id) { echo "selected"; } ?> value="<?php echo $location_id; ?>"><?php echo $location_name; ?></option>
<?php
}
?>
</select>
</div>
</div>
<?php } else { ?>
<div class="col-md-2">
<div class="input-group mb-3 mb-md-0">
<select class="form-control select2" name="client" onchange="this.form.submit()">
<option value="" <?php if ($client == "") { echo "selected"; } ?>>- All Clients -</option>
<?php
$sql_clients_filter = mysqli_query($mysqli, "
SELECT DISTINCT client_id, client_name
FROM clients
JOIN assets ON asset_client_id = client_id
WHERE $archive_query
$access_permission_query
ORDER BY client_name ASC
");
while ($row = mysqli_fetch_array($sql_clients_filter)) {
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
?>
<option <?php if ($client == $client_id) { echo "selected"; } ?> value="<?php echo $client_id; ?>"><?php echo $client_name; ?></option>
<?php
}
?>
</select>
</div>
</div>
<?php } ?>
<div class="col-md-3">
<div class="form-group">
<select onchange="this.form.submit()" class="form-control select2" name="show_column[]" data-placeholder="- Show Additional Columns -" multiple>
<option
<?php if (isset($_GET['show_column']) && is_array($_GET['show_column']) && in_array('Mac_Address', $_GET['show_column'])) { echo 'selected'; } ?>>Mac_Address
</option>
<option
<?php if (isset($_GET['show_column']) && is_array($_GET['show_column']) && in_array('OS', $_GET['show_column'])) { echo 'selected'; } ?>>OS
</option>
<option
<?php if (isset($_GET['show_column']) && is_array($_GET['show_column']) && in_array('Purchase_Date', $_GET['show_column'])) { echo 'selected'; } ?>>Purchase_Date
</option>
<option
<?php if (isset($_GET['show_column']) && is_array($_GET['show_column']) && in_array('Install_Date', $_GET['show_column'])) { echo 'selected'; } ?>>Install_Date
</option>
<option
<?php if (isset($_GET['show_column']) && is_array($_GET['show_column']) && in_array('Warranty_Expire', $_GET['show_column'])) { echo 'selected'; } ?>>Warranty_Expire
</option>
</select>
</div>
</div>
<div class="col-md-3">
<div class="btn-group float-right">
<a href="?<?php echo $client_url; ?>&archived=<?php if($archived == 1){ echo 0; } else { echo 1; } ?>"
class="btn btn-<?php if($archived == 1){ echo "primary"; } else { echo "default"; } ?>">
<i class="fa fa-fw fa-archive mr-2"></i>Archived
</a>
<div class="dropdown ml-2" id="bulkActionButton" hidden>
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">
<i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount"></span>)
</button>
<div class="dropdown-menu">
<?php if ($client_url) { ?>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkAssignContactModal">
<i class="fas fa-fw fa-user mr-2"></i>Assign Contact
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkAssignLocationModal">
<i class="fas fa-fw fa-map-marker-alt mr-2"></i>Assign Location
</a>
<?php } ?>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkAssignPhysicalLocationModal">
<i class="fas fa-fw fa-map-marker-alt mr-2"></i>Set Physical Location
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkEditStatusModal">
<i class="fas fa-fw fa-info mr-2"></i>Set Status
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkAddTicketModal">
<i class="fas fa-fw fa-life-ring mr-2"></i>Create Tickets
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkTransferAssetClientModal">
<i class="fas fa-fw fa-arrow-right mr-2"></i>Transfer to Client
</a>
<?php if ($archived) { ?>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-info"
type="submit" form="bulkActions" name="bulk_unarchive_assets">
<i class="fas fa-fw fa-redo mr-2"></i>Unarchive
</button>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-danger text-bold"
type="submit" form="bulkActions" name="bulk_delete_assets">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</button>
<?php } else { ?>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-danger confirm-link"
type="submit" form="bulkActions" name="bulk_archive_assets">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</button>
<?php } ?>
</div>
</div>
</div>
</div>
</div>
</form>
<hr>
<form id="bulkActions" action="post.php" method="post" enctype="multipart/form-data">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<div class="table-responsive">
<table class="table border table-hover">
<thead class="thead-light <?php if (!$num_rows[0]) { echo "d-none"; } ?> text-nowrap">
<tr>
<td class="bg-light pr-0">
<div class="form-check">
<input class="form-check-input" id="selectAllCheckbox" type="checkbox" onclick="checkAll(this)">
</div>
</td>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=asset_name&order=<?php echo $disp; ?>">
Name <?php if ($sort == 'asset_name') { echo $order_icon; } ?>
</a>
</th>
<?php if ($_GET['type'] !== 'virtual' && $_GET['type'] !== 'server') { ?>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=asset_type&order=<?php echo $disp; ?>">
Type <?php if ($sort == 'asset_type') { echo $order_icon; } ?>
</a>
</th>
<?php } ?>
<?php if ($_GET['type'] !== 'virtual') { ?>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=asset_make&order=<?php echo $disp; ?>">
Model <?php if ($sort == 'asset_make') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=asset_serial&order=<?php echo $disp; ?>">
Serial <?php if ($sort == 'asset_serial') { echo $order_icon; } ?>
</a>
</th>
<?php } ?>
<?php if (isset($_GET['show_column']) && is_array($_GET['show_column']) && in_array('OS', $_GET['show_column'])) { ?>
<?php if ($_GET['type'] !== 'network' && $_GET['type'] !== 'other') { ?>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=asset_os&order=<?php echo $disp; ?>">
OS <?php if ($sort == 'asset_os') { echo $order_icon; } ?>
</a>
</th>
<?php } ?>
<?php } ?>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=interface_ip&order=<?php echo $disp; ?>">
IP <?php if ($sort == 'interface_ip') { echo $order_icon; } ?>
</a>
</th>
<?php if (isset($_GET['show_column']) && is_array($_GET['show_column']) && in_array('Mac_Address', $_GET['show_column'])) { ?>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=interface_mac&order=<?php echo $disp; ?>">
MAC Address <?php if ($sort == 'interface_mac') { echo $order_icon; } ?>
</a>
</th>
<?php } ?>
<?php if (isset($_GET['show_column']) && is_array($_GET['show_column']) && in_array('Purchase_Date', $_GET['show_column'])) { ?>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=asset_purchase_date&order=<?php echo $disp; ?>">
Purchase Date <?php if ($sort == 'asset_purchase_date') { echo $order_icon; } ?>
</a>
</th>
<?php } ?>
<?php if (isset($_GET['show_column']) && is_array($_GET['show_column']) && in_array('Install_Date', $_GET['show_column'])) { ?>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=asset_install_date&order=<?php echo $disp; ?>">
Install Date <?php if ($sort == 'asset_install_date') { echo $order_icon; } ?>
</a>
</th>
<?php } ?>
<?php if (isset($_GET['show_column']) && is_array($_GET['show_column']) && in_array('Warranty_Expire', $_GET['show_column'])) { ?>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=asset_warranty_expire&order=<?php echo $disp; ?>">
Warranty Expire <?php if ($sort == 'asset_warranty_expire') { echo $order_icon; } ?>
</a>
</th>
<?php } ?>
<?php if ($_GET['type'] !== 'network' && $_GET['type'] !== 'server' && $_GET['type'] !== 'other') { ?>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=contact_name&order=<?php echo $disp; ?>">
Assigned To <?php if ($sort == 'contact_name') { echo $order_icon; } ?>
</a>
</th>
<?php } ?>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=location_name&order=<?php echo $disp; ?>">
Location <?php if ($sort == 'location_name') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=asset_status&order=<?php echo $disp; ?>">
Status <?php if ($sort == 'asset_status') { echo $order_icon; } ?>
</a>
</th>
<?php if (!$client_url) { ?>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=client_name&order=<?php echo $disp; ?>">
Client <?php if ($sort == 'client_name') { echo $order_icon; } ?>
</a>
</th>
<?php } ?>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql)) {
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
$asset_id = intval($row['asset_id']);
$asset_type = nullable_htmlentities($row['asset_type']);
$asset_name = nullable_htmlentities($row['asset_name']);
$asset_description = nullable_htmlentities($row['asset_description']);
if ($asset_description) {
$asset_description_display = $asset_description;
} else {
$asset_description_display = "-";
}
$asset_make = nullable_htmlentities($row['asset_make']);
$asset_model = nullable_htmlentities($row['asset_model']);
$asset_serial = nullable_htmlentities($row['asset_serial']);
if ($asset_serial) {
$asset_serial_display = $asset_serial;
} else {
$asset_serial_display = "-";
}
$asset_os = nullable_htmlentities($row['asset_os']);
if ($asset_os) {
$asset_os_display = $asset_os;
} else {
$asset_os_display = "-";
}
$asset_ip = nullable_htmlentities($row['interface_ip']);
if ($asset_ip) {
$asset_ip_display = $asset_ip;
} else {
$asset_ip_display = "-";
}
$asset_ipv6 = nullable_htmlentities($row['interface_ipv6']);
$asset_nat_ip = nullable_htmlentities($row['interface_nat_ip']);
$asset_mac = nullable_htmlentities(getFallBack($row['interface_mac']));
$asset_uri = sanitize_url($row['asset_uri']);
$asset_uri_2 = sanitize_url($row['asset_uri_2']);
$asset_uri_client = sanitize_url($row['asset_uri_client']);
$asset_status = nullable_htmlentities($row['asset_status']);
$asset_purchase_reference = nullable_htmlentities($row['asset_purchase_reference']);
$asset_purchase_date = nullable_htmlentities($row['asset_purchase_date']);
if ($asset_purchase_date) {
$asset_purchase_date_display = $asset_purchase_date;
} else {
$asset_purchase_date_display = "-";
}
$asset_warranty_expire = nullable_htmlentities($row['asset_warranty_expire']);
if ($asset_warranty_expire) {
$asset_warranty_expire_display = $asset_warranty_expire;
} else {
$asset_warranty_expire_display = "-";
}
$asset_install_date = nullable_htmlentities($row['asset_install_date']);
if ($asset_install_date) {
$asset_install_date_display = $asset_install_date;
} else {
$asset_install_date_display = "-";
}
$asset_photo = nullable_htmlentities($row['asset_photo']);
$asset_physical_location = nullable_htmlentities($row['asset_physical_location']);
if ($asset_physical_location) {
$asset_physical_location_display = "<div class='text-secondary'>$asset_physical_location</div>";
} else {
$asset_physical_location_display = "";
}
$asset_notes = nullable_htmlentities($row['asset_notes']);
$asset_created_at = nullable_htmlentities($row['asset_created_at']);
$asset_archived_at = nullable_htmlentities($row['asset_archived_at']);
$asset_vendor_id = intval($row['asset_vendor_id']);
$asset_location_id = intval($row['asset_location_id']);
$asset_contact_id = intval($row['asset_contact_id']);
$asset_network_id = intval($row['interface_network_id']);
$device_icon = getAssetIcon($asset_type);
$contact_archived_at = nullable_htmlentities($row['contact_archived_at']);
if ($contact_archived_at) {
$contact_archive_display = "<span class='text-danger'>(Archived)</span>";
} else {
$contact_archive_display = '';
}
$contact_name = nullable_htmlentities($row['contact_name']);
if ($contact_name) {
$contact_name_display = "<a class='ajax-modal' href='#' data-modal-url='modals/contact/contact_details.php?id=$asset_contact_id' data-modal-size='lg'>$contact_name $contact_archive_display</a>";
} else {
$contact_name_display = "-";
}
$location_name = nullable_htmlentities($row['location_name']);
if (empty($location_name)) {
$location_name = "-";
}
$location_archived_at = nullable_htmlentities($row['location_archived_at']);
if ($location_archived_at) {
$location_name_display = "<div class='text-danger' title='Archived'><s>$location_name</s></div>";
} else {
$location_name_display = $location_name;
}
$sql_credentials = mysqli_query($mysqli, "SELECT * FROM credentials WHERE credential_asset_id = $asset_id");
$credential_count = mysqli_num_rows($sql_credentials);
?>
<tr>
<td class="pr-0 bg-light">
<div class="form-check">
<input class="form-check-input bulk-select" type="checkbox" name="asset_ids[]" value="<?php echo $asset_id ?>">
</div>
</td>
<td>
<a class="text-dark" href="asset_details.php?client_id=<?php echo $client_id; ?>&asset_id=<?php echo $asset_id; ?>">
<div class="media">
<i class="fa fa-fw fa-2x fa-<?php echo $device_icon; ?> mr-3 mt-1"></i>
<div class="media-body">
<div><?php echo $asset_name; ?></div>
<div><small class="text-secondary"><?php echo $asset_description; ?></small></div>
</div>
</div>
</a>
</td>
<?php if ($_GET['type'] !== 'virtual' && $_GET['type'] !== 'server') { ?>
<td><?php echo $asset_type; ?></td>
<?php } ?>
<?php if ($_GET['type'] !== 'virtual') { ?>
<td>
<?php echo $asset_make; ?>
<div class="mt-0">
<small class="text-muted"><?php echo $asset_model; ?></small>
</div>
</td>
<?php } ?>
<?php if ($_GET['type'] !== 'virtual') { ?>
<td><?php echo $asset_serial_display; ?></td>
<?php } ?>
<?php if (isset($_GET['show_column']) && is_array($_GET['show_column']) && in_array('OS', $_GET['show_column'])) { ?>
<?php if ($_GET['type'] !== 'network' && $_GET['type'] !== 'other') { ?>
<td><?php echo $asset_os_display; ?></td>
<?php } ?>
<?php } ?>
<td><?php echo $asset_ip_display; ?></td>
<?php if (isset($_GET['show_column']) && is_array($_GET['show_column']) && in_array('Mac_Address', $_GET['show_column'])) { ?>
<td><?php echo $asset_mac; ?></td>
<?php } ?>
<?php if (isset($_GET['show_column']) && is_array($_GET['show_column']) && in_array('Purchase_Date', $_GET['show_column'])) { ?>
<td><?php echo $asset_purchase_date_display; ?></td>
<?php } ?>
<?php if (isset($_GET['show_column']) && is_array($_GET['show_column']) && in_array('Install_Date', $_GET['show_column'])) { ?>
<td><?php echo $asset_install_date_display; ?></td>
<?php } ?>
<?php if (isset($_GET['show_column']) && is_array($_GET['show_column']) && in_array('Warranty_Expire', $_GET['show_column'])) { ?>
<td><?php echo $asset_warranty_expire_display; ?></td>
<?php } ?>
<?php if ($_GET['type'] !== 'network' && $_GET['type'] !== 'other' && $_GET['type'] !== 'server') { ?>
<td><?php echo $contact_name_display; ?></td>
<?php } ?>
<td>
<?php echo $location_name_display; ?>
<?php echo $asset_physical_location_display; ?>
</td>
<td><?php echo $asset_status; ?></td>
<?php if (!$client_url) { ?>
<td><a href="assets.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
<?php } ?>
<td class="text-center">
<div class="btn-group">
<?php if ( !empty($asset_uri) || !empty($asset_uri_2) || !empty($asset_uri_client)) { ?>
<div class="dropdown dropleft text-center">
<button class="btn btn-default btn-sm" type="button" data-toggle="dropdown">
<i class="fa fa-fw fa-external-link-alt"></i>
</button>
<div class="dropdown-menu">
<?php if ($asset_uri) { ?>
<a href="<?php echo $asset_uri; ?>" alt="<?php echo $asset_uri; ?>" target="_blank" class="dropdown-item" >
<i class="fa fa-fw fa-external-link-alt mr-2"></i><?php echo truncate($asset_uri,40); ?>
</a>
<?php } ?>
<?php if ($asset_uri_2) { ?>
<div class="dropdown-divider"></div>
<a href="<?php echo $asset_uri_2; ?>" target="_blank" class="dropdown-item" >
<i class="fa fa-fw fa-external-link-alt mr-2"></i><?php echo truncate($asset_uri_2,40); ?>
</a>
<?php } ?>
<?php if ($asset_uri_client) { ?>
<div class="dropdown-divider"></div>
<a href="<?php echo $asset_uri_client; ?>" target="_blank" class="dropdown-item" >
<i class="fa fa-fw fa-external-link-alt mr-2"></i>Client URI: <?php echo truncate($asset_uri_client,40); ?>
</a>
<?php } ?>
</div>
</div>
<?php } ?>
<div class="dropdown dropleft text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown"><i class="fas fa-ellipsis-h"></i></button>
<div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/asset/asset_edit.php?id=<?= $asset_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit
</a>
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/asset/asset_copy.php?id=<?= $asset_id ?>">
<i class="fas fa-fw fa-copy mr-2"></i>Copy
</a>
<?php if ($session_user_role > 2) { ?>
<?php if ($asset_archived_at) { ?>
<a class="dropdown-item text-info" href="post.php?unarchive_asset=<?php echo $asset_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-redo mr-2"></i>Unarchive
</a>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_asset=<?php echo $asset_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</a>
<?php } else { ?>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_asset=<?php echo $asset_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</a>
<?php } ?>
<?php } ?>
</div>
</div>
</div>
</td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
<?php
if ($client_url) {
require_once "modals/asset/asset_bulk_assign_contact.php";
require_once "modals/asset/asset_bulk_assign_location.php";
}
?>
<?php require_once "modals/asset/asset_bulk_assign_physical_location.php"; ?>
<?php require_once "modals/asset/asset_bulk_transfer_client.php"; ?>
<?php require_once "modals/asset/asset_bulk_edit_status.php"; ?>
<?php require_once "modals/asset/asset_bulk_add_ticket.php"; ?>
</form>
<?php require_once "../includes/filter_footer.php"; ?>
</div>
</div>
<script src="../js/bulk_actions.js"></script>
<!-- JSON Autocomplete / type ahead -->
<link rel="stylesheet" href="../plugins/jquery-ui/jquery-ui.min.css">
<script src="../plugins/jquery-ui/jquery-ui.min.js"></script>
<script>
$(function() {
var operatingSystems = <?php echo $json_os; ?>;
$("#os").autocomplete({
source: operatingSystems, // Should be an array of objects with 'label' and 'value'
select: function(event, ui) {
$("#os").val(ui.item.label); // Set the input field value to the selected label
return false;
}
});
});
</script>
<?php
require_once "modals/asset/asset_add.php";
require_once "modals/asset/asset_export.php";
if ($client_url) {
require_once "modals/asset/asset_import.php";
}
require_once "../includes/footer.php";

72
agent/blank.php Normal file
View File

@@ -0,0 +1,72 @@
<?php require_once "includes/inc_all.php"; ?>
<!-- Breadcrumbs-->
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="index.html">Dashboard</a>
</li>
<li class="breadcrumb-item active">Blank Page</li>
</ol>
<!-- Page Content -->
<h1>Blank Page</h1>
<hr>
<p>This is a great starting point for new custom pages.</p>
<h1><?php echo $session_user_role; ?></h1>
<?php validateAdminRole(); ?>
<?php
$start_date = date('Y') . "-10-10";
echo "<H1>$start_date</H1>";
echo "<H2>User Agent</H2>";
echo getUserAgent();
?>
<br>
<input type="tel" name="phone" id="phone">
<div class="form-group">
<label>Minimal</label>
<select class="form-control select2 select2-hidden-accessible" style="width: 100%;" data-select2-id="1" tabindex="-1" aria-hidden="true">
<option selected="selected" data-select2-id="3">Alabama</option>
<option data-select2-id="35">Alaska</option>
<option data-select2-id="36">California</option>
<option data-select2-id="37">Delaware</option>
<option data-select2-id="38">Tennessee</option>
<option data-select2-id="39">Texas</option>
<option data-select2-id="40">Washington</option>
</select><span class="select2 select2-container select2-container--default select2-container--below" dir="ltr" data-select2-id="2" style="width: 100%;"><span class="selection"><span class="select2-selection select2-selection--single" role="combobox" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-disabled="false" aria-labelledby="select2-nbex-container"><span class="select2-selection__rendered" id="select2-nbex-container" role="textbox" aria-readonly="true" title="Alabama">Alabama</span><span class="select2-selection__arrow" role="presentation"><b role="presentation"></b></span></span></span><span class="dropdown-wrapper" aria-hidden="true"></span></span>
</div>
<dl>
<dt>Requester</dt>
<dd>Sam Adams</dd>
<dt>Created</dt>
<dd><time datetime="2024-04-11T17:52:30+00:00" title="2024-04-11 13:52" data-datetime="calendar">Today at 13:52</time></dd>
<dt>Last activity</dt>
<dd><time datetime="2024-04-11T18:08:55+00:00" title="2024-04-11 14:08" data-datetime="calendar">Today at 14:08</time></dd>
</dl>
<?php echo randomString(100); ?>
<br>
<textarea class="tinymceTest"></textarea>
<textarea class="tinymce"></textarea>
<textarea class="tinymceTicket"></textarea>
<?php
// show the current Date and Time
$date_time = date('Y-m-d H:i:s');
echo "Current Date and Time: <strong>$date_time</strong>";
?>
<script>toastr.success('Have Fun Wozz!!')</script>
<?php require_once "../includes/footer.php";

113
agent/budget.php Normal file
View File

@@ -0,0 +1,113 @@
<?php
require_once "includes/inc_all.php";
// Perms
enforceUserPermission('module_financial');
// Fetch categories
$query = "SELECT category_id, category_name FROM categories WHERE category_type ='Expense' AND category_archived_at IS NULL";
$result = mysqli_query($mysqli, $query);
$categories = [];
while($row = mysqli_fetch_assoc($result)) {
$categories[] = $row;
}
// Fetch years with budget
$query = "SELECT DISTINCT budget_year FROM budget ORDER BY budget_year ASC";
$result = mysqli_query($mysqli, $query);
$years = [];
while ($row = mysqli_fetch_assoc($result)) {
$years[] = $row['budget_year'];
}
// Fetch current year budgets
$currentYear = date("Y");
if (isset($_GET['year'])) {
$currentYear = intval($_GET['year']);
}
$query = "SELECT * FROM budget WHERE budget_year = $currentYear";
$result = mysqli_query($mysqli, $query);
$budgets = [];
while ($row = mysqli_fetch_assoc($result)) {
$budgets[] = $row;
}
$months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
$columnTotals = array_fill(0, 12, 0);
$grandTotal = 0;
?>
<div class="card card-dark">
<div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fas fa-fw fa-balance-scale mr-2"></i>Budget for <span id="currentYear"><?php echo $currentYear; ?></span></h3>
<div class="card-tools">
<a href="budget_edit.php" class="btn btn-primary">
<i class="fas fa-edit mr-2"></i>Edit Budget
</a>
</div>
</div>
<div class="card-body">
<form id="yearForm" method="GET" action="budget.php">
<div class="form-group">
<select class="form-control" name="year" id="yearSelect" onchange="submit();">
<?php foreach ($years as $year): ?>
<option value="<?php echo $year; ?>" <?php if ($year == $currentYear) { echo 'selected'; } ?>><?php echo $year; ?></option>
<?php endforeach; ?>
</select>
</div>
</form>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Expense</th>
<?php foreach ($months as $month): ?>
<th><?php echo $month; ?></th>
<?php endforeach; ?>
<th>Total</th>
</tr>
</thead>
<tbody>
<?php foreach ($categories as $category): ?>
<tr>
<td><?php echo nullable_htmlentities($category['category_name']); ?></td>
<?php
$rowTotal = 0;
foreach ($months as $index => $month):
$amount = getBudgetAmount($budgets, $category['category_id'], $index + 1);
$rowTotal += $amount;
$columnTotals[$index] += $amount;
?>
<td><?php echo $amount; ?></td>
<?php endforeach; ?>
<td><?php echo $rowTotal; ?></td>
</tr>
<?php
$grandTotal += $rowTotal;
endforeach; ?>
</tbody>
<tfoot>
<tr>
<th>Total</th>
<?php foreach ($columnTotals as $total): ?>
<th><?php echo $total; ?></th>
<?php endforeach; ?>
<th><?php echo $grandTotal; ?></th>
</tr>
</tfoot>
</table>
</div>
<?php
function getBudgetAmount($budgets, $categoryId, $month) {
foreach ($budgets as $budget) {
if ($budget['budget_category_id'] == $categoryId && $budget['budget_month'] == $month) {
return intval($budget['budget_amount']);
}
}
return 0;
}
require_once "../includes/footer.php";
?>

114
agent/budget_edit.php Normal file
View File

@@ -0,0 +1,114 @@
<?php
require_once "includes/inc_all.php";
enforceUserPermission('module_financial', 2);
// Fetch categories
$query = "SELECT category_id, category_name FROM categories WHERE category_type ='Expense' AND category_archived_at IS NULL";
$result = mysqli_query($mysqli, $query);
$categories = [];
while($row = mysqli_fetch_assoc($result)) {
$categories[] = $row;
}
// Fetch current year budgets
$currentYear = date("Y");
if(isset($_GET['year'])) {
$currentYear = intval($_GET['year']);
}
$query = "SELECT * FROM budget WHERE budget_year = $currentYear";
$result = mysqli_query($mysqli, $query);
$budgets = [];
while($row = mysqli_fetch_assoc($result)) {
$budgets[] = $row;
}
$months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
$columnTotals = array_fill(0, 12, 0);
$grandTotal = 0;
?>
<div class="card card-dark">
<div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fas fa-fw fa-balance-scale mr-2"></i>Editing Budget for <span id="currentYear"><?php echo $currentYear; ?></span></h3>
<div class="card-tools">
<a href="budget.php" class="btn btn-default text-dark">
<i class="fas fa-eye mr-2"></i>View Budget
</a>
<button type="submit" name="save_budget" form="budgetForm" class="btn btn-primary"><i class="fas fa-fw fa-check mr-2"></i>Save Budget</button>
<button type="submit" name="delete_budget" form="budgetForm" class="btn btn-danger"><i class="fas fa-fw fa-trash mr-2"></i>Delete Budget</button>
</div>
</div>
<div class="card-body">
<form id="yearForm" method="GET" action="budget.php">
<div class="form-group">
<select class="form-control" name="year" id="yearSelect" onchange="submit();">
<?php for ($i = $currentYear - 10; $i <= $currentYear + 5; $i++): ?>
<option value="<?php echo $i; ?>" <?php if ($i == $currentYear) echo 'selected'; ?>><?php echo $i; ?></option>
<?php endfor; ?>
</select>
</div>
</form>
<form id="budgetForm" method="POST" action="post.php">
<input type="hidden" name="year" value="<?php echo $currentYear; ?>">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Expense</th>
<?php foreach ($months as $month): ?>
<th><?php echo $month; ?></th>
<?php endforeach; ?>
<th>Total</th>
</tr>
</thead>
<tbody>
<?php foreach ($categories as $category): ?>
<tr>
<td><?php echo nullable_htmlentities($category['category_name']); ?></td>
<?php
$rowTotal = 0;
foreach ($months as $index => $month):
$amount = getBudgetAmount($budgets, $category['category_id'], $index + 1);
$rowTotal += $amount;
$columnTotals[$index] += $amount;
?>
<td><input type='text' inputmode='numeric' pattern='[0-9]*' class="form-control" name="budget[<?php echo intval($category['category_id']); ?>][<?php echo $index + 1; ?>]" value="<?php echo $amount; ?>"></td>
<?php endforeach; ?>
<td><?php echo $rowTotal; ?></td>
</tr>
<?php
$grandTotal += $rowTotal;
endforeach; ?>
</tbody>
<tfoot>
<tr>
<th>Total</th>
<?php foreach ($columnTotals as $total): ?>
<th><?php echo $total; ?></th>
<?php endforeach; ?>
<th><?php echo $grandTotal; ?></th>
</tr>
</tfoot>
</table>
</form>
</div>
</div>
<?php
function getBudgetAmount($budgets, $categoryId, $month) {
foreach ($budgets as $budget) {
if ($budget['budget_category_id'] == $categoryId && $budget['budget_month'] == $month) {
return intval($budget['budget_amount']);
}
}
return 0;
}
require_once "../includes/footer.php";
?>

367
agent/calendar.php Normal file
View File

@@ -0,0 +1,367 @@
<?php
// If client_id is in URI then show client Side Bar and client header
if (isset($_GET['client_id'])) {
require_once "includes/inc_all_client.php";
$client_event_query = "WHERE event_client_id = $client_id";
$client_query = "WHERE 1 = 1 AND client_id = $client_id";
$client_url = "&client_id=$client_id";
} else {
require_once "includes/inc_all.php";
$client_event_query = '';
$client_query = 'WHERE 1 = 1';
$client_url = '';
}
if (isset($_GET['calendar_id'])) {
$calendar_selected_id = intval($_GET['calendar_id']);
}
?>
<!-- So that when hovering over a created event it turns into a hand instead of cursor -->
<style>
.fc-event {
cursor: pointer;
}
</style>
<div class="row">
<div class="col-md-3">
<div class="card">
<div class="card-header py-2">
<h3 class="card-title mt-1">Calendars</h3>
<div class="card-tools">
<button type="button" class="btn btn-dark btn-sm" data-toggle="modal" data-target="#addCalendarModal"><i class="fas fa-plus"></i></button>
</div>
</div>
<div class="card-body">
<form>
<?php
$sql = mysqli_query($mysqli, "SELECT * FROM calendars");
while ($row = mysqli_fetch_array($sql)) {
$calendar_id = intval($row['calendar_id']);
$calendar_name = nullable_htmlentities($row['calendar_name']);
$calendar_color = nullable_htmlentities($row['calendar_color']);
?>
<div class="form-group">
<i class="fas fa-fw fa-circle mr-2" style="color:<?php echo $calendar_color; ?>;"></i><?php echo $calendar_name; ?>
<button type="button" class="btn btn-link btn-sm float-right ajax-modal"
data-modal-url="modals/calendar/calendar_edit.php?id=<?= $calendar_id ?>">
<i class="fas fa-fw fa-pencil-alt text-secondary"></i>
</button>
</div>
<?php
}
?>
</form>
</div>
</div>
<div class="card">
<div class="card-header py-2">
<h3 class="card-title mt-1">System Calendars</h3>
<div class="card-tools">
<button type="button" class="btn btn-dark btn-sm"><i class="fas fa-eye"></i></button>
</div>
</div>
<div class="card-body">
</div>
</div>
</div>
<div class="col-md-9">
<div class="card">
<div id='calendar'></div>
</div>
</div>
</div>
<?php
require_once "modals/calendar/calendar_event_add.php";
require_once "modals/calendar/calendar_add.php";
//loop through IDs and create a modal for each
$sql = mysqli_query($mysqli, "SELECT * FROM calendar_events LEFT JOIN calendars ON event_calendar_id = calendar_id $client_event_query");
while ($row = mysqli_fetch_array($sql)) {
$event_id = intval($row['event_id']);
$event_title = nullable_htmlentities($row['event_title']);
$event_description = nullable_htmlentities($row['event_description']);
$event_location = nullable_htmlentities($row['event_location']);
$event_start = nullable_htmlentities($row['event_start']);
$event_end = nullable_htmlentities($row['event_end']);
$event_repeat = nullable_htmlentities($row['event_repeat']);
$calendar_id = intval($row['calendar_id']);
$calendar_name = nullable_htmlentities($row['calendar_name']);
$calendar_color = nullable_htmlentities($row['calendar_color']);
$client_id = intval($row['event_client_id']);
}
?>
<?php require_once "../includes/footer.php";
?>
<script src='../plugins/fullcalendar/dist/index.global.js'></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
themeSystem: 'bootstrap',
defaultView: 'dayGridMonth',
customButtons: {
newEvent: {
text: 'New Event',
bootstrapFontAwesome: 'fas fa-plus',
click: function() {
$("#addCalendarEventModal").modal();
}
}
},
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth newEvent'
},
<?php if (!$session_mobile) {
?>aspectRatio: 2.5,
<?php } else { ?>
aspectRatio: 0.7,
<?php } ?>
navLinks: true, // can click day/week names to navigate views
selectable: true,
height: '90vh',
selectMirror: true,
eventClick: function(editEvent) {
var eventId = editEvent.event.id;
var $link = $('<a>', {
href: '#',
'class': 'ajax-modal',
'data-modal-url': 'modals/calendar/calendar_event_edit.php?<?php echo $client_url; ?>&id=' + eventId
});
$('body').append($link); // Append to the body
$link.trigger('click'); // Trigger the modal
$link.remove(); // Cleanup
},
dayMaxEvents: true, // allow "more" link when too many events
views: {
timeGrid: {
dayMaxEventRows: 3, // adjust to 6 only for timeGridWeek/timeGridDay
expandRows: true,
nowIndicator: true,
eventMaxStack: 1,
},
dayGrid: {
dayMaxEvents: 3, // adjust to 6 only for timeGridWeek/timeGridDay
expandRows: true,
},
},
events: [
<?php
$sql = mysqli_query($mysqli, "SELECT * FROM calendar_events LEFT JOIN calendars ON event_calendar_id = calendar_id $client_event_query");
while ($row = mysqli_fetch_array($sql)) {
$event_id = intval($row['event_id']);
$event_title = json_encode($row['event_title']);
$event_start = json_encode($row['event_start']);
$event_end = json_encode($row['event_end']);
$calendar_id = intval($row['calendar_id']);
$calendar_name = json_encode($row['calendar_name']);
$calendar_color = json_encode($row['calendar_color']);
echo "{ id: $event_id, title: $event_title, start: $event_start, end: $event_end, color: $calendar_color },";
}
//Invoices Created
$sql = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN invoices ON client_id = invoice_client_id $client_query");
while ($row = mysqli_fetch_array($sql)) {
$event_id = intval($row['invoice_id']);
$scope = strval($row['invoice_scope']);
if (empty($scope)) {
$scope = "Not Set";
}
$event_title = json_encode($row['invoice_prefix'] . $row['invoice_number'] . " created -scope: " . $scope);
$event_start = json_encode($row['invoice_date']);
echo "{ id: $event_id, title: $event_title, start: $event_start, display: 'list-item', color: 'blue', url: 'invoice.php?invoice_id=$event_id$client_url' },";
}
//Quotes Created
$sql = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN quotes ON client_id = quote_client_id $client_query");
while ($row = mysqli_fetch_array($sql)) {
$event_id = intval($row['quote_id']);
$event_title = json_encode($row['quote_prefix'] . $row['quote_number'] . " " . $row['quote_scope']);
$event_start = json_encode($row['quote_date']);
echo "{ id: $event_id, title: $event_title, start: $event_start, display: 'list-item', color: 'purple', url: 'quote.php?quote_id=$event_id$client_url' },";
}
//Tickets Created
$sql = mysqli_query($mysqli, "SELECT * FROM clients
LEFT JOIN tickets ON client_id = ticket_client_id
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
LEFT JOIN users ON ticket_assigned_to = user_id
$client_query"
);
while ($row = mysqli_fetch_array($sql)) {
$event_id = intval($row['ticket_id']);
$ticket_status = intval($row['ticket_status']);
$ticket_status_name = strval($row['ticket_status_name']);
$username = $row['user_name'];
if (empty($username)) {
$username = "";
} else {
//Limit to characters and add ...
$username = "[". substr($row['user_name'], 0, 9) . "...]";
}
$event_title = json_encode($row['ticket_prefix'] . $row['ticket_number'] . " created - " . $row['ticket_subject'] . " " . $username . "{" . $ticket_status_name . "}");
$event_start = json_encode($row['ticket_created_at']);
if ($ticket_status == 1) {
$event_color = "red";
} elseif ($ticket_status == 2) {
$event_color = "blue";
} elseif ($ticket_status == 3) {
$event_color = "grey";
} else {
$event_color = "black";
}
echo "{ id: $event_id, title: $event_title, start: $event_start, color: '$event_color', url: 'ticket.php?ticket_id=$event_id$client_url' },";
}
// Recurring Tickets
$sql = mysqli_query($mysqli, "SELECT * FROM clients
LEFT JOIN recurring_tickets ON client_id = recurring_ticket_client_id
LEFT JOIN users ON recurring_ticket_assigned_to = user_id
$client_query"
);
while ($row = mysqli_fetch_array($sql)) {
$event_id = intval($row['recurring_ticket_id']);
$client_id = intval($row['client_id']);
$username = $row['user_name'];
$frequency = $row['recurring_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['recurring_ticket_subject'] . " " . $username);
$event_start = json_encode($row['recurring_ticket_next_run']);
echo "{ id: $event_id, title: $event_title, start: $event_start, color: '$event_color', url: 'recurring_tickets.php?client_id=$client_id$client_url' },";
}
//Tickets Scheduled
$sql = mysqli_query($mysqli, "SELECT * FROM clients
LEFT JOIN tickets ON client_id = ticket_client_id
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
LEFT JOIN users ON ticket_assigned_to = user_id
$client_query AND ticket_schedule IS NOT NULL"
);
while ($row = mysqli_fetch_array($sql)) {
$event_id = intval($row['ticket_id']);
$username = $row['user_name'];
if (empty($username)) {
$username = "";
} else {
//Limit to characters and add ...
$username = substr($row['user_name'], 0, 9) . "...";
}
if (strtotime($row['ticket_schedule']) < time()) {
if (!empty($row['ticket_schedule'])) {
$event_color = "red";
} else {
$event_color = "green";
}
} else {
$event_color = "grey";
}
$ticket_status = strval($row['ticket_status_name']);
$event_title = json_encode($row['ticket_prefix'] . $row['ticket_number'] . " scheduled - " . $row['ticket_subject'] . " [" . $username . "]{" . $ticket_status . "}");
$event_start = json_encode($row['ticket_schedule']);
echo "{ id: $event_id, title: $event_title, start: $event_start, color: '$event_color', url: 'ticket.php?ticket_id=$event_id$client_url' },";
}
//Vendors Added Created
$sql = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN vendors ON client_id = vendor_client_id $client_query");
while ($row = mysqli_fetch_array($sql)) {
$event_id = intval($row['vendor_id']);
$client_id = intval($row['client_id']);
$event_title = json_encode("Vendor : '" . $row['vendor_name'] . "' created");
$event_start = json_encode($row['vendor_created_at']);
echo "{ id: $event_id, title: $event_title, start: $event_start, color: 'brown', url: 'vendors.php?$client_url' },";
}
if (!isset($_GET['client_id'])) {
//Clients Added
$sql = mysqli_query($mysqli, "SELECT * FROM clients");
while ($row = mysqli_fetch_array($sql)) {
$event_id = intval($row['client_id']);
$event_title = json_encode("Client: '" . $row['client_name'] . "' created");
$event_start = json_encode($row['client_created_at']);
echo "{ id: $event_id, title: $event_title, start: $event_start, color: 'brown', url: 'client_overview.php?client_id=$event_id' },";
}
}
?>
],
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();
});
</script>
<!-- Automatically set new event end date to 1 hr after start date -->
<script>
// Function - called when user leaves field (onblur)
function updateIncrementEndTime() {
// Get the start date
let start = document.getElementById("event_add_start").value;
// Create a date object
let new_end = new Date(start);
// Get the time zone offset in minutes, convert it to milliseconds
let offsetInMilliseconds = new_end.getTimezoneOffset() * 60 * 1000;
// Adjust the date by the time zone offset before adding an hour
new_end = new Date(new_end.getTime() - offsetInMilliseconds);
// Set the end date to 1 hr in the future
new_end.setHours(new_end.getHours() + 1);
// Get the date back as a string, with the milliseconds trimmed off
new_end = new_end.toISOString().replace(/.\d+Z$/g, "");
// Update the end date field
document.getElementById("event_add_end").value = new_end;
}
</script>

313
agent/certificates.php Normal file
View File

@@ -0,0 +1,313 @@
<?php
// Default Column Sortby Filter
$sort = "certificate_name";
$order = "ASC";
// If client_id is in URI then show client Side Bar and client header
if (isset($_GET['client_id'])) {
require_once "includes/inc_all_client.php";
$client_query = "AND certificate_client_id = $client_id";
$client_url = "client_id=$client_id&";
// Overide Filter Header Archived
if (isset($_GET['archived']) && $_GET['archived'] == 1) {
$archived = 1;
$archive_query = "certificate_archived_at IS NOT NULL";
} else {
$archived = 0;
$archive_query = "certificate_archived_at IS NULL";
}
} else {
require_once "includes/inc_client_overview_all.php";
$client_query = '';
$client_url = '';
// Overide Filter Header Archived
if (isset($_GET['archived']) && $_GET['archived'] == 1) {
$archived = 1;
$archive_query = "(client_archived_at IS NOT NULL OR certificate_archived_at IS NOT NULL)";
} else {
$archived = 0;
$archive_query = "(client_archived_at IS NULL AND certificate_archived_at IS NULL)";
}
}
// Perms
enforceUserPermission('module_support');
if (!$client_url) {
// Client Filter
if (isset($_GET['client']) & !empty($_GET['client'])) {
$client_query = 'AND (certificate_client_id = ' . intval($_GET['client']) . ')';
$client = intval($_GET['client']);
} else {
// Default - any
$client_query = '';
$client = '';
}
}
$sql = mysqli_query($mysqli, "SELECT SQL_CALC_FOUND_ROWS * FROM certificates
LEFT JOIN clients ON client_id = certificate_client_id
WHERE $archive_query
AND (certificate_name LIKE '%$q%' OR certificate_domain LIKE '%$q%' OR certificate_issued_by LIKE '%$q%' OR client_name LIKE '%$q%')
$access_permission_query
$client_query
ORDER BY $sort $order LIMIT $record_from, $record_to"
);
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?>
<div class="card card-dark">
<div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fas fa-fw fa-lock mr-2"></i>Certificates</h3>
<div class="card-tools">
<div class="btn-group">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addCertificateModal"><i class="fas fa-plus mr-2"></i>New Certificate</button>
<?php if ($num_rows[0] > 0) { ?>
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#exportCertificateModal">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
</div>
<?php } ?>
</div>
</div>
</div>
<div class="card-body">
<form autocomplete="off">
<?php if ($client_url) { ?>
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<?php } ?>
<input type="hidden" name="archived" value="<?php echo $archived; ?>">
<div class="row">
<div class="col-md-4">
<div class="input-group mb-3 mb-md-0">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search Certificates">
<div class="input-group-append">
<button class="btn btn-dark"><i class="fa fa-search"></i></button>
</div>
</div>
</div>
<?php if ($client_url) { ?>
<div class="col-md-2"></div>
<?php } else { ?>
<div class="col-md-2">
<div class="input-group">
<select class="form-control select2" name="client" onchange="this.form.submit()">
<option value="" <?php if ($client == "") { echo "selected"; } ?>>- All Clients -</option>
<?php
$sql_clients_filter = mysqli_query($mysqli, "
SELECT DISTINCT client_id, client_name
FROM clients
JOIN certificates ON certificate_client_id = client_id
WHERE $archive_query
$access_permission_query
ORDER BY client_name ASC
");
while ($row = mysqli_fetch_array($sql_clients_filter)) {
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
?>
<option <?php if ($client == $client_id) { echo "selected"; } ?> value="<?php echo $client_id; ?>"><?php echo $client_name; ?></option>
<?php
}
?>
</select>
</div>
</div>
<?php } ?>
<div class="col-md-6">
<div class="btn-group float-right">
<a href="?<?php echo $client_url; ?>archived=<?php if($archived == 1){ echo 0; } else { echo 1; } ?>"
class="btn btn-<?php if($archived == 1){ echo "primary"; } else { echo "default"; } ?>">
<i class="fa fa-fw fa-archive mr-2"></i>Archived
</a>
<div class="dropdown ml-2" id="bulkActionButton" hidden>
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">
<i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>)
</button>
<div class="dropdown-menu">
<button class="dropdown-item text-danger text-bold"
type="submit" form="bulkActions" name="bulk_delete_certificates">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</button>
</div>
</div>
</div>
</div>
</div>
</form>
<hr>
<div class="table-responsive-sm">
<form id="bulkActions" action="post.php" method="post">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<table class="table table-striped table-borderless table-hover">
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
<tr>
<td class="pr-0">
<div class="form-check">
<input class="form-check-input" id="selectAllCheckbox" type="checkbox" onclick="checkAll(this)">
</div>
</td>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=certificate_name&order=<?php echo $disp; ?>">
Name <?php if ($sort == 'certificate_name') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=certificate_domain&order=<?php echo $disp; ?>">
Domain <?php if ($sort == 'certificate_domain') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=certificate_issued_by&order=<?php echo $disp; ?>">
Issued By <?php if ($sort == 'certificate_issued_by') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=certificate_expire&order=<?php echo $disp; ?>">
Expire <?php if ($sort == 'certificate_expire') { echo $order_icon; } ?>
</a>
</th>
<?php if (!$client_url) { ?>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=client_name&order=<?php echo $disp; ?>">
Client <?php if ($sort == 'client_name') { echo $order_icon; } ?>
</a>
</th>
<?php } ?>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql)) {
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
$certificate_id = intval($row['certificate_id']);
$certificate_name = nullable_htmlentities($row['certificate_name']);
$certificate_description = nullable_htmlentities($row['certificate_description']);
$certificate_domain = nullable_htmlentities($row['certificate_domain']);
$certificate_issued_by = nullable_htmlentities($row['certificate_issued_by']);
$certificate_expire = nullable_htmlentities($row['certificate_expire']);
$certificate_created_at = nullable_htmlentities($row['certificate_created_at']);
$certificate_archived_at = nullable_htmlentities($row['certificate_archived_at']);
$certificate_expire_ago = timeAgo($certificate_expire);
// Convert the expiry date to a timestamp
$certificate_expire_timestamp = strtotime($row['certificate_expire']);
$current_timestamp = time(); // Get current timestamp
// Calculate the difference in days
$days_until_expiry = ($certificate_expire_timestamp - $current_timestamp) / (60 * 60 * 24);
// Determine the class based on the number of days until expiry
if ($days_until_expiry <= 0) {
$tr_class = "table-secondary";
} elseif ($days_until_expiry <= 1) {
$tr_class = "table-danger";
} elseif ($days_until_expiry <= 7) {
$tr_class = "table-warning";
} else {
$tr_class = '';
}
?>
<tr class="<?php echo $tr_class; ?>">
<td class="pr-0">
<div class="form-check">
<input class="form-check-input bulk-select" type="checkbox" name="certificate_ids[]" value="<?php echo $certificate_id ?>">
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
</div>
</td>
<td>
<a class="text-dark ajax-modal" href="#"
data-modal-url="modals/certificate/certificate_edit.php?<?= $client_url ?>&id=<?= $certificate_id ?>">
<div class="media">
<i class="fa fa-fw fa-2x fa-lock mr-3"></i>
<div class="media-body">
<div><?php echo $certificate_name; ?></div>
<div><small class="text-secondary"><?php echo $certificate_description; ?></small></div>
</div>
</div>
</a>
</td>
<td><?php echo $certificate_domain; ?></td>
<td><?php echo $certificate_issued_by; ?></td>
<td>
<div><?php echo $certificate_expire; ?></div>
<div><small><?php echo $certificate_expire_ago; ?></small></div>
</td>
<?php if (!$client_url) { ?>
<td><a href="certificates.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
<?php } ?>
<td>
<div class="dropdown dropleft text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i>
</button>
<div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/certificate/certificate_edit.php?<?= $client_url ?>&id=<?= $certificate_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit
</a>
<?php if ($session_user_role == 3) { ?>
<?php if ($certificate_archived_at) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-info confirm-link" href="post.php?unarchive_certificate=<?php echo $certificate_id; ?>">
<i class="fas fa-fw fa-redo mr-2"></i>Restore
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_certificate=<?php echo $certificate_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</a>
<?php } else { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_certificate=<?php echo $certificate_id; ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</a>
<?php } ?>
<?php } ?>
</div>
</div>
</td>
</tr>
<?php
}
?>
</tbody>
</table>
</form>
</div>
<?php require_once "../includes/filter_footer.php";
?>
</div>
</div>
<?php
require_once "modals/certificate/certificate_add.php";
require_once "modals/certificate/certificate_export.php";
?>
<script src="../js/bulk_actions.js"></script>
<script src="js/certificate_fetch_ssl.js"></script>
<?php require_once "../includes/footer.php";

130
agent/client_autopay.php Normal file
View File

@@ -0,0 +1,130 @@
<?php
require_once "includes/inc_all_client.php";
// Perms
enforceUserPermission('module_sales');
// Initialize stripe
require_once 'plugins/stripe-php/init.php';
// Get Stripe vars
$stripe_vars = mysqli_fetch_array(mysqli_query($mysqli, "SELECT config_stripe_enable, config_stripe_publishable, config_stripe_secret FROM settings WHERE company_id = 1"));
$config_stripe_enable = intval($stripe_vars['config_stripe_enable']);
$config_stripe_publishable = nullable_htmlentities($stripe_vars['config_stripe_publishable']);
$config_stripe_secret = nullable_htmlentities($stripe_vars['config_stripe_secret']);
// Get client's StripeID from database
$stripe_client_details = mysqli_fetch_array(mysqli_query($mysqli, "SELECT * FROM client_stripe WHERE client_id = $client_id LIMIT 1"));
if ($stripe_client_details) {
$stripe_id = sanitizeInput($stripe_client_details['stripe_id']);
$stripe_pm = sanitizeInput($stripe_client_details['stripe_pm']);
}
// Stripe not enabled in settings
if (!$config_stripe_enable || !$config_stripe_publishable || !$config_stripe_secret) {
echo "Stripe payment error - Stripe is not enabled, please talk to your helpdesk for further information.";
include_once '../includes/footer.php';
exit();
}
?>
<div class="card card-dark">
<div class="card-header">
<h3 class="card-title"><i class="fa fa-redo-alt mr-2"></i>AutoPay</h3>
</div>
<div class="card-body">
<!-- Setup pt1: Stripe ID not found / auto-payment not configured -->
<?php if (!$stripe_client_details || empty($stripe_id)) { ?>
<b>Save card details</b><br>
In order to set up automatic payments, you must create a customer record in Stripe.<br>
First, you must authorize Stripe to store your card details for the purpose of automatic payment.
<br><br>
<div class="col-5">
<form action="post.php" method="POST">
<div class="form-group">
<div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="consent" name="consent" value="1" required>
<label for="consent" class="custom-control-label">
I grant consent for automatic payments
</label>
</div>
</div>
<div class="form-group">
<button type="submit" class="form-control btn-success" name="create_stripe_customer">Create Stripe Customer Record</button>
</div>
</form>
</div>
<?php }
// Setup pt2: Stripe ID found / payment may be configured -->
elseif (empty($stripe_pm)) { ?>
<b>Save card details</b><br>
Please add the payment details you would like to save.<br>
By adding payment details here, you grant consent for future automatic payments of invoices.<br><br>
<input type="hidden" id="stripe_publishable_key" value="<?php echo $config_stripe_publishable ?>">
<script src="https://js.stripe.com/v3/"></script>
<script src="js/autopay_setup_stripe.js"></script>
<div id="checkout">
<!-- Checkout will insert the payment form here -->
</div>
<?php }
// Manage the saved card
else { ?>
<b>Manage saved payment methods</b>
<?php
try {
// Initialize
$stripe = new \Stripe\StripeClient($config_stripe_secret);
// Get payment method info (last 4 digits etc)
$payment_method = $stripe->customers->retrievePaymentMethod(
$stripe_id,
$stripe_pm,
[]
);
} catch (Exception $e) {
$error = $e->getMessage();
error_log("Stripe payment error - encountered exception when fetching payment method info for $stripe_pm: $error");
logApp("Stripe", "error", "Exception when fetching payment method info for $stripe_pm: $error");
}
$card_name = nullable_htmlentities($payment_method->billing_details->name);
$card_brand = nullable_htmlentities($payment_method->card->display_brand);
$card_last4 = nullable_htmlentities($payment_method->card->last4);
$card_expires = nullable_htmlentities($payment_method->card->exp_month) . "/" . nullable_htmlentities($payment_method->card->exp_year);
?>
<ul><li><?php echo "$card_name - $card_brand card ending in $card_last4, expires $card_expires"; ?></li></ul>
<hr>
<b>Actions</b><br>
- <a href="post.php?stripe_remove_pm&pm=<?php echo $stripe_pm; ?>">Remove saved payment method</a>
<?php } ?>
</div>
</div>
</div>
<?php
require_once "../includes/footer.php";

704
agent/client_overview.php Normal file
View File

@@ -0,0 +1,704 @@
<?php
require_once "includes/inc_all_client.php";
$sql_recent_activities = mysqli_query(
$mysqli,
"SELECT * FROM logs
WHERE log_client_id = $client_id
ORDER BY log_created_at DESC
LIMIT 5"
);
$sql_important_contacts = mysqli_query(
$mysqli,
"SELECT * FROM contacts
WHERE contact_client_id = $client_id
AND (contact_important = 1
OR contact_billing = 1
OR contact_technical = 1
OR contact_primary = 1
)
AND contact_archived_at IS NULL
ORDER BY contact_primary DESC, contact_name DESC LIMIT 5"
);
$sql_recent_tickets = mysqli_query(
$mysqli,
"SELECT * FROM tickets
WHERE ticket_client_id = $client_id
ORDER BY ticket_created_at ASC
LIMIT 5"
);
$sql_recent_credentials = mysqli_query(
$mysqli,
"SELECT * FROM credentials
WHERE credential_client_id = $client_id
AND credential_archived_at IS NULL
ORDER BY credential_updated_at ASC
LIMIT 5"
);
$sql_shared_items = mysqli_query(
$mysqli,
"SELECT * FROM shared_items
WHERE item_client_id = $client_id
AND item_active = 1
ORDER BY item_created_at ASC
LIMIT 5"
);
/*
* EXPIRING/ACTION ITEMS
*/
// Stale Tickets
$sql_stale_tickets = mysqli_query(
$mysqli,
"SELECT * FROM tickets
WHERE ticket_client_id = $client_id
AND ticket_updated_at < CURRENT_DATE - INTERVAL 7 DAY
AND ticket_resolved_At IS NULL
AND ticket_closed_at IS NULL
ORDER BY ticket_updated_at ASC"
);
// 8 - 45 Day Warning
// Get Domains Expiring
$sql_domains_expiring = mysqli_query(
$mysqli,
"SELECT * FROM domains
WHERE domain_client_id = $client_id
AND domain_expire IS NOT NULL
AND domain_archived_at IS NULL
AND domain_expire > CURRENT_DATE
AND domain_expire < CURRENT_DATE + INTERVAL 45 DAY
ORDER BY domain_expire ASC"
);
// Get Certificates Expiring
$sql_certificates_expiring = mysqli_query(
$mysqli,
"SELECT * FROM certificates
WHERE certificate_client_id = $client_id
AND certificate_expire IS NOT NULL
AND certificate_archived_at IS NULL
AND certificate_expire > CURRENT_DATE
AND certificate_expire < CURRENT_DATE + INTERVAL 45 DAY
ORDER BY certificate_expire ASC"
);
// Get Licenses Expiring
$sql_licenses_expiring = mysqli_query(
$mysqli,
"SELECT * FROM software
WHERE software_client_id = $client_id
AND software_expire IS NOT NULL
AND software_archived_at IS NULL
AND software_expire > CURRENT_DATE
AND software_expire < CURRENT_DATE + INTERVAL 45 DAY
ORDER BY software_expire ASC"
);
// Get Asset Warranties Expiring
$sql_asset_warranties_expiring = mysqli_query(
$mysqli,
"SELECT * FROM assets
WHERE asset_client_id = $client_id
AND asset_warranty_expire IS NOT NULL
AND asset_archived_at IS NULL
AND asset_warranty_expire > CURRENT_DATE
AND asset_warranty_expire < CURRENT_DATE + INTERVAL 45 DAY
ORDER BY asset_warranty_expire ASC"
);
// Get Assets Retiring 7 Year
$sql_asset_retire = mysqli_query(
$mysqli,
"SELECT * FROM assets
WHERE asset_client_id = $client_id
AND asset_install_date IS NOT NULL
AND asset_archived_at IS NULL
AND asset_install_date + INTERVAL 7 YEAR > CURRENT_DATE
AND asset_install_date + INTERVAL 7 YEAR <= CURRENT_DATE + INTERVAL 45 DAY
ORDER BY asset_install_date ASC"
);
/*
* EXPIRED ITEMS
*/
// Get Domains Expired
$sql_domains_expired = mysqli_query(
$mysqli,
"SELECT * FROM domains
WHERE domain_client_id = $client_id
AND domain_expire IS NOT NULL
AND domain_archived_at IS NULL
AND domain_expire < CURRENT_DATE
ORDER BY domain_expire ASC"
);
// Get Certificates Expired
$sql_certificates_expired = mysqli_query(
$mysqli,
"SELECT * FROM certificates
WHERE certificate_client_id = $client_id
AND certificate_expire IS NOT NULL
AND certificate_archived_at IS NULL
AND certificate_expire < CURRENT_DATE
ORDER BY certificate_expire ASC"
);
// Get Licenses Expired
$sql_licenses_expired = mysqli_query(
$mysqli,
"SELECT * FROM software
WHERE software_client_id = $client_id
AND software_expire IS NOT NULL
AND software_archived_at IS NULL
AND software_expire < CURRENT_DATE
ORDER BY software_expire ASC"
);
// Get Asset Warranties Expired
$sql_asset_warranties_expired = mysqli_query(
$mysqli,
"SELECT * FROM assets
WHERE asset_client_id = $client_id
AND asset_warranty_expire IS NOT NULL
AND asset_archived_at IS NULL
AND asset_warranty_expire < CURRENT_DATE
ORDER BY asset_warranty_expire ASC"
);
// Get Retired Assets
$sql_asset_retired = mysqli_query(
$mysqli,
"SELECT * FROM assets
WHERE asset_client_id = $client_id
AND asset_install_date IS NOT NULL
AND asset_archived_at IS NULL
AND asset_install_date + INTERVAL 7 YEAR < CURRENT_DATE -- Assets retired (installed more than 7 years ago)
ORDER BY asset_install_date ASC"
);
?>
<div class="row">
<!-- Notes -->
<div class="col-md-8">
<div class="card card-dark mb-3">
<div class="card-header">
<h5 class="card-title"><i class="fa fa-fw fa-edit mr-2"></i>Quick Notes</h5>
</div>
<div class="card-body p-1">
<textarea class="form-control" rows=8 id="clientNotes" placeholder="Enter quick notes here" onblur="updateClientNotes(<?php echo $client_id ?>)"><?php echo $client_notes ?></textarea>
</div>
</div>
</div>
<div class="col-md-4">
<?php if (mysqli_num_rows($sql_important_contacts) > 0) { ?>
<div class="card card-dark mb-3">
<div class="card-header">
<h5 class="card-title"><i class="fa fa-fw fa-users mr-2"></i>Important Contacts</h5>
</div>
<div class="card-body p-2">
<table class="table table-borderless table-sm">
<?php
while ($row = mysqli_fetch_array($sql_important_contacts)) {
$contact_id = intval($row['contact_id']);
$contact_name = nullable_htmlentities($row['contact_name']);
$contact_title = nullable_htmlentities($row['contact_title']);
$contact_email = nullable_htmlentities($row['contact_email']);
$contact_phone_country_code = nullable_htmlentities($row['contact_phone_country_code']);
$contact_phone = nullable_htmlentities(formatPhoneNumber($row['contact_phone'], $contact_phone_country_code));
$contact_extension = nullable_htmlentities($row['contact_extension']);
$contact_mobile_country_code = nullable_htmlentities($row['contact_mobile_country_code']);
$contact_mobile = nullable_htmlentities(formatPhoneNumber($row['contact_mobile'], $contact_mobile_country_code));
$contact_photo = nullable_htmlentities($row['contact_photo']);
$contact_primary = intval($row['contact_primary']);
$contact_initials = initials($contact_name);
if ($contact_primary == 1) {
$contact_primary_display = "<small class='text-success'>Primary Contact</small>";
} else {
$contact_primary_display = false;
}
?>
<tr>
<td>
<a href="#" class="ajax-modal"
data-modal-size="lg"
data-modal-url="modals/contact/contact_details.php?id=<?= $contact_id ?>">
<div class="media">
<?php if ($contact_photo) { ?>
<span class="fa-stack fa-2x mr-2 text-center">
<img class="img-size-50 img-circle" src="<?php echo "../uploads/clients/$client_id/$contact_photo"; ?>">
</span>
<?php } else { ?>
<span class="fa-stack fa-2x mr-2">
<i class="fa fa-circle fa-stack-2x text-secondary"></i>
<span class="fa fa-stack-1x text-white"><?php echo $contact_initials; ?></span>
</span>
<?php } ?>
<div class="media-body">
<div class="text-bold"><?php echo $contact_name; ?></div>
<small class="text-secondary"><?php echo $contact_title; ?></small>
<div><?php echo $contact_primary_display; ?></div>
<?php
if (!empty($contact_tags_display)) { ?>
<div class="mt-1">
<?php echo $contact_tags_display; ?>
</div>
<?php } ?>
</div>
</div>
</a>
</td>
<td>
<?php if (!empty($contact_phone)) { ?>
<?php echo "<i class='fa fa-fw fa-phone text-secondary'></i> $contact_phone $contact_extension"; ?>
<?php } ?>
<?php if (!empty($contact_mobile)) { ?>
<br>
<div class="text-secondary"><i class='fa fa-fw fa-mobile-alt text-secondary'></i> <?php echo "$contact_mobile"; ?></div>
<?php } ?>
</td>
</tr>
<?php
}
?>
</table>
</div>
</div>
<?php } ?>
</div>
<?php if (mysqli_num_rows($sql_shared_items) > 0) { ?>
<div class="col-md-4">
<div class="card card-dark mb-3">
<div class="card-header">
<h5 class="card-title"><i class="fa fa-fw fa-share-square mr-2"></i>Shared Items</h5>
</div>
<div class="card-body p-2">
<table class="table table-borderless table-sm">
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_shared_items)) {
$item_id = intval($row['item_id']);
$item_active = nullable_htmlentities($row['item_active']);
$item_key = nullable_htmlentities($row['item_key']);
$item_type = nullable_htmlentities($row['item_type']);
$item_related_id = intval($row['item_related_id']);
$item_note = nullable_htmlentities($row['item_note']);
$item_recipient = nullable_htmlentities($row['item_recipient']);
$item_views = nullable_htmlentities($row['item_views']);
$item_view_limit = nullable_htmlentities($row['item_view_limit']);
$item_created_at = nullable_htmlentities($row['item_created_at']);
$item_expire_at = nullable_htmlentities($row['item_expire_at']);
$item_expire_at_human = timeAgo($row['item_expire_at']);
if ($item_type == 'Credential') {
$share_item_sql = mysqli_query($mysqli, "SELECT credential_name FROM credentials WHERE credential_id = $item_related_id AND credential_client_id = $client_id");
$share_item = mysqli_fetch_array($share_item_sql);
$item_name = nullable_htmlentities($share_item['credential_name']);
$item_icon = "fas fa-key";
} elseif ($item_type == 'Document') {
$share_item_sql = mysqli_query($mysqli, "SELECT document_name FROM documents WHERE document_id = $item_related_id AND document_client_id = $client_id");
$share_item = mysqli_fetch_array($share_item_sql);
$item_name = nullable_htmlentities($share_item['document_name']);
$item_icon = "fas fa-folder";
} elseif ($item_type == 'File') {
$share_item_sql = mysqli_query($mysqli, "SELECT file_name FROM files WHERE file_id = $item_related_id AND file_client_id = $client_id");
$share_item = mysqli_fetch_array($share_item_sql);
$item_name = nullable_htmlentities($share_item['file_name']);
$item_icon = "fas fa-paperclip";
}
?>
<tr>
<td title="<?php echo $item_type; ?>">
<i class="<?php echo $item_icon; ?> mr-2 text-secondary"></i><?php echo $item_name; ?>
</td>
<td>
<div>Views: <?php echo $item_views ?></div>
<div class="text-secondary"><?php echo $item_recipient; ?></div>
</td>
<td title="Expires at <?php echo $item_expire_at; ?>">Expires <?php echo $item_expire_at_human ?></td>
<td title="Deactivate Link">
<a class="text-danger confirm-link" href="post.php?deactivate_shared_item=<?php echo $item_id; ?>">
<i class="fas fa-fw fa-calendar-times mr-2"></i>
</a>
</td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
<?php } ?>
<?php
if (mysqli_num_rows($sql_domains_expiring) > 0
|| mysqli_num_rows($sql_certificates_expiring) > 0
|| mysqli_num_rows($sql_asset_warranties_expiring) > 0
|| mysqli_num_rows($sql_asset_retire) > 0
|| mysqli_num_rows($sql_licenses_expiring) > 0
) { ?>
<div class="col-md-4">
<div class="card card-dark mb-3">
<div class="card-header">
<h5 class="card-title"><i class="fa fa-fw fa-exclamation-triangle text-warning mr-2"></i>Expiring in the Next 45 Days</h5>
</div>
<div class="card-body p-2">
<?php
while ($row = mysqli_fetch_array($sql_domains_expiring)) {
$domain_id = intval($row['domain_id']);
$domain_name = nullable_htmlentities($row['domain_name']);
$domain_expire = nullable_htmlentities($row['domain_expire']);
$domain_expire_human = timeAgo($row['domain_expire']);
?>
<p class="mb-1">
<i class="fa fa-fw fa-globe text-secondary mr-1"></i>
<a href="domains.php?client_id=<?php echo $client_id; ?>&q=<?php echo $domain_name; ?>">Domain: <?php echo $domain_name; ?></a>
<span>-- <?php echo $domain_expire; ?> (<?php echo $domain_expire_human; ?>)</span>
</p>
<?php
}
?>
<?php
while ($row = mysqli_fetch_array($sql_certificates_expiring)) {
$certificate_id = intval($row['certificate_id']);
$certificate_name = nullable_htmlentities($row['certificate_name']);
$certificate_expire = nullable_htmlentities($row['certificate_expire']);
$certificate_expire_human = timeAgo($row['certificate_expire']);
?>
<p class="mb-1">
<i class="fa fa-fw fa-lock text-secondary mr-1"></i>
<a href="certificates.php?client_id=<?php echo $client_id; ?>&q=<?php echo $certificate_name; ?>">Certificate: <?php echo $certificate_name; ?></a>
<span>-- <?php echo $certificate_expire; ?> (<?php echo $certificate_expire_human; ?>)</span>
</p>
<?php
}
?>
<?php
while ($row = mysqli_fetch_array($sql_asset_warranties_expiring)) {
$asset_id = intval($row['asset_id']);
$asset_name = nullable_htmlentities($row['asset_name']);
$asset_warranty_expire = nullable_htmlentities($row['asset_warranty_expire']);
$asset_warranty_expire_human = timeAgo($row['asset_warranty_expire']);
?>
<p class="mb-1">
<i class="fa fa-fw fa-laptop text-secondary mr-1"></i>
<a href="asset_details.php?client_id=<?php echo $client_id; ?>&asset_id=<?php echo $asset_id; ?>">Asset Warranty: <?php echo $asset_name; ?></a>
<span>-- <?php echo $asset_warranty_expire; ?> (<?php echo $asset_warranty_expire_human; ?>)</span>
</p>
<?php
}
?>
<?php
while ($row = mysqli_fetch_array($sql_asset_retire)) {
$asset_id = intval($row['asset_id']);
$asset_name = nullable_htmlentities($row['asset_name']);
$asset_install_date = nullable_htmlentities($row['asset_install_date']);
$asset_install_date_human = timeAgo($row['asset_install_date']);
?>
<p class="mb-1">
<i class="fa fa-fw fa-laptop text-secondary mr-1"></i>
<a href="asset_details.php?client_id=<?php echo $client_id; ?>&asset_id=<?php echo $asset_id; ?>">Asset Retire: <?php echo $asset_name; ?></a>
<span>-- <?php echo $asset_install_date; ?> (<?php echo $asset_install_date_human; ?>)</span>
</p>
<?php
}
?>
<?php
while ($row = mysqli_fetch_array($sql_licenses_expiring)) {
$software_id = intval($row['software_id']);
$software_name = nullable_htmlentities($row['software_name']);
$software_expire = nullable_htmlentities($row['software_expire']);
$software_expire_human = timeAgo($row['software_expire']);
?>
<p class="mb-1">
<i class="fa fa-fw fa-cube text-secondary mr-1"></i>
<a href="software.php?client_id=<?php echo $client_id; ?>&q=<?php echo $software_name; ?>">License: <?php echo $software_name; ?></a>
<span>-- <?php echo $software_expire; ?> (<?php echo $software_expire_human; ?>)</span>
</p>
<?php
}
?>
</div>
</div>
</div>
<?php } ?>
<?php
if (mysqli_num_rows($sql_domains_expired) > 0
|| mysqli_num_rows($sql_certificates_expired) > 0
|| mysqli_num_rows($sql_asset_warranties_expired) > 0
|| mysqli_num_rows($sql_asset_retired) > 0
|| mysqli_num_rows($sql_licenses_expired) > 0
)
{ ?>
<div class="col-md-4">
<div class="card card-dark mb-3">
<div class="card-header">
<h5 class="card-title"><i class="fa fa-fw fa-exclamation-triangle text-danger mr-2"></i>Expired</h5>
</div>
<div class="card-body p-2">
<?php
while ($row = mysqli_fetch_array($sql_domains_expired)) {
$domain_id = intval($row['domain_id']);
$domain_name = nullable_htmlentities($row['domain_name']);
$domain_expire = nullable_htmlentities($row['domain_expire']);
$domain_expire_human = timeAgo($row['domain_expire']);
?>
<p class="mb-1">
<i class="fa fa-fw fa-globe text-secondary mr-1"></i>
<a href="domains.php?client_id=<?php echo $client_id; ?>&q=<?php echo $domain_name; ?>">Domain: <?php echo $domain_name; ?></a>
<span>-- <?php echo $domain_expire; ?> (<?php echo $domain_expire_human; ?>)</span>
</p>
<?php
}
?>
<?php
while ($row = mysqli_fetch_array($sql_certificates_expired)) {
$certificate_id = intval($row['certificate_id']);
$certificate_name = nullable_htmlentities($row['certificate_name']);
$certificate_expire = nullable_htmlentities($row['certificate_expire']);
$certificate_expire_human = timeAgo($row['certificate_expire']);
?>
<p class="mb-1">
<i class="fa fa-fw fa-lock text-secondary mr-1"></i>
<a href="certificates.php?client_id=<?php echo $client_id; ?>&q=<?php echo $certificate_name; ?>">Certificate: <?php echo $certificate_name; ?></a>
<span>-- <?php echo $certificate_expire; ?> (<?php echo $certificate_expire_human; ?>)</span>
</p>
<?php
}
?>
<?php
while ($row = mysqli_fetch_array($sql_asset_warranties_expired)) {
$asset_id = intval($row['asset_id']);
$asset_name = nullable_htmlentities($row['asset_name']);
$asset_warranty_expire = nullable_htmlentities($row['asset_warranty_expire']);
$asset_warranty_expire_human = timeAgo($row['asset_warranty_expire']);
?>
<p class="mb-1">
<i class="fa fa-fw fa-laptop text-secondary mr-1"></i>Asset Warranty:
<a href="asset_details.php?client_id=<?php echo $client_id; ?>&asset_id=<?php echo $asset_id; ?>"><?php echo $asset_name; ?></a>
<span>-- <?php echo $asset_warranty_expire; ?> (<?php echo $asset_warranty_expire_human; ?>)</span>
</p>
<?php
}
?>
<?php
while ($row = mysqli_fetch_array($sql_asset_retired)) {
$asset_id = intval($row['asset_id']);
$asset_name = nullable_htmlentities($row['asset_name']);
$asset_install_date = nullable_htmlentities($row['asset_install_date']);
$asset_install_date_human = timeAgo($row['asset_install_date']);
?>
<p class="mb-1">
<i class="fa fa-fw fa-laptop text-secondary mr-1"></i>
<a href="asset_details.php?client_id=<?php echo $client_id; ?>&asset_id=<?php echo $asset_id; ?>">Asset Retire: <?php echo $asset_name; ?></a>
<span>-- <?php echo $asset_install_date; ?> (<?php echo $asset_install_date_human; ?>)</span>
</p>
<?php
}
?>
<?php
while ($row = mysqli_fetch_array($sql_licenses_expired)) {
$software_id = intval($row['software_id']);
$software_name = nullable_htmlentities($row['software_name']);
$software_expire = nullable_htmlentities($row['software_expire']);
$software_expire_human = timeAgo($row['software_expire']);
?>
<p class="mb-1">
<i class="fa fa-fw fa-cube text-secondary mr-1"></i>
<a href="software.php?client_id=<?php echo $client_id; ?>&q=<?php echo $software_name; ?>">Software: <?php echo $software_name; ?></a>
<span>-- <?php echo $software_expire; ?> (<?php echo $software_expire_human; ?>)</span>
</p>
<?php
}
?>
</div>
</div>
</div>
<?php } ?>
<?php if (mysqli_num_rows($sql_stale_tickets) > 0) { ?>
<!-- Stale Tickets -->
<div class="col-md-4">
<div class="card card-dark mb-3">
<div class="card-header">
<h5 class="card-title"><i class="fa fa-fw fa-life-ring mr-2"></i>Stale Tickets <small>(Not updated within 3 days)</small></h5>
</div>
<div class="card-body p-2">
<table class="table table-borderless table-sm">
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_stale_tickets)) {
$ticket_id = intval($row['ticket_id']);
$ticket_prefix = nullable_htmlentities($row['ticket_prefix']);
$ticket_number = intval($row['ticket_number']);
$ticket_subject = nullable_htmlentities($row['ticket_subject']);
$ticket_created_at = nullable_htmlentities($row['ticket_created_at']);
$ticket_created_at_human = timeAgo($row['ticket_created_at']);
?>
<tr>
<td><a href="ticket.php?client_id=<?php echo $client_id; ?>&ticket_id=<?php echo $ticket_id?>"><?php echo "$ticket_prefix$ticket_number"; ?></a></td>
<td><?php echo $ticket_subject; ?></td>
<td><?php echo $ticket_created_at_human; ?> <small class="text-muted"><?php echo $ticket_created_at; ?></small></td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
</div>
</div>
<?php } ?>
<?php if (mysqli_num_rows($sql_recent_activities) > 0) { ?>
<!-- Recent Activities -->
<div class="col-md-6">
<div class="card card-dark mb-3">
<div class="card-header">
<h5 class="card-title"><i class="fa fa-fw fa-history mr-2"></i>Recent Activities <small>(Last 10 tasks)</small></h5>
</div>
<div class="card-body p-2">
<table class="table table-borderless table-sm">
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_recent_activities)) {
$log_created_at_time_ago = timeAgo($row['log_created_at']);
$log_description = nullable_htmlentities($row['log_description']);
?>
<tr>
<td class="text-nowrap text-secondary"><?php echo $log_created_at_time_ago; ?></td>
<td><?php echo $log_description; ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
<?php if ($session_user_role == 3) { ?>
<div class="card-footer">
<a href="../admin/audit_log.php?client=<?php echo $client_id; ?>">See More...</a>
</div>
<?php } ?>
</div>
</div>
<?php } ?>
</div>
<script>
function updateClientNotes(client_id) {
var notes = document.getElementById("clientNotes").value;
// Send a POST request to ajax.php as ajax.php with data client_set_notes=true, client_id=NUM, notes=NOTES
jQuery.post(
"ajax.php",
{
client_set_notes: 'TRUE',
client_id: client_id,
notes: notes
}
)
}
</script>
<?php
require_once "../includes/footer.php";

640
agent/clients.php Normal file
View File

@@ -0,0 +1,640 @@
<?php
// Default Column Sortby/Order Filter
$sort = "client_accessed_at";
$order = "DESC";
require_once "includes/inc_all.php";
// Perms
enforceUserPermission('module_client');
// Leads Filter
if (isset($_GET['leads']) && $_GET['leads'] == 1) {
$leads_filter = 1;
$leads_query = "AND client_lead = 1";
} else {
$leads_filter = 0;
$leads_query = "AND client_lead = 0";
}
// Tags Filter
if (isset($_GET['tags']) && is_array($_GET['tags']) && !empty($_GET['tags'])) {
// Sanitize each element of the tags array
$sanitizedTags = array_map('intval', $_GET['tags']);
// Convert the sanitized tags into a comma-separated string
$tag_filter = implode(",", $sanitizedTags);
$tag_query = "AND tags.tag_id IN ($tag_filter)";
} else {
$tag_filter = 0;
$tag_query = '';
}
// Industry Filter
if (isset($_GET['industry']) & !empty($_GET['industry'])) {
$industry_query = "AND (clients.client_type = '" . sanitizeInput($_GET['industry']) . "')";
$industry_filter = nullable_htmlentities($_GET['industry']);
} else {
// Default - any
$industry_query = '';
$industry_filter = '';
}
// Referral Filter
if (isset($_GET['referral']) & !empty($_GET['referral'])) {
$referral_query = "AND (clients.client_referral = '" . sanitizeInput($_GET['referral']) . "')";
$referral_filter = nullable_htmlentities($_GET['referral']);
} else {
// Default - any
$referral_query = '';
$referral_filter = '';
}
$sql = mysqli_query(
$mysqli,
"
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_id = clients.client_id
LEFT JOIN tags ON tags.tag_id = client_tags.tag_id
WHERE (client_name LIKE '%$q%' OR client_abbreviation 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 location_country 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'
$leads_query
$access_permission_query
$tag_query
$industry_query
$referral_query
GROUP BY client_id
ORDER BY $sort $order
LIMIT $record_from, $record_to
");
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?>
<div class="card">
<div class="card-header bg-dark py-2">
<h3 class="card-title mt-2"><i class="fa fa-fw fa-user-friends mr-2"></i><?php if($leads_filter == 0){ echo "Clients"; } else { echo "Leads"; } ?></h3>
<div class="card-tools">
<?php if (lookupUserPermission("module_client") >= 2) { ?>
<div class="btn-group">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addClientModal">
<i class="fas fa-plus mr-2"></i>New
<?php if ($leads_filter == 0) { echo "Client"; } else { echo "Lead"; } ?>
</button>
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#importClientModal">
<i class="fa fa-fw fa-upload mr-2"></i>Import
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#exportClientModal">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
</div>
</div>
<?php } ?>
</div>
</div>
<div class="card-header pb-2 pt-3">
<form autocomplete="off">
<input type="hidden" name="leads" value="<?php echo $leads_filter; ?>">
<input type="hidden" name="archived" value="<?php echo $archived; ?>">
<div class="row">
<div class="col-md-5">
<div class="form-group">
<div class="input-group">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search <?php if($leads_filter == 0){ echo "clients"; } else { echo "leads"; } ?>" autofocus>
<div class="input-group-append">
<button class="btn btn-secondary" type="button" data-toggle="collapse" data-target="#advancedFilter"><i class="fas fa-filter"></i></button>
<button class="btn btn-primary"><i class="fa fa-search"></i></button>
</div>
</div>
</div>
</div>
<div class="col-md-7">
<div class="btn-toolbar form-group float-right">
<div class="btn-group mr-2">
<a href="?leads=0" class="btn btn-<?php if ($leads_filter == 0){ echo "primary"; } else { echo "default"; } ?>" title="Clients"><i class="fa fa-fw fa-user-friends"></i><span class="d-none d-sm-inline ml-2">Clients</span></a>
<a href="?leads=1" class="btn btn-<?php if ($leads_filter == 1){ echo "primary"; } else { echo "default"; } ?>"><i class="fa fa-fw fa-bullhorn"></i><span class="d-none d-sm-inline ml-2">Leads</span></a>
</div>
<div class="btn-group">
<a href="?<?php echo $url_query_strings_sort ?>&archived=<?php if($archived == 1){ echo 0; } else { echo 1; } ?>"
class="btn btn-<?php if ($archived == 1) { echo "primary"; } else { echo "default"; } ?>">
<i class="fa fa-fw fa-archive mr-2"></i>Archived
</a>
<div class="dropdown ml-2" id="bulkActionButton" hidden>
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">
<i class="fas fa-fw fa-layer-group"></i><span class="d-none d-sm-inline ml-2">Action</span> (<span id="selectedCount">0</span>)
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkEditHourlyRateModal">
<i class="fas fa-fw fa-clock mr-2"></i>Set Hourly Rate
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkEditIndustryModal">
<i class="fas fa-fw fa-briefcase mr-2"></i>Set Industry
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkEditReferralModal">
<i class="fas fa-fw fa-link mr-2"></i>Set Referral
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkAssignTagsModal">
<i class="fas fa-fw fa-tags mr-2"></i>Assign Tags
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkSendEmailModal">
<i class="fas fa-fw fa-paper-plane mr-2"></i>Send Email
</a>
<?php if ($archived) { ?>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-info"
type="submit" form="bulkActions" name="bulk_unarchive_clients">
<i class="fas fa-fw fa-redo mr-2"></i>Restore
</button>
<?php } else { ?>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-danger confirm-link"
type="submit" form="bulkActions" name="bulk_archive_clients">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</button>
<?php } ?>
</div>
</div>
</div>
</div>
</div>
</div>
<div
class="collapse
<?php
if (
isset($_GET['dtf'])
|| $industry_filter
|| $referral_filter
|| (isset($_GET['tags']) && is_array($_GET['tags']))
|| $_GET['canned_date'] !== "custom" )
{
echo "show";
}
?>
"
id="advancedFilter"
>
<div class="row">
<div class="col-md-2">
<div class="form-group">
<label>Canned date</label>
<select onchange="this.form.submit()" class="form-control select2" name="canned_date">
<option <?php if ($_GET['canned_date'] == "custom") { echo "selected"; } ?> value="custom">Custom</option>
<option <?php if ($_GET['canned_date'] == "today") { echo "selected"; } ?> value="today">Today</option>
<option <?php if ($_GET['canned_date'] == "yesterday") { echo "selected"; } ?> value="yesterday">Yesterday</option>
<option <?php if ($_GET['canned_date'] == "thisweek") { echo "selected"; } ?> value="thisweek">This Week</option>
<option <?php if ($_GET['canned_date'] == "lastweek") { echo "selected"; } ?> value="lastweek">Last Week</option>
<option <?php if ($_GET['canned_date'] == "thismonth") { echo "selected"; } ?> value="thismonth">This Month</option>
<option <?php if ($_GET['canned_date'] == "lastmonth") { echo "selected"; } ?> value="lastmonth">Last Month</option>
<option <?php if ($_GET['canned_date'] == "thisyear") { echo "selected"; } ?> value="thisyear">This Year</option>
<option <?php if ($_GET['canned_date'] == "lastyear") { echo "selected"; } ?> value="lastyear">Last Year</option>
</select>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>Date from</label>
<input onchange="this.form.submit()" type="date" class="form-control" name="dtf" max="2999-12-31" value="<?php echo nullable_htmlentities($dtf); ?>">
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>Date to</label>
<input onchange="this.form.submit()" type="date" class="form-control" name="dtt" max="2999-12-31" value="<?php echo nullable_htmlentities($dtt); ?>">
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>Tag</label>
<select onchange="this.form.submit()" class="form-control select2" name="tags[]" data-placeholder="- Select Tags -" multiple>
<?php
$sql_tags_filter = mysqli_query($mysqli, "
SELECT tags.tag_id, tags.tag_name
FROM tags
LEFT JOIN client_tags ON client_tags.tag_id = tags.tag_id
WHERE tag_type = 1
GROUP BY tags.tag_id
HAVING COUNT(client_tags.client_id) > 0 OR tags.tag_id IN ($tag_filter)
");
while ($row = mysqli_fetch_array($sql_tags_filter)) {
$tag_id = intval($row['tag_id']);
$tag_name = nullable_htmlentities($row['tag_name']); ?>
<option value="<?php echo $tag_id ?>" <?php if (isset($_GET['tags']) && is_array($_GET['tags']) && in_array($tag_id, $_GET['tags'])) { echo 'selected'; } ?>> <?php echo $tag_name ?> </option>
<?php } ?>
</select>
</div>
</div>
<div class="col-sm-2">
<div class="form-group">
<label>Industry</label>
<select class="form-control select2" name="industry" onchange="this.form.submit()">
<option value="">- All Industries -</option>
<?php
$sql_industries_filter = mysqli_query($mysqli, "SELECT DISTINCT client_type FROM clients WHERE 1 = 1 AND client_$archive_query AND client_type != '' $leads_query ORDER BY client_type ASC");
while ($row = mysqli_fetch_array($sql_industries_filter)) {
$industry_name = nullable_htmlentities($row['client_type']);
?>
<option <?php if ($industry_name == $industry_filter) { echo "selected"; } ?>><?php echo $industry_name; ?></option>
<?php
}
?>
</select>
</div>
</div>
<div class="col-sm-2">
<div class="form-group">
<label>Referral</label>
<select class="form-control select2" name="referral" onchange="this.form.submit()">
<option value="">- All Referrals -</option>
<?php
$sql_referrals_filter = mysqli_query($mysqli, "SELECT DISTINCT client_referral FROM clients WHERE 1 = 1 AND client_$archive_query AND client_referral != '' $leads_query ORDER BY client_referral ASC");
while ($row = mysqli_fetch_array($sql_referrals_filter)) {
$referral_name = nullable_htmlentities($row['client_referral']);
?>
<option <?php if ($referral_name == $referral_filter) { echo "selected"; } ?>><?php echo $referral_name; ?></option>
<?php
}
?>
</select>
</div>
</div>
</div>
</div>
</form>
</div>
<form id="bulkActions" action="post.php" method="post" enctype="multipart/form-data">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<div class="table-responsive-sm">
<table class="table table-hover mb-0 text-nowrap">
<thead class="<?php if ($num_rows[0] == 0) { echo "d-none"; } ?> bg-light">
<tr>
<td class="pr-0">
<div class="form-check">
<input class="form-check-input" id="selectAllCheckbox" type="checkbox" onclick="checkAll(this)">
</div>
</td>
<th>
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=client_name&order=<?php echo $disp; ?>">
Client Name <?php if ($sort == 'client_name') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=location_city&order=<?php echo $disp; ?>">
Primary Location <?php if ($sort == 'location_city') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=contact_name&order=<?php echo $disp; ?>">
Primary Contact
<?php if ($sort == 'contact_name') { echo $order_icon; } ?>
</a>
</th>
<th></th>
<?php if ((lookupUserPermission("module_financial") >= 1) && $config_module_enable_accounting == 1) { ?>
<th>Billing</th>
<?php } ?>
<?php if (lookupUserPermission("module_client") >= 2) { ?>
<th class="text-center">Action</th>
<?php } ?>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql)) {
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
$client_type = nullable_htmlentities($row['client_type']);
$location_id = intval($row['location_id']);
$location_country = nullable_htmlentities($row['location_country']);
$location_address = nullable_htmlentities($row['location_address']);
$location_city = nullable_htmlentities($row['location_city']);
$location_state = nullable_htmlentities($row['location_state']);
$location_zip = nullable_htmlentities($row['location_zip']);
if (empty($location_address) && empty($location_city) && empty($location_state) && empty($location_zip)) {
$location_address_display = "-";
} else {
$location_address_display = "<div class='media'><i class='fa fa-fw fa-map-marker-alt text-secondary mt-1 mr-2'></i><div class='media-body'>$location_address<div>$location_city $location_state $location_zip</div><div><small>$location_country</small></div></div></div>";
}
$contact_id = intval($row['contact_id']);
$contact_name = nullable_htmlentities($row['contact_name']);
$contact_title = nullable_htmlentities($row['contact_title']);
$contact_phone_country_code = nullable_htmlentities($row['contact_phone_country_code']);
$contact_phone = nullable_htmlentities(formatPhoneNumber($row['contact_phone'], $contact_phone_country_code));
$contact_extension = nullable_htmlentities($row['contact_extension']);
$contact_mobile_country_code = nullable_htmlentities($row['contact_mobile_country_code']);
$contact_mobile = nullable_htmlentities(formatPhoneNumber($row['contact_mobile'], $contact_mobile_country_code));
$contact_email = nullable_htmlentities($row['contact_email']);
$client_website = nullable_htmlentities($row['client_website']);
$client_rate = floatval($row['client_rate']);
$client_currency_code = nullable_htmlentities($row['client_currency_code']);
$client_net_terms = intval($row['client_net_terms']);
$client_tax_id_number = nullable_htmlentities($row['client_tax_id_number']);
$client_referral = nullable_htmlentities($row['client_referral']);
$client_abbreviation = nullable_htmlentities($row['client_abbreviation']);
$client_notes = nullable_htmlentities($row['client_notes']);
$client_created_at = date('Y-m-d', strtotime($row['client_created_at']));
$client_updated_at = nullable_htmlentities($row['client_updated_at']);
$client_archived_at = nullable_htmlentities($row['client_archived_at']);
$client_is_lead = intval($row['client_lead']);
// Abbreviation
if (empty($client_abbreviation)) {
$client_abbreviation = shortenClient($client_name);
}
// Counts
// Contact Count
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('contact_id') AS num FROM contacts WHERE contact_client_id = $client_id AND contact_archived_at IS NULL"));
$contact_count = $row['num'];
if ($contact_count) {
$contact_count_display = "<a href='contacts.php?client_id=$client_id' class='mr-2 mb-1 badge badge-pill badge-dark p-2' title='Contacts ($contact_count)'><i class='fas fa-fw fa-users mr-2'></i>$contact_count</a>";
} else {
$contact_count_display = '';
}
// Vendors Count
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('vendor_id') AS num FROM vendors WHERE vendor_client_id = $client_id AND vendor_archived_at IS NULL"));
$vendor_count = $row['num'];
if ($vendor_count) {
$vendor_count_display = "<a href='vendors.php?client_id=$client_id' class='mr-2 mb-1 badge badge-pill badge-dark p-2' title='Vendors ($vendor_count)'><i class='fas fa-fw fa-building mr-2'></i>$vendor_count</a>";
} else {
$vendor_count_display = '';
}
// Asset Count
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('asset_id') AS num FROM assets WHERE asset_client_id = $client_id AND asset_archived_at IS NULL"));
$asset_count = $row['num'];
if ($asset_count) {
$asset_count_display = "<a href='assets.php?client_id=$client_id' class='mr-2 mb-1 badge badge-pill badge-secondary p-2' title='Assets ($asset_count)'><i class='fas fa-fw fa-desktop mr-2'></i>$asset_count</a>";
} else {
$asset_count_display = '';
}
// Credential Count
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('credential_id') AS num FROM credentials WHERE credential_client_id = $client_id AND credential_archived_at IS NULL"));
$credential_count = $row['num'];
if ($credential_count) {
$credential_count_display = "<a href='credentials.php?client_id=$client_id' class='mr-2 mb-1 badge badge-pill badge-secondary p-2' title='Credentials ($credential_count)'><i class='fas fa-fw fa-key mr-2'></i>$credential_count</a>";
} else {
$credential_count_display = '';
}
// Software Count
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('software_id') AS num FROM software WHERE software_client_id = $client_id AND software_archived_at IS NULL"));
$software_count = $row['num'];
if ($software_count) {
$software_count_display = "<a href='software.php?client_id=$client_id' class='mr-2 mb-1 badge badge-pill badge-secondary p-2' title='Licenses ($software_count)'><i class='fas fa-fw fa-cube mr-2'></i>$software_count</a>";
} else {
$software_count_display = '';
}
// Ticket Count
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('ticket_id') AS num FROM tickets WHERE ticket_client_id = $client_id AND ticket_archived_at IS NULL"));
$ticket_count = $row['num'];
if ($ticket_count) {
$ticket_count_display = "<a href='tickets.php?client_id=$client_id' class='mr-2 mb-1 badge badge-pill badge-secondary p-2' title='Tickets ($ticket_count)'><i class='fas fa-fw fa-life-ring mr-2'></i>$ticket_count</a>";
} else {
$ticket_count_display = '';
}
// 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.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']);
$client_tag_name = nullable_htmlentities($row['tag_name']);
$client_tag_color = nullable_htmlentities($row['tag_color']);
if (empty($client_tag_color)) {
$client_tag_color = "dark";
}
$client_tag_icon = nullable_htmlentities($row['tag_icon']);
if (empty($client_tag_icon)) {
$client_tag_icon = "tag";
}
$client_tag_id_array[] = $client_tag_id;
$client_tag_name_display_array[] = "<a href='clients.php?tags[]=$client_tag_id'><span class='badge text-light p-1 mr-1' style='background-color: $client_tag_color;'><i class='fa fa-fw fa-$client_tag_icon mr-2'></i>$client_tag_name</span></a>";
}
$client_tags_display = implode('', $client_tag_name_display_array);
//Add up all the payments for the invoice and get the total amount paid to the invoice
$sql_invoice_amounts = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS invoice_amounts FROM invoices WHERE invoice_client_id = $client_id AND invoice_status != 'Draft' AND invoice_status != 'Cancelled' AND invoice_status != 'Non-Billable' ");
$row = mysqli_fetch_array($sql_invoice_amounts);
$invoice_amounts = floatval($row['invoice_amounts']);
$sql_amount_paid = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS amount_paid FROM payments, invoices WHERE payment_invoice_id = invoice_id AND invoice_client_id = $client_id");
$row = mysqli_fetch_array($sql_amount_paid);
$amount_paid = floatval($row['amount_paid']);
$balance = $invoice_amounts - $amount_paid;
//set Text color on balance
if ($balance > 0) {
$balance_text_color = "text-danger font-weight-bold";
} else {
$balance_text_color = "";
}
// Get Credit Balance
$sql_credit_balance = mysqli_query($mysqli, "SELECT SUM(credit_amount) AS credit_balance FROM credits WHERE credit_client_id = $client_id");
$row = mysqli_fetch_array($sql_credit_balance);
$credit_balance = floatval($row['credit_balance']);
//Get Monthly Recurring Total
$sql_recurring_monthly_total = mysqli_query($mysqli, "SELECT SUM(recurring_invoice_amount) AS recurring_monthly_total FROM recurring_invoices WHERE recurring_invoice_status = 1 AND recurring_invoice_frequency = 'month' AND recurring_invoice_client_id = $client_id");
$row = mysqli_fetch_array($sql_recurring_monthly_total);
$recurring_monthly_total = floatval($row['recurring_monthly_total']);
//Get Yearly Recurring Total
$sql_recurring_yearly_total = mysqli_query($mysqli, "SELECT SUM(recurring_invoice_amount) AS recurring_yearly_total FROM recurring_invoices WHERE recurring_invoice_status = 1 AND recurring_invoice_frequency = 'year' AND recurring_invoice_client_id = $client_id");
$row = mysqli_fetch_array($sql_recurring_yearly_total);
$recurring_yearly_total = floatval($row['recurring_yearly_total']) / 12;
$recurring_monthly = $recurring_monthly_total + $recurring_yearly_total;
?>
<tr>
<td class="pr-0 bg-light">
<div class="form-check">
<input class="form-check-input bulk-select" type="checkbox" name="client_ids[]" value="<?php echo $client_id ?>">
</div>
</td>
<td>
<a data-toggle="tooltip" data-placement="right" title="Client ID: <?php echo $client_id; ?>" class="font-weight-bold h6" href="client_overview.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a>
<?php
if (!empty($client_type)) {
?>
<div class="text-secondary mt-1">
<?php echo $client_type; ?>
</div>
<?php } ?>
<?php
if (!empty($client_tags_display)) { ?>
<div class="mt-1 text-wrap">
<?php echo $client_tags_display; ?>
</div>
<?php } ?>
<div class="mt-1 text-secondary">
<small><strong>Abbreviation: </strong> <?php echo $client_abbreviation; ?></small><br>
<small><strong>Created: </strong> <?php echo $client_created_at; ?></small><br>
</div>
</td>
<td><?php echo $location_address_display; ?></td>
<td>
<?php
if (empty($contact_name) && empty($contact_phone) && empty($contact_mobile) && empty($client_email)) {
echo "-";
}
if (!empty($contact_name)) { ?>
<div class="text-bold">
<i class="fa fa-fw fa-user text-secondary mr-2 mb-2"></i><a class="ajax-modal" href="#"
data-modal-url="modals/contact/contact_details.php?client_id=<?= $client_id ?>&id=<?= $contact_id ?>" data-modal-size="lg"><?= $contact_name; ?>
</a>
</div>
<?php } else {
echo "-";
}
if (!empty($contact_phone)) { ?>
<div class="mt-1">
<i class="fa fa-fw fa-phone text-secondary mr-2 mb-2"></i><?php echo $contact_phone; ?> <?php if (!empty($contact_extension)) { echo "x$contact_extension"; } ?>
</div>
<?php }
if (!empty($contact_mobile)) { ?>
<div class="mt-1">
<i class="fa fa-fw fa-mobile-alt text-secondary mr-2"></i><?php echo $contact_mobile; ?>
</div>
<?php }
if (!empty($contact_email)) { ?>
<div class="mt-1">
<i class="fa fa-fw fa-envelope text-secondary mr-2"></i><a href="mailto:<?php echo $contact_email; ?>"><?php echo $contact_email; ?></a><button class='btn btn-sm clipboardjs' type="button" data-clipboard-text='<?php echo $contact_email; ?>'><i class='far fa-copy text-secondary'></i></button>
</div>
<?php } ?>
</td>
<td class="text-wrap">
<?php echo "$contact_count_display$vendor_count_display$asset_count_display$credential_count_display$software_count_display$ticket_count_display"; ?>
</td>
<!-- Show Billing if perms & if accounting module is enabled -->
<?php if ((lookupUserPermission("module_financial") >= 1) && $config_module_enable_accounting == 1) { ?>
<td class="text-right">
<div class="d-flex justify-content-between">
<span class="text-secondary">Balance</span>
<span class="<?php echo $balance_text_color; ?>"><?php echo numfmt_format_currency($currency_format, $balance, $session_company_currency); ?></span>
</div>
<div class="d-flex justify-content-between">
<span class="text-secondary">Paid</span>
<span><?php echo numfmt_format_currency($currency_format, $amount_paid, $session_company_currency); ?></span>
</div>
<?php if ($credit_balance > 0) { ?>
<div class="d-flex justify-content-between">
<span class="text-secondary">Credit</span>
<span class="text-success"><?php echo numfmt_format_currency($currency_format, $credit_balance, $session_company_currency); ?></span>
</div>
<?php } ?>
<div class="d-flex justify-content-between">
<span class="text-secondary">Monthly</span>
<span><?php echo numfmt_format_currency($currency_format, $recurring_monthly, $session_company_currency); ?></span>
</div>
<div class="d-flex justify-content-between">
<span class="text-secondary">Hourly Rate</span>
<span><?php echo numfmt_format_currency($currency_format, $client_rate, $session_company_currency); ?></span>
</div>
</td>
<?php } ?>
<!-- Actions -->
<?php if (lookupUserPermission("module_client") >= 2) { ?>
<td>
<div class="dropdown dropleft text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i>
</button>
<div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/client/client_edit.php?id=<?= $client_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit
</a>
<?php if ($client_archived_at) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-info confirm-link" href="post.php?restore_client=<?php echo $client_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-redo mr-2"></i>Restore
</a>
<?php } else { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_client=<?php echo $client_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</a>
<?php } ?>
</div>
</div>
</td>
<?php } ?>
</tr>
<?php
} ?>
</tbody>
</table>
</div>
<?php
require_once "modals/client/client_bulk_edit_industry.php";
require_once "modals/client/client_bulk_edit_referral.php";
require_once "modals/client/client_bulk_edit_hourly_rate.php";
require_once "modals/client/client_bulk_assign_tags.php";
require_once "modals/client/client_bulk_email.php";
?>
</form>
<!-- Ends Card Body -->
<?php require_once "../includes/filter_footer.php"; ?>
</div> <!-- End Card -->
<script src="../js/bulk_actions.js"></script>
<?php
require_once "modals/client/client_add.php";
require_once "modals/client/client_import.php";
require_once "modals/client/client_export.php";
require_once "../includes/footer.php";

1183
agent/contact_details.php Normal file

File diff suppressed because it is too large Load Diff

607
agent/contacts.php Normal file
View File

@@ -0,0 +1,607 @@
<?php
// Default Column Sortby Filter
$sort = "contact_name";
$order = "ASC";
// If client_id is in URI then show client Side Bar and client header
if (isset($_GET['client_id'])) {
require_once "includes/inc_all_client.php";
$client_query = "AND contact_client_id = $client_id";
$client_url = "client_id=$client_id&";
// Overide Filter Header Archived
if (isset($_GET['archived']) && $_GET['archived'] == 1) {
$archived = 1;
$archive_query = "contact_archived_at IS NOT NULL";
} else {
$archived = 0;
$archive_query = "contact_archived_at IS NULL";
}
} else {
require_once "includes/inc_client_overview_all.php";
$client_query = '';
$client_url = '';
// Overide Filter Header Archived
if (isset($_GET['archived']) && $_GET['archived'] == 1) {
$archived = 1;
$archive_query = "(client_archived_at IS NOT NULL OR contact_archived_at IS NOT NULL)";
} else {
$archived = 0;
$archive_query = "(client_archived_at IS NULL AND contact_archived_at IS NULL)";
}
}
// Tags Filter
if (isset($_GET['tags']) && is_array($_GET['tags']) && !empty($_GET['tags'])) {
// Sanitize each element of the tags array
$sanitizedTags = array_map('intval', $_GET['tags']);
// Convert the sanitized tags into a comma-separated string
$tag_filter = implode(",", $sanitizedTags);
$tag_query = "AND tags.tag_id IN ($tag_filter)";
} else {
$tag_filter = 0;
$tag_query = '';
}
if (!$client_url) {
// Client Filter
if (isset($_GET['client']) & !empty($_GET['client'])) {
$client_query = 'AND (contact_client_id = ' . intval($_GET['client']) . ')';
$client = intval($_GET['client']);
} else {
// Default - any
$client_query = '';
$client = '';
}
}
if ($client_url && isset($_GET['location']) && !empty($_GET['location'])) {
// Location Filter
$location_query = 'AND (contact_location_id = ' . intval($_GET['location']) . ')';
$location_filter = intval($_GET['location']);
} else {
// Default - any
$location_query = '';
$location_filter = 0;
}
$sql = mysqli_query($mysqli, "SELECT SQL_CALC_FOUND_ROWS contacts.*, clients.*, locations.*, users.*, GROUP_CONCAT(tags.tag_name) FROM contacts
LEFT JOIN clients ON client_id = contact_client_id
LEFT JOIN locations ON location_id = contact_location_id
LEFT JOIN users ON user_id = contact_user_id
LEFT JOIN contact_tags ON contact_tags.contact_id = contacts.contact_id
LEFT JOIN tags ON tags.tag_id = contact_tags.tag_id
WHERE $archive_query
$tag_query
AND (contact_name LIKE '%$q%' OR contact_title LIKE '%$q%' OR location_name LIKE '%$q%' OR contact_email LIKE '%$q%' OR contact_department LIKE '%$q%' OR contact_phone LIKE '%$phone_query%' OR contact_extension LIKE '%$q%' OR contact_mobile LIKE '%$phone_query%' OR tag_name LIKE '%$q%' OR client_name LIKE '%$q%')
$access_permission_query
$client_query
$location_query
GROUP BY contact_id
ORDER BY contact_primary DESC, contact_important DESC, $sort $order LIMIT $record_from, $record_to"
);
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?>
<div class="card card-dark">
<div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fa fa-fw fa-address-book mr-2"></i>Contacts</h3>
<div class="card-tools">
<div class="btn-group">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addContactModal">
<i class="fas fa-plus mr-2"></i>New Contact
</button>
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<?php if ($client_url) { ?>
<!-- <a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#contactInviteModal"><i class="fas fa-fw fa-paper-plane mr-2"></i>Invite</a>-->
<!-- <div class="dropdown-divider"></div>-->
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#importContactModal">
<i class="fa fa-fw fa-upload mr-2"></i>Import
</a>
<div class="dropdown-divider"></div>
<?php } ?>
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#exportContactModal">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
</div>
</div>
</div>
</div>
<div class="card-body">
<form autocomplete="off">
<?php if ($client_url) { ?>
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<?php } ?>
<input type="hidden" name="archived" value="<?php echo $archived; ?>">
<div class="row">
<div class="col-md-4">
<div class="input-group mb-3 mb-md-0">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search Contacts">
<div class="input-group-append">
<button class="btn btn-dark"><i class="fa fa-search"></i></button>
</div>
</div>
</div>
<div class="col-md-3">
<div class="input-group mb-3 mb-md-0">
<select onchange="this.form.submit()" class="form-control select2" name="tags[]" data-placeholder="- Select Tags -" multiple>
<?php
$sql_tags_filter = mysqli_query($mysqli, "
SELECT tags.tag_id, tags.tag_name
FROM tags
LEFT JOIN contact_tags ON contact_tags.tag_id = tags.tag_id
LEFT JOIN contacts ON contact_tags.contact_id = contacts.contact_id
WHERE tag_type = 3
$client_query OR tags.tag_id IN ($tag_filter)
GROUP BY tags.tag_id
HAVING COUNT(contact_tags.contact_id) > 0 OR tags.tag_id IN ($tag_filter)
");
while ($row = mysqli_fetch_array($sql_tags_filter)) {
$tag_id = intval($row['tag_id']);
$tag_name = nullable_htmlentities($row['tag_name']); ?>
<option value="<?php echo $tag_id ?>" <?php if (isset($_GET['tags']) && in_array($tag_id, $_GET['tags'])) { echo 'selected'; } ?>> <?php echo $tag_name ?> </option>
<?php } ?>
</select>
</div>
</div>
<?php if ($client_url) { ?>
<div class="col-md-2">
<div class="input-group mb-3 mb-md-0">
<select class="form-control select2" name="location" onchange="this.form.submit()">
<option value="">- All Locations -</option>
<?php
$sql_locations_filter = mysqli_query($mysqli, "
SELECT DISTINCT location_id, location_name
FROM locations
WHERE location_client_id = $client_id
AND ( EXISTS (SELECT 1 FROM contacts WHERE contact_location_id = location_id AND $archive_query) OR location_id = $location_filter)
ORDER BY location_name ASC
");
while ($row = mysqli_fetch_array($sql_locations_filter)) {
$location_id = intval($row['location_id']);
$location_name = nullable_htmlentities($row['location_name']);
?>
<option <?php if ($location_filter == $location_id) { echo "selected"; } ?> value="<?php echo $location_id; ?>"><?php echo $location_name; ?></option>
<?php
}
?>
</select>
</div>
</div>
<?php } else { ?>
<div class="col-md-2">
<div class="input-group mb-3 mb-md-0">
<select class="form-control select2" name="client" onchange="this.form.submit()">
<option value="" <?php if ($client == "") { echo "selected"; } ?>>- All Clients -</option>
<?php
$sql_clients_filter = mysqli_query($mysqli, "
SELECT DISTINCT client_id, client_name
FROM clients
JOIN contacts ON contact_client_id = client_id
WHERE $archive_query
$access_permission_query
ORDER BY client_name ASC
");
while ($row = mysqli_fetch_array($sql_clients_filter)) {
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
?>
<option <?php if ($client == $client_id) { echo "selected"; } ?> value="<?php echo $client_id; ?>"><?php echo $client_name; ?></option>
<?php
}
?>
</select>
</div>
</div>
<?php } ?>
<div class="col-md-3">
<div class="btn-group float-right">
<a href="?<?php echo $client_url; ?>archived=<?php if($archived == 1){ echo 0; } else { echo 1; } ?>"
class="btn btn-<?php if($archived == 1){ echo "primary"; } else { echo "default"; } ?>">
<i class="fa fa-fw fa-archive mr-2"></i>Archived
</a>
<div class="dropdown ml-2" id="bulkActionButton" hidden>
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">
<i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>)
</button>
<div class="dropdown-menu">
<?php if ($client_url) { ?>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkAssignLocationModal">
<i class="fas fa-fw fa-map-marker-alt mr-2"></i>Assign Location
</a>
<div class="dropdown-divider"></div>
<?php } ?>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkEditPhoneModal">
<i class="fas fa-fw fa-phone-alt mr-2"></i>Set Phone Number
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkEditDepartmentModal">
<i class="fas fa-fw fa-users mr-2"></i>Set Department
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkEditRoleModal">
<i class="fas fa-fw fa-user-shield mr-2"></i>Set Roles
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkAssignTagsModal">
<i class="fas fa-fw fa-tags mr-2"></i>Assign Tags
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkSendEmailModal">
<i class="fas fa-fw fa-paper-plane mr-2"></i>Send Email
</a>
<?php if ($archived) { ?>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-info"
type="submit" form="bulkActions" name="bulk_unarchive_contacts">
<i class="fas fa-fw fa-redo mr-2"></i>Unarchive
</button>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-danger text-bold"
type="submit" form="bulkActions" name="bulk_delete_contacts">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</button>
<?php } else { ?>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-danger confirm-link"
type="submit" form="bulkActions" name="bulk_archive_contacts">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</button>
<?php } ?>
</div>
</div>
</div>
</div>
</div>
</form>
<hr>
<form id="bulkActions" action="post.php" method="post" enctype="multipart/form-data">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<div class="table-responsive-sm">
<table class="table border">
<thead class="thead-light <?php if (!$num_rows[0]) { echo "d-none"; } ?>">
<tr>
<td class="bg-light pr-0">
<div class="form-check">
<input class="form-check-input" id="selectAllCheckbox" type="checkbox" onclick="checkAll(this)">
</div>
</td>
<th>
<a class="text-secondary ml-3" href="?<?php echo $url_query_strings_sort; ?>&sort=contact_name&order=<?php echo $disp; ?>">
Name <?php if ($sort == 'contact_name') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=contact_department&order=<?php echo $disp; ?>">
Department <?php if ($sort == 'contact_department') { echo $order_icon; } ?>
</a>
</th>
<th>Contact</th>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=location_name&order=<?php echo $disp; ?>">
Location <?php if ($sort == 'location_name') { echo $order_icon; } ?>
</a>
</th>
<th></th>
<?php if (!$client_url) { ?>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=client_name&order=<?php echo $disp; ?>">
Client <?php if ($sort == 'client_name') { echo $order_icon; } ?>
</a>
</th>
<?php } ?>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql)) {
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
$contact_id = intval($row['contact_id']);
$contact_name = nullable_htmlentities($row['contact_name']);
$contact_title = nullable_htmlentities($row['contact_title']);
if (empty($contact_title)) {
$contact_title_display = "";
} else {
$contact_title_display = "<small class='text-secondary'>$contact_title</small>";
}
$contact_department = getFallBack(nullable_htmlentities($row['contact_department']));
$contact_extension = nullable_htmlentities($row['contact_extension']);
if (empty($contact_extension)) {
$contact_extension_display = "";
} else {
$contact_extension_display = "<small class='text-secondary ml-1'>x$contact_extension</small>";
}
$contact_phone_country_code = nullable_htmlentities($row['contact_phone_country_code']);
$contact_phone = nullable_htmlentities(formatPhoneNumber($row['contact_phone'], $contact_phone_country_code));
if (empty($contact_phone)) {
$contact_phone_display = "";
} else {
$contact_phone_display = "<div><i class='fas fa-fw fa-phone mr-2'></i><a href='tel:$contact_phone'>$contact_phone$contact_extension_display</a></div>";
}
$contact_mobile_country_code = nullable_htmlentities($row['contact_mobile_country_code']);
$contact_mobile = nullable_htmlentities(formatPhoneNumber($row['contact_mobile'], $contact_mobile_country_code));
if (empty($contact_mobile)) {
$contact_mobile_display = "";
} else {
$contact_mobile_display = "<div class='mt-2'><i class='fas fa-fw fa-mobile-alt mr-2'></i><a href='tel:$contact_mobile'>$contact_mobile</a></div>";
}
$contact_email = nullable_htmlentities($row['contact_email']);
if (empty($contact_email)) {
$contact_email_display = "";
} else {
$contact_email_display = "<div class='mt-1'><i class='fas fa-fw fa-envelope mr-2'></i><a href='mailto:$contact_email'>$contact_email</a><button class='btn btn-sm clipboardjs' type='button' data-clipboard-text='$contact_email'><i class='far fa-copy text-secondary'></i></button></div>";
}
$contact_info_display = "$contact_phone_display $contact_mobile_display $contact_email_display";
if (empty($contact_info_display)) {
$contact_info_display = "-";
}
$contact_pin = nullable_htmlentities($row['contact_pin']);
$contact_photo = nullable_htmlentities($row['contact_photo']);
$contact_initials = initials($contact_name);
$contact_notes = nullable_htmlentities($row['contact_notes']);
$contact_primary = intval($row['contact_primary']);
$contact_important = intval($row['contact_important']);
$contact_billing = intval($row['contact_billing']);
$contact_technical = intval($row['contact_technical']);
$contact_created_at = nullable_htmlentities($row['contact_created_at']);
$contact_archived_at = nullable_htmlentities($row['contact_archived_at']);
if ($contact_primary == 1) {
$contact_primary_display = "<small class='text-success'>Primary Contact</small>";
} else {
$contact_primary_display = false;
}
$contact_location_id = intval($row['contact_location_id']);
$location_name = nullable_htmlentities($row['location_name']);
if (empty($location_name)) {
$location_name = "<span class='text-muted'>N/A</span>";
}
$location_archived_at = nullable_htmlentities($row['location_archived_at']);
if ($location_archived_at) {
$location_name_display = "<div class='text-danger' title='Archived'><s>$location_name</s></div>";
} else {
$location_name_display = $location_name;
}
$auth_method = nullable_htmlentities($row['user_auth_method']);
$contact_user_id = intval($row['contact_user_id']);
if ($contact_user_id) {
$user_exists_display = "<span class='badge badge-pill badge-dark p-1' title='User: $auth_method'><i class='fas fa-fw fa-user'></i></span>";
} else {
$user_exists_display = "";
}
// Counts
// Asset Count
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('asset_id') AS num FROM assets WHERE asset_contact_id = $contact_id AND asset_archived_at IS NULL"));
$asset_count = $row['num'];
if ($asset_count) {
$asset_count_display = "<a href='contact_details.php?client_id=$client_id&contact_id=$contact_id#assets' class='mr-2 mb-1 badge badge-pill badge-dark p-2' title='Assets ($asset_count)'><i class='fas fa-fw fa-desktop mr-2'></i>$asset_count</a>";
} else {
$asset_count_display = '';
}
// Credential Count
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('credential_id') AS num FROM credentials WHERE credential_contact_id = $contact_id AND credential_archived_at IS NULL"));
$credential_count = $row['num'];
if ($credential_count) {
$credential_count_display = "<a href='contact_details.php?client_id=$client_id&contact_id=$contact_id#credentials' class='mr-2 mb-1 badge badge-pill badge-secondary p-2' title='Credentials ($credential_count)'><i class='fas fa-fw fa-key mr-2'></i>$credential_count</a>";
} else {
$credential_count_display = '';
}
// Software Count
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('software_id') AS num FROM software, software_contacts WHERE software.software_id = software_contacts.software_id AND software_contacts.contact_id = $contact_id AND software_archived_at IS NULL"));
$software_count = $row['num'];
if ($software_count) {
$software_count_display = "<a href='contact_details.php?client_id=$client_id&contact_id=$contact_id#software' class='mr-2 mb-1 badge badge-pill badge-secondary p-2' title='Licenses ($software_count)'><i class='fas fa-fw fa-cube mr-2'></i>$software_count</a>";
} else {
$software_count_display = '';
}
// Ticket Count
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('ticket_id') AS num FROM tickets WHERE ticket_contact_id = $contact_id AND ticket_archived_at IS NULL"));
$ticket_count = $row['num'];
if ($ticket_count) {
$ticket_count_display = "<a href='contact_details.php?client_id=$client_id&contact_id=$contact_id#tickets' class='mr-2 mb-1 badge badge-pill badge-secondary p-2' title='Tickets ($ticket_count)'><i class='fas fa-fw fa-life-ring mr-2'></i>$ticket_count</a>";
} else {
$ticket_count_display = '';
}
// Tags
$contact_tag_name_display_array = array();
$contact_tag_id_array = array();
$sql_contact_tags = mysqli_query($mysqli, "SELECT * FROM contact_tags LEFT JOIN tags ON contact_tags.tag_id = tags.tag_id WHERE contact_id = $contact_id ORDER BY tag_name ASC");
while ($row = mysqli_fetch_array($sql_contact_tags)) {
$contact_tag_id = intval($row['tag_id']);
$contact_tag_name = nullable_htmlentities($row['tag_name']);
$contact_tag_color = nullable_htmlentities($row['tag_color']);
if (empty($contact_tag_color)) {
$contact_tag_color = "dark";
}
$contact_tag_icon = nullable_htmlentities($row['tag_icon']);
if (empty($contact_tag_icon)) {
$contact_tag_icon = "tag";
}
$contact_tag_id_array[] = $contact_tag_id;
$contact_tag_name_display_array[] = "<a href='contacts.php?$client_url tags[]=$contact_tag_id'><span class='badge text-light p-1 mr-1' style='background-color: $contact_tag_color;'><i class='fa fa-fw fa-$contact_tag_icon mr-2'></i>$contact_tag_name</span></a>";
}
$contact_tags_display = implode('', $contact_tag_name_display_array);
?>
<tr>
<td class="pr-0 bg-light">
<div class="form-check">
<input class="form-check-input bulk-select" type="checkbox" name="contact_ids[]" value="<?php echo $contact_id ?>">
</div>
</td>
<td>
<a class="text-dark" href="contact_details.php?client_id=<?php echo $client_id; ?>&contact_id=<?php echo $contact_id; ?>">
<div class="media">
<?php if ($contact_photo) { ?>
<span class="fa-stack fa-2x mr-3 text-center">
<img class="img-size-50 img-circle" src="<?php echo "../uploads/clients/$client_id/$contact_photo"; ?>">
</span>
<?php } else { ?>
<span class="fa-stack fa-2x mr-3">
<i class="fa fa-circle fa-stack-2x text-secondary"></i>
<span class="fa fa-stack-1x text-white"><?php echo $contact_initials; ?></span>
</span>
<?php } ?>
<div class="media-body">
<div class="<?php if($contact_important) { echo "text-bold"; } ?>"><?php echo $contact_name; ?> <?php echo $user_exists_display; ?></div>
<?php echo $contact_title_display; ?>
<div><?php echo $contact_primary_display; ?></div>
<?php
if (!empty($contact_tags_display)) { ?>
<div class="mt-1">
<?php echo $contact_tags_display; ?>
</div>
<?php } ?>
</div>
</div>
</a>
</td>
<td><?php echo $contact_department; ?></td>
<td><?php echo $contact_info_display; ?></td>
<td><?php echo $location_name_display; ?></td>
<td>
<?php echo "$asset_count_display$credential_count_display$software_count_display$ticket_count_display"; ?>
</td>
<?php if (!$client_url) { ?>
<td><a href="contacts.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
<?php } ?>
<td>
<div class="dropdown dropleft text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i>
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="contact_details.php?<?= $client_url ?>contact_id=<?= $contact_id ?>">
<i class="fas fa-fw fa-eye mr-2"></i>Details
</a>
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/contact/contact_note_add.php?id=<?= $contact_id ?>">
<i class="fas fa-fw fa-sticky-note mr-2"></i>Make Note
</a>
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/contact/contact_edit.php?id=<?= $contact_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit
</a>
<?php if ($session_user_role == 3 && $contact_primary == 0) { ?>
<?php if ($contact_archived_at) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-info confirm-link" href="post.php?unarchive_contact=<?php echo $contact_id; ?>">
<i class="fas fa-fw fa-redo mr-2"></i>Unarchive
</a>
<?php } else { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_contact=<?php echo $contact_id; ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?anonymize_contact=<?php echo $contact_id; ?>">
<i class="fas fa-fw fa-user-secret mr-2"></i>Anonymize & Archive
</a>
<?php } ?>
<?php if ($config_destructive_deletes_enable) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_contact=<?php echo $contact_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</a>
<?php } ?>
<?php } ?>
</div>
</div>
</td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
<?php if ($client_url) { require_once "modals/contact/contact_bulk_assign_location.php"; } ?>
<?php require_once "modals/contact/contact_bulk_edit_phone.php"; ?>
<?php require_once "modals/contact/contact_bulk_edit_department.php"; ?>
<?php require_once "modals/contact/contact_bulk_edit_role.php"; ?>
<?php require_once "modals/contact/contact_bulk_assign_tags.php"; ?>
<?php require_once "modals/contact/contact_bulk_email.php"; ?>
</form>
<?php require_once "../includes/filter_footer.php";
?>
</div>
</div>
<!-- JavaScript to Show/Hide Password Form Group -->
<script>
function generatePassword(type, id) {
// Send a GET request to ajax.php as ajax.php?get_readable_pass=true
jQuery.get(
"ajax.php", {
get_readable_pass: 'true'
},
function(data) {
//If we get a response from post.php, parse it as JSON
const password = JSON.parse(data);
// Set the password value to the correct modal, based on the type
if (type == "add") {
document.getElementById("password-add").value = password;
} else if (type == "edit") {
document.getElementById("password-edit-"+id.toString()).value = password;
}
}
);
}
$(document).ready(function() {
$('.authMethod').on('change', function() {
var $form = $(this).closest('.authForm');
if ($(this).val() === 'local') {
$form.find('.passwordGroup').show();
} else {
$form.find('.passwordGroup').hide();
}
});
$('.authMethod').trigger('change');
});
</script>
<script src="../js/bulk_actions.js"></script>
<?php
require_once "modals/contact/contact_add.php";
require_once "modals/contact/contact_export.php";
if ($client_url) {
require_once "modals/contact/contact_invite.php";
require_once "modals/contact/contact_import.php";
}
require_once "../includes/footer.php";

543
agent/credentials.php Normal file
View File

@@ -0,0 +1,543 @@
<?php
// Default Column Sortby Filter
$sort = "credential_name";
$order = "ASC";
// If client_id is in URI then show client Side Bar and client header
if (isset($_GET['client_id'])) {
require_once "includes/inc_all_client.php";
$client_query = "AND credential_client_id = $client_id";
$client_url = "client_id=$client_id&";
// Overide Filter Header Archived
if (isset($_GET['archived']) && $_GET['archived'] == 1) {
$archived = 1;
$archive_query = "credential_archived_at IS NOT NULL";
} else {
$archived = 0;
$archive_query = "credential_archived_at IS NULL";
}
// Log when users load the Credentials page
logAction("Credential", "View", "$session_name viewed the Credentials page for client", $client_id);
} else {
require_once "includes/inc_client_overview_all.php";
$client_query = '';
$client_url = '';
// Overide Filter Header Archived
if (isset($_GET['archived']) && $_GET['archived'] == 1) {
$archived = 1;
$archive_query = "(client_archived_at IS NOT NULL OR credential_archived_at IS NOT NULL)";
} else {
$archived = 0;
$archive_query = "(client_archived_at IS NULL AND credential_archived_at IS NULL)";
}
// Log when users load the Credentials page
logAction("Credential", "View", "$session_name viewed the All Credentials page");
}
// Perms
enforceUserPermission('module_credential');
// Tags Filter
if (isset($_GET['tags']) && is_array($_GET['tags']) && !empty($_GET['tags'])) {
// Sanitize each element of the tags array
$sanitizedTags = array_map('intval', $_GET['tags']);
// Convert the sanitized tags into a comma-separated string
$tag_filter = implode(",", $sanitizedTags);
$tag_query = "AND tags.tag_id IN ($tag_filter)";
} else {
$tag_filter = 0;
$tag_query = '';
}
if (!$client_url) {
// Client Filter
if (isset($_GET['client']) & !empty($_GET['client'])) {
$client_query = 'AND (credential_client_id = ' . intval($_GET['client']) . ')';
$client = intval($_GET['client']);
} else {
// Default - any
$client_query = '';
$client = '';
}
}
// Location Filter
if ($client_url && isset($_GET['location']) && !empty($_GET['location'])) {
$location_query = 'AND (a.asset_location_id = ' . intval($_GET['location']) . ')';
$location_query_innerjoin = 'INNER JOIN assets a on a.asset_id = c.credential_asset_id ';
$location_filter = intval($_GET['location']);
} else {
// Default - any
$location_query_innerjoin = '';
$location_query = '';
$location_filter = '';
}
$sql = mysqli_query(
$mysqli,
"SELECT SQL_CALC_FOUND_ROWS c.credential_id AS c_credential_id, c.*, credential_tags.*, tags.*, clients.*, contacts.*, assets.*
FROM credentials c
LEFT JOIN credential_tags ON credential_tags.credential_id = c.credential_id
LEFT JOIN tags ON tags.tag_id = credential_tags.tag_id
LEFT JOIN clients ON client_id = credential_client_id
LEFT JOIN contacts ON contact_id = credential_contact_id
LEFT JOIN assets ON asset_id = credential_asset_id
$location_query_innerjoin
WHERE $archive_query
$tag_query
AND (c.credential_name LIKE '%$q%' OR c.credential_description LIKE '%$q%' OR c.credential_uri LIKE '%$q%' OR tag_name LIKE '%$q%' OR client_name LIKE '%$q%')
$location_query
$access_permission_query
$client_query
GROUP BY c.credential_id
ORDER BY c.credential_important DESC, $sort $order LIMIT $record_from, $record_to"
);
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?>
<div class="card card-dark">
<div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fa fa-fw fa-key mr-2"></i>Credentials</h3>
<div class="card-tools">
<?php if (lookupUserPermission("module_credential") >= 2) { ?>
<div class="btn-group">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addCredentialModal" <?php if (!isset($_COOKIE['user_encryption_session_key'])) { echo "disabled"; } ?>>
<i class="fas fa-plus mr-2"></i>New Credential
</button>
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<?php if ($client_url) { ?>
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#importCredentialModal">
<i class="fa fa-fw fa-upload mr-2"></i>Import
</a>
<div class="dropdown-divider"></div>
<?php } ?>
<?php if ($num_rows[0] > 0) { ?>
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#exportCredentialModal">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
<?php } ?>
</div>
</div>
<?php } ?>
</div>
</div>
<div class="card-body">
<form autocomplete="off">
<?php if ($client_url) { ?>
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<?php } ?>
<input type="hidden" name="archived" value="<?php echo $archived; ?>">
<div class="row">
<div class="col-md-4">
<div class="input-group mb-3 mb-md-0">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search Credentials">
<div class="input-group-append">
<button class="btn btn-dark"><i class="fa fa-search"></i></button>
</div>
</div>
</div>
<div class="col-md-3">
<div class="input-group mb-3 mb-md-0">
<select onchange="this.form.submit()" class="form-control select2" name="tags[]" data-placeholder="- Select Tags -" multiple>
<?php
$sql_tags_filter = mysqli_query($mysqli, "
SELECT tags.tag_id, tags.tag_name
FROM tags
LEFT JOIN credential_tags ON credential_tags.tag_id = tags.tag_id
LEFT JOIN credentials ON credential_tags.credential_id = credentials.credential_id
WHERE tag_type = 4
$client_query OR tags.tag_id IN ($tag_filter)
GROUP BY tags.tag_id
HAVING COUNT(credential_tags.credential_id) > 0 OR tags.tag_id IN ($tag_filter)
");
while ($row = mysqli_fetch_array($sql_tags_filter)) {
$tag_id = intval($row['tag_id']);
$tag_name = nullable_htmlentities($row['tag_name']); ?>
<option value="<?php echo $tag_id ?>" <?php if (isset($_GET['tags']) && is_array($_GET['tags']) && in_array($tag_id, $_GET['tags'])) { echo 'selected'; } ?>> <?php echo $tag_name ?> </option>
<?php } ?>
</select>
</div>
</div>
<?php if ($client_url) { ?>
<div class="col-md-2">
<div class="input-group mb-3 mb-md-0">
<select class="form-control select2" name="location" onchange="this.form.submit()">
<option value="">- All Asset Locations -</option>
<?php
$sql_locations_filter = mysqli_query($mysqli, "SELECT * FROM locations WHERE location_client_id = $client_id AND location_archived_at IS NULL ORDER BY location_name ASC");
while ($row = mysqli_fetch_array($sql_locations_filter)) {
$location_id = intval($row['location_id']);
$location_name = nullable_htmlentities($row['location_name']);
?>
<option <?php if ($location_filter == $location_id) { echo "selected"; } ?> value="<?php echo $location_id; ?>"><?php echo $location_name; ?></option>
<?php
}
?>
</select>
</div>
</div>
<?php } else { ?>
<div class="col-md-2">
<div class="input-group mb-3 mb-md-0">
<select class="form-control select2" name="client" onchange="this.form.submit()">
<option value="" <?php if ($client == "") { echo "selected"; } ?>>- All Clients -</option>
<?php
$sql_clients_filter = mysqli_query($mysqli, "
SELECT DISTINCT client_id, client_name
FROM clients
JOIN credentials ON credential_client_id = client_id
WHERE $archive_query
$access_permission_query
ORDER BY client_name ASC
");
while ($row = mysqli_fetch_array($sql_clients_filter)) {
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
?>
<option <?php if ($client == $client_id) { echo "selected"; } ?> value="<?php echo $client_id; ?>"><?php echo $client_name; ?></option>
<?php
}
?>
</select>
</div>
</div>
<?php } ?>
<div class="col-md-3">
<div class="btn-group float-right">
<a href="?<?php echo $client_url; ?>&archived=<?php if($archived == 1){ echo 0; } else { echo 1; } ?>"
class="btn btn-<?php if($archived == 1){ echo "primary"; } else { echo "default"; } ?>">
<i class="fa fa-fw fa-archive mr-2"></i>Archived
</a>
<div class="dropdown ml-2" id="bulkActionButton" hidden>
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">
<i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>)
</button>
<div class="dropdown-menu">
<?php if ($archived) { ?>
<button class="dropdown-item text-info"
type="submit" form="bulkActions" name="bulk_unarchive_credentials">
<i class="fas fa-fw fa-redo mr-2"></i>Unarchive
</button>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-danger text-bold"
type="submit" form="bulkActions" name="bulk_delete_credentials">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</button>
<?php } else { ?>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkAssignTagsModal">
<i class="fas fa-fw fa-tags mr-2"></i>Assign Tags
</a>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-danger confirm-link"
type="submit" form="bulkActions" name="bulk_archive_credentials">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</button>
<?php } ?>
</div>
</div>
</div>
</div>
</div>
</form>
<hr>
<form id="bulkActions" action="post.php" method="post">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<div class="table-responsive-sm">
<table class="table table-striped table-borderless table-hover">
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?> text-nowrap">
<tr>
<td class="pr-0">
<div class="form-check">
<input class="form-check-input" id="selectAllCheckbox" type="checkbox" onclick="checkAll(this)">
</div>
</td>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=credential_name&order=<?php echo $disp; ?>">
Name <?php if ($sort == 'credential_name') { echo $order_icon; } ?>
</a>
</th>
<th>Username / ID</th>
<th>Password / Key</th>
<th>OTP</th>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=credential_uri&order=<?php echo $disp; ?>">
URI <?php if ($sort == 'credential_uri') { echo $order_icon; } ?>
</a>
</th>
<th></th>
<?php if (!$client_url) { ?>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=client_name&order=<?php echo $disp; ?>">
Client <?php if ($sort == 'client_name') { echo $order_icon; } ?>
</a>
</th>
<?php } ?>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql)) {
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
$credential_id = intval($row['c_credential_id']);
$credential_name = nullable_htmlentities($row['credential_name']);
$credential_description = nullable_htmlentities($row['credential_description']);
$credential_uri = sanitize_url($row['credential_uri']);
if (empty($credential_uri)) {
$credential_uri_display = "-";
} else {
$credential_uri_display = "<a href='$credential_uri'>" . truncate($credential_uri,40) . "</a><button class='btn btn-sm clipboardjs' type='button' title='$credential_uri' data-clipboard-text='$credential_uri'><i class='far fa-copy text-secondary'></i></button>";
}
$credential_uri_2 = sanitize_url($row['credential_uri_2']);
$credential_username = nullable_htmlentities(decryptCredentialEntry($row['credential_username']));
if (empty($credential_username)) {
$credential_username_display = "-";
} else {
$credential_username_display = "$credential_username<button class='btn btn-sm clipboardjs' type='button' data-clipboard-text='$credential_username'><i class='far fa-copy text-secondary'></i></button>";
}
$credential_password = nullable_htmlentities(decryptCredentialEntry($row['credential_password']));
$credential_otp_secret = nullable_htmlentities($row['credential_otp_secret']);
$credential_id_with_secret = '"' . $row['credential_id'] . '","' . $row['credential_otp_secret'] . '"';
if (empty($credential_otp_secret)) {
$otp_display = "-";
} else {
$otp_display = "<span onmouseenter='showOTPViaCredentialID($credential_id)'><i class='far fa-clock'></i> <span id='otp_$credential_id'><i>Hover..</i></span></span>";
}
$credential_note = nullable_htmlentities($row['credential_note']);
$credential_created_at = nullable_htmlentities($row['credential_created_at']);
$credential_archived_at = nullable_htmlentities($row['credential_archived_at']);
$credential_important = intval($row['credential_important']);
$credential_contact_id = intval($row['credential_contact_id']);
$contact_name = nullable_htmlentities($row['contact_name']);
$credential_asset_id = intval($row['credential_asset_id']);
$asset_name = nullable_htmlentities($row['asset_name']);
// Tags
$credential_tag_name_display_array = array();
$credential_tag_id_array = array();
$sql_credential_tags = mysqli_query($mysqli, "SELECT * FROM credential_tags LEFT JOIN tags ON credential_tags.tag_id = tags.tag_id WHERE credential_id = $credential_id ORDER BY tag_name ASC");
while ($row = mysqli_fetch_array($sql_credential_tags)) {
$credential_tag_id = intval($row['tag_id']);
$credential_tag_name = nullable_htmlentities($row['tag_name']);
$credential_tag_color = nullable_htmlentities($row['tag_color']);
if (empty($credential_tag_color)) {
$credential_tag_color = "dark";
}
$credential_tag_icon = nullable_htmlentities($row['tag_icon']);
if (empty($credential_tag_icon)) {
$credential_tag_icon = "tag";
}
$credential_tag_id_array[] = $credential_tag_id;
$credential_tag_name_display_array[] = "<a href='credentials.php?$client_url tags[]=$credential_tag_id'><span class='badge text-light p-1 mr-1' style='background-color: $credential_tag_color;'><i class='fa fa-fw fa-$credential_tag_icon mr-2'></i>$credential_tag_name</span></a>";
}
$credential_tags_display = implode('', $credential_tag_name_display_array);
if ($credential_contact_id) {
$credential_contact_display = "<a href='#' class='mr-2 mb-1 badge badge-pill badge-dark p-2 ajax-modal' title='$contact_name'
data-modal-size='lg'
data-modal-url='modals/contact/contact_details.php?id=$credential_contact_id'>
<i class='fas fa-fw fa-user'></i></a>";
} else {
$credential_contact_display = '';
}
if ($credential_asset_id) {
$credential_asset_display = "<a href='#' class='mr-2 mb-1 badge badge-pill badge-secondary p-2 ajax-modal' title='$asset_name' data-toggle=''
data-modal-size='lg'
data-modal-url='modals/asset/asset_details.php?id=$credential_asset_id'>
<i class='fas fa-fw fa-desktop'></i></a>";
} else {
$credential_asset_display = '';
}
// Check if shared
$sql_shared = mysqli_query(
$mysqli,
"SELECT * FROM shared_items
WHERE item_client_id = $client_id
AND item_active = 1
AND item_views != item_view_limit
AND item_expire_at > NOW()
AND item_type = 'Credential'
AND item_related_id = $credential_id
LIMIT 1"
);
if (mysqli_num_rows($sql_shared) > 0) {
$row = mysqli_fetch_array($sql_shared);
$item_id = intval($row['item_id']);
$item_active = nullable_htmlentities($row['item_active']);
$item_key = nullable_htmlentities($row['item_key']);
$item_type = nullable_htmlentities($row['item_type']);
$item_related_id = intval($row['item_related_id']);
$item_note = nullable_htmlentities($row['item_note']);
$item_recipient = nullable_htmlentities($row['item_recipient']);
$item_views = nullable_htmlentities($row['item_views']);
$item_view_limit = nullable_htmlentities($row['item_view_limit']);
$item_created_at = nullable_htmlentities($row['item_created_at']);
$item_expire_at = nullable_htmlentities($row['item_expire_at']);
$item_expire_at_human = timeAgo($row['item_expire_at']);
}
?>
<tr class="<?php if (!empty($credential_important)) { echo "text-bold"; } ?>">
<td class="pr-0">
<div class="form-check">
<input class="form-check-input bulk-select" type="checkbox" name="credential_ids[]" value="<?php echo $credential_id ?>">
</div>
</td>
<td>
<a class="text-dark ajax-modal" href="#"
data-modal-url="modals/credential/credential_edit.php?id=<?= $credential_id ?>">
<div class="media">
<i class="fa fa-fw fa-2x fa-key mr-3"></i>
<div class="media-body">
<div><?php echo $credential_name; ?></div>
<div><small class="text-secondary"><?php echo $credential_description; ?></small></div>
<?php
if (!empty($credential_tags_display)) { ?>
<div class="mt-1">
<?php echo $credential_tags_display; ?>
</div>
<?php } ?>
</div>
</div>
</a>
</td>
<td class="text-nowrap"><?php echo $credential_username_display; ?></td>
<td class="text-nowrap">
<button class="btn p-0" type="button" data-toggle="popover" data-trigger="focus" data-placement="top" data-content="<?php echo $credential_password; ?>"><i class="fas fa-2x fa-ellipsis-h text-secondary"></i><i class="fas fa-2x fa-ellipsis-h text-secondary"></i></button><button class="btn btn-sm clipboardjs" type="button" data-clipboard-text="<?php echo $credential_password; ?>"><i class="far fa-copy text-secondary"></i></button>
</td>
<td class="text-nowrap"><?php echo $otp_display; ?></td>
<td><?php echo $credential_uri_display; ?></td>
<td>
<?php echo "$credential_contact_display$credential_asset_display"; ?>
<?php if (mysqli_num_rows($sql_shared) > 0) { ?>
<div class="media" title="Expires <?php echo $item_expire_at_human; ?>">
<i class="fas fa-link mr-2 mt-1"></i>
<div class="media-body">Shared
<br>
<small class="text-secondary"><?php echo $item_recipient; ?></small>
</div>
</div>
<?php } ?>
</td>
<?php if (!$client_url) { ?>
<td><a href="credentials.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
<?php } ?>
<td class="text-center">
<div class="btn-group">
<?php if ( !empty($credential_uri) || !empty($credential_uri_2) ) { ?>
<div class="dropdown dropleft text-center">
<button class="btn btn-default btn-sm" type="button" data-toggle="dropdown">
<i class="fa fa-fw fa-external-link-alt"></i>
</button>
<div class="dropdown-menu">
<?php if ($credential_uri) { ?>
<a href="<?php echo $credential_uri; ?>" alt="<?php echo $credential_uri; ?>" target="_blank" class="dropdown-item" >
<i class="fa fa-fw fa-external-link-alt"></i> <?php echo truncate($credential_uri,40); ?>
</a>
<?php } ?>
<?php if ($credential_uri_2) { ?>
<div class="dropdown-divider"></div>
<a href="<?php echo $credential_uri_2; ?>" target="_blank" class="dropdown-item" >
<i class="fa fa-fw fa-external-link-alt"></i> <?php echo truncate($credential_uri_2,40); ?>
</a>
<?php } ?>
</div>
</div>
<?php } ?>
<div class="dropdown dropleft text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i>
</button>
<div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/credential/credential_edit.php?id=<?= $credential_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit
</a>
<div class="dropdown-divider"></div>
<?php if ($client_url) { ?>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#shareModal" onclick="populateShareModal(<?php echo "$client_id, 'Credential', $credential_id"; ?>)">
<i class="fas fa-fw fa-share mr-2"></i>Share
</a>
<?php } ?>
<?php if (lookupUserPermission("module_credential") >= 2) { ?>
<?php if ($credential_archived_at) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-info confirm-link" href="post.php?unarchive_credential=<?php echo $credential_id; ?>">
<i class="fas fa-fw fa-redo mr-2"></i>Unarchive
</a>
<?php if (lookupUserPermission("module_credential") >= 3) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_credential=<?php echo $credential_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
<?php } ?>
</a>
<?php } else { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_credential=<?php echo $credential_id; ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</a>
<?php } ?>
<?php } ?>
</div>
</div>
</div>
</td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
<?php require_once "modals/credential/credential_bulk_assign_tags.php"; ?>
</form>
<?php require_once "../includes/filter_footer.php";
?>
</div>
</div>
<!-- Include script to get TOTP code via the login ID -->
<script src="js/credential_show_otp_via_id.js"></script>
<!-- Include script to generate readable passwords for login entries -->
<script src="js/generate_password.js"></script>
<script src="../js/bulk_actions.js"></script>
<?php
require_once "modals/credential/credential_add.php";
require_once "modals/credential/credential_export.php";
if ($client_url) {
require_once "modals/credential/credential_import.php";
require_once "modals/share_modal.php";
}
require_once "../includes/footer.php";

View File

@@ -0,0 +1,15 @@
/*!
* AdminLTE 3.2.0 Specific Dropdown Fix
* Targets .fix-quote-dropdown only
* Prevents alignment bugs in split button dropdowns going too far left
* (ChatGPT)
*/
.fix-quote-dropdown .dropdown-menu {
left: auto !important;
right: 0 !important;
top: calc(100% + 0.25rem) !important;
transform: none !important;
min-width: max-content;
z-index: 1050;
}

View File

@@ -0,0 +1,83 @@
/* General Popover Styling */
.popover {
max-width: 600px;
}
/* Kanban Board Container */
#kanban-board {
display: flex;
overflow-x: auto;
box-sizing: border-box;
min-width: 400px;
height: calc(100vh - 210px);
}
/* Kanban Column */
.kanban-column {
flex: 1;
min-width: 300px;
max-width: 300px;
margin: 0 10px;
background: #f4f4f4;
border: 1px solid #ccc;
border-radius: 4px;
padding: 10px;
min-height: calc(100vh - 230px);
max-height: calc(100vh - 230px);
box-sizing: border-box;
display: flex;
flex-direction: column;
}
/* Column Inner Scrollable Task Area */
.kanban-status {
flex: 1;
overflow-y: auto;
min-height: 60px;
position: relative;
padding: 5px;
background-color: #f9f9f9;
border-radius: 4px;
}
/* Individual Task Cards */
.task {
background: #fff;
margin: 5px 0;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
cursor: grab;
user-select: none;
}
/* Grabbing Cursor State */
.task:active {
cursor: grabbing;
}
/* Drag Handle (shown on mobile or with class targeting) */
.drag-handle-class {
float: right;
touch-action: none;
cursor: grab;
}
/* Placeholder shown in empty columns */
.empty-placeholder {
border: 2px dashed #ccc;
background-color: #fcfcfc;
color: #999;
font-style: italic;
padding: 12px;
margin: 10px 0;
text-align: center;
border-radius: 4px;
pointer-events: none;
}
/* Sortable drop zone feedback (optional visual cue) */
.kanban-status.sortable-over {
background-color: #eaf6ff;
transition: background-color 0.2s ease;
}

72
agent/custom/index.php Normal file
View File

@@ -0,0 +1,72 @@
<?php require_once "includes/inc_all.php"; ?>
<!-- Breadcrumbs-->
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="index.html">Dashboard</a>
</li>
<li class="breadcrumb-item active">Blank Page</li>
</ol>
<!-- Page Content -->
<h1>Blank Page</h1>
<hr>
<p>This is a great starting point for new custom pages.</p>
<h1><?php echo $session_user_role; ?></h1>
<?php validateAdminRole(); ?>
<?php
$start_date = date('Y') . "-10-10";
echo "<H1>$start_date</H1>";
echo "<H2>User Agent</H2>";
echo getUserAgent();
?>
<br>
<input type="tel" name="phone" id="phone">
<div class="form-group">
<label>Minimal</label>
<select class="form-control select2 select2-hidden-accessible" style="width: 100%;" data-select2-id="1" tabindex="-1" aria-hidden="true">
<option selected="selected" data-select2-id="3">Alabama</option>
<option data-select2-id="35">Alaska</option>
<option data-select2-id="36">California</option>
<option data-select2-id="37">Delaware</option>
<option data-select2-id="38">Tennessee</option>
<option data-select2-id="39">Texas</option>
<option data-select2-id="40">Washington</option>
</select><span class="select2 select2-container select2-container--default select2-container--below" dir="ltr" data-select2-id="2" style="width: 100%;"><span class="selection"><span class="select2-selection select2-selection--single" role="combobox" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-disabled="false" aria-labelledby="select2-nbex-container"><span class="select2-selection__rendered" id="select2-nbex-container" role="textbox" aria-readonly="true" title="Alabama">Alabama</span><span class="select2-selection__arrow" role="presentation"><b role="presentation"></b></span></span></span><span class="dropdown-wrapper" aria-hidden="true"></span></span>
</div>
<dl>
<dt>Requester</dt>
<dd>Sam Adams</dd>
<dt>Created</dt>
<dd><time datetime="2024-04-11T17:52:30+00:00" title="2024-04-11 13:52" data-datetime="calendar">Today at 13:52</time></dd>
<dt>Last activity</dt>
<dd><time datetime="2024-04-11T18:08:55+00:00" title="2024-04-11 14:08" data-datetime="calendar">Today at 14:08</time></dd>
</dl>
<?php echo randomString(100); ?>
<br>
<textarea class="tinymceTest"></textarea>
<textarea class="tinymce"></textarea>
<textarea class="tinymceTicket"></textarea>
<?php
// show the current Date and Time
$date_time = date('Y-m-d H:i:s');
echo "Current Date and Time: <strong>$date_time</strong>";
?>
<script>toastr.success('Have Fun Wozz!!')</script>
<?php require_once "../includes/footer.php";

9
agent/custom/readme.php Normal file
View File

@@ -0,0 +1,9 @@
<?php
/*
- Custom Pages -
If you wish to add custom pages to ITFlow, add them to this directory"
*/

1169
agent/dashboard.php Normal file

File diff suppressed because it is too large Load Diff

415
agent/document_details.php Normal file
View File

@@ -0,0 +1,415 @@
<?php
require_once "includes/inc_all_client.php";
//Initialize the HTML Purifier to prevent XSS
require "../plugins/htmlpurifier/HTMLPurifier.standalone.php";
$purifier_config = HTMLPurifier_Config::createDefault();
$purifier_config->set('Cache.DefinitionImpl', null); // Disable cache by setting a non-existent directory or an invalid one
$purifier_config->set('URI.AllowedSchemes', ['data' => true, 'src' => true, 'http' => true, 'https' => true]);
$purifier = new HTMLPurifier($purifier_config);
if (isset($_GET['document_id'])) {
$document_id = intval($_GET['document_id']);
}
$folder_location = 0;
$sql_document = mysqli_query($mysqli, "SELECT * FROM documents
LEFT JOIN folders ON document_folder_id = folder_id
LEFT JOIN users ON document_created_by = user_id
WHERE document_client_id = $client_id AND document_id = $document_id"
);
$row = mysqli_fetch_array($sql_document);
$folder_name = nullable_htmlentities($row['folder_name']);
$document_name = nullable_htmlentities($row['document_name']);
$document_description = nullable_htmlentities($row['document_description']);
$document_content = $purifier->purify($row['document_content']);
$document_created_by_id = intval($row['document_created_by']);
$document_created_by_name = nullable_htmlentities($row['user_name']);
$document_created_at = nullable_htmlentities($row['document_created_at']);
$document_updated_at = nullable_htmlentities($row['document_updated_at']);
$document_archived_at = nullable_htmlentities($row['document_archived_at']);
$document_folder_id = intval($row['document_folder_id']);
$document_client_visible = intval($row['document_client_visible']);
// Override Tab Title // No Sanitizing needed as this var will opnly be used in the tab title
$page_title = $row['document_name'];
?>
<ol class="breadcrumb d-print-none">
<li class="breadcrumb-item">
<a href="client_overview.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a>
</li>
<li class="breadcrumb-item">
<a href="documents.php?client_id=<?php echo $client_id; ?>">Documents</a>
</li>
<?php
// Build the full folder path
$folder_id = $document_folder_id;
$folder_path = array();
while ($folder_id > 0) {
$sql_folder = mysqli_query($mysqli, "SELECT folder_name, parent_folder FROM folders WHERE folder_id = $folder_id");
if ($row_folder = mysqli_fetch_assoc($sql_folder)) {
$folder_name = nullable_htmlentities($row_folder['folder_name']);
$parent_folder = intval($row_folder['parent_folder']);
// Prepend the folder to the beginning of the array
array_unshift($folder_path, array('folder_id' => $folder_id, 'folder_name' => $folder_name));
// Move up to the parent folder
$folder_id = $parent_folder;
} else {
// If the folder is not found, break the loop
break;
}
}
// Output breadcrumb items for each folder in the path
foreach ($folder_path as $folder) {
$bread_crumb_folder_id = $folder['folder_id']; // Sanitized before put in array
$bread_crumb_folder_name = $folder['folder_name']; // Sanitized before put in array
?>
<li class="breadcrumb-item">
<a href="documents.php?client_id=<?php echo $client_id; ?>&folder_id=<?php echo $bread_crumb_folder_id; ?>">
<i class="fas fa-fw fa-folder-open mr-2"></i><?php echo $bread_crumb_folder_name; ?>
</a>
</li>
<?php
}
?>
<li class="breadcrumb-item active">
<i class="fas fa-file"></i> <?php echo $document_name; ?>
<?php if (!empty($document_archived_at)) {
echo "<span class='text-danger ml-2'>(ARCHIVED on $document_archived_at)</span>";
} ?>
</li>
</ol>
<div class="row">
<div class="col-md-9">
<div class="card">
<div class="card-header bg-dark">
<h3><?php echo $document_name; ?> <?php if (!empty($document_description)) { ?><span class="h6 text-muted">(<?php echo $document_description; ?>)</span><?php } ?></h3>
<div class="row">
<div class="col"><strong>Date:</strong> <?php echo date('Y-m-d', strtotime($document_created_at)); ?></div>
<?php if(!empty($document_created_by_name)){ ?>
<div class="col"><strong>Prepared By:</strong> <?php echo $document_created_by_name; ?></div>
<?php } ?>
</div>
</div>
<div class="card-body prettyContent">
<?php echo $document_content; ?>
<hr>
<h4>Documentation Revision History</h4>
<table class="table table-sm">
<thead class="thead-light">
<th>Version</th>
<th>Date</th>
<th>Name</th>
<th>Description</th>
<th>Author</th>
</thead>
<tbody>
<?php
$sql_document_versions = mysqli_query($mysqli, "SELECT * FROM document_versions
LEFT JOIN users ON document_version_created_by = user_id
WHERE document_version_document_id = $document_id
ORDER BY document_version_created_at ASC"
);
$document_version_count = 1; // Initialize the document version counter
while ($row = mysqli_fetch_array($sql_document_versions)) {
$document_version_id = intval($row['document_version_id']);
$document_version_name = nullable_htmlentities($row['document_version_name']);
$document_version_description = nullable_htmlentities($row['document_version_description']);
if ($document_version_description ) {
$document_version_description_display = $document_version_description;
} else {
$document_version_description_display = "-";
}
$document_version_author = nullable_htmlentities($row['user_name']);
$document_version_created_date = date('Y-m-d', strtotime($row['document_version_created_at']));
?>
<tr>
<td><?php echo $document_version_count; ?></td>
<td><?php echo $document_version_created_date; ?></td>
<td><?php echo $document_version_name; ?></td>
<td><?php echo $document_version_description_display; ?></td>
<td><?php echo $document_version_author; ?></td>
</tr>
<?php
$document_version_count++; // Increment the counter
}
?>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-md-3 d-print-none">
<div class="row">
<div class="col-12 mb-3">
<button type="button" class="btn btn-primary ajax-modal mr-2"
data-modal-size="lg"
data-modal-url="modals/document/document_edit.php?id=<?= $document_id ?>">
<i class="fas fa-fw fa-edit"></i>
</button>
<button type="button" class="btn btn-secondary mr-2" data-toggle="modal" data-target="#shareModal"
onclick="populateShareModal(<?php echo "$client_id, 'Document', $document_id"; ?>)">
<i class="fas fa-fw fa-share"></i>
</button>
<a class="btn btn-success mr-2" href="post.php?export_document=<?php echo $document_id; ?>"><i class='fas fa-fw fa-file-pdf'></i></a>
<button type="button" class="btn btn-secondary" onclick="window.print();"><i class="fas fa-fw fa-print"></i></button>
</div>
</div>
<div class="card card-body bg-light">
<h5 class="mb-3"><i class="fas fa-tags mr-2"></i>Related Items</h5>
<h6>
<i class="fas fa-fw fa-paperclip text-secondary mr-2"></i>Files
<button type="button" class="btn btn-link btn-sm" data-toggle="modal" data-target="#linkFileToDocumentModal">
<i class="fas fa-fw fa-plus"></i>
</button>
</h6>
<?php
$sql_files = mysqli_query($mysqli, "SELECT * FROM files, document_files
WHERE document_files.file_id = files.file_id
AND document_files.document_id = $document_id
ORDER BY file_name ASC"
);
$linked_files = array();
while ($row = mysqli_fetch_array($sql_files)) {
$file_id = intval($row['file_id']);
$folder_id = intval($row['file_folder_id']);
$file_name = nullable_htmlentities($row['file_name']);
$linked_files[] = $file_id;
?>
<div class="ml-2">
<a href="files.php?client_id=<?php echo $client_id; ?>&folder_id=<?php echo $folder_id; ?>&q=<?php echo $file_name; ?>" target="_blank"><?php echo $file_name; ?></a>
<a class="confirm-link" href="post.php?unlink_file_from_document&file_id=<?php echo $file_id; ?>&document_id=<?php echo $document_id; ?>">
<i class="fas fa-fw fa-trash-alt text-secondary float-right"></i>
</a>
</div>
<?php
}
?>
<h6>
<i class="fas fa-fw fa-users text-secondary mt-3 mr-2"></i>Contacts
<button type="button" class="btn btn-link btn-sm" data-toggle="modal" data-target="#linkContactToDocumentModal">
<i class="fas fa-fw fa-plus"></i>
</button>
</h6>
<?php
$sql_contacts = mysqli_query($mysqli, "SELECT contacts.contact_id, contact_name FROM contacts, contact_documents
WHERE contacts.contact_id = contact_documents.contact_id
AND contact_documents.document_id = $document_id
ORDER BY contact_name ASC"
);
$linked_contacts = array();
while ($row = mysqli_fetch_array($sql_contacts)) {
$contact_id = intval($row['contact_id']);
$contact_name = nullable_htmlentities($row['contact_name']);
$linked_contacts[] = $contact_id;
?>
<div class="ml-2">
<a class="ajax-modal" href="#"
data-modal-size="lg"
data-modal-url="modals/contact/contact_details.php?id=<?= $contact_id ?>">
<?php echo $contact_name; ?></a>
<a class="confirm-link float-right" href="post.php?unlink_contact_from_document&contact_id=<?php echo $contact_id; ?>&document_id=<?php echo $document_id; ?>">
<i class="fas fa-fw fa-trash-alt text-secondary"></i>
</a>
</div>
<?php
}
?>
<h6>
<i class="fas fa-fw fa-laptop text-secondary mr-2 mt-3"></i>Assets
<button type="button" class="btn btn-link btn-sm" data-toggle="modal" data-target="#linkAssetToDocumentModal">
<i class="fas fa-fw fa-plus"></i>
</button>
</h6>
<?php
$sql_assets = mysqli_query($mysqli, "SELECT assets.asset_id, asset_name FROM assets, asset_documents
WHERE assets.asset_id = asset_documents.asset_id
AND asset_documents.document_id = $document_id
ORDER BY asset_name ASC"
);
$linked_assets = array();
while ($row = mysqli_fetch_array($sql_assets)) {
$asset_id = intval($row['asset_id']);
$asset_name = nullable_htmlentities($row['asset_name']);
$linked_assets[] = $asset_id;
?>
<div class="ml-2">
<a class="ajax-modal" href="#"
data-modal-size="lg"
data-modal-url="modals/asset/asset_details.php?id=<?= $asset_id ?>">
<?php echo $asset_name; ?>
</a>
<a class="confirm-link float-right" href="post.php?unlink_asset_from_document&asset_id=<?php echo $asset_id; ?>&document_id=<?php echo $document_id; ?>">
<i class="fas fa-fw fa-trash-alt text-secondary"></i>
</a>
</div>
<?php
}
?>
<h6>
<i class="fas fa-fw fa-cube text-secondary mr-2 mt-3"></i>Licenses
<button type="button" class="btn btn-link btn-sm" data-toggle="modal" data-target="#linkSoftwareToDocumentModal">
<i class="fas fa-fw fa-plus"></i>
</button>
</h6>
<?php
$sql_software = mysqli_query($mysqli, "SELECT software.software_id, software_name FROM software, software_documents
WHERE software.software_id = software_documents.software_id
AND software_documents.document_id = $document_id
ORDER BY software_name ASC"
);
$linked_software = array();
while ($row = mysqli_fetch_array($sql_software)) {
$software_id = intval($row['software_id']);
$software_name = nullable_htmlentities($row['software_name']);
$linked_software[] = $software_id;
?>
<div class="ml-2">
<a href="software.php?client_id=<?php echo $client_id; ?>&q=<?php echo $software_name; ?>" target="_blank"><?php echo $software_name; ?></a>
<a class="confirm-link float-right" href="post.php?unlink_software_from_document&software_id=<?php echo $software_id; ?>&document_id=<?php echo $document_id; ?>">
<i class="fas fa-fw fa-trash-alt text-secondary"></i>
</a>
</div>
<?php
}
?>
<h6>
<i class="fas fa-fw fa-building text-secondary mr-2 mt-3"></i>Vendors
<button type="button" class="btn btn-link btn-sm" data-toggle="modal" data-target="#linkVendorToDocumentModal">
<i class="fas fa-fw fa-plus"></i>
</button>
</h6>
<?php
$sql_vendors = mysqli_query($mysqli, "SELECT vendors.vendor_id, vendor_name FROM vendors, vendor_documents
WHERE vendors.vendor_id = vendor_documents.vendor_id
AND vendor_documents.document_id = $document_id
ORDER BY vendor_name ASC"
);
$associated_vendors = array();
while ($row = mysqli_fetch_array($sql_vendors)) {
$vendor_id = intval($row['vendor_id']);
$vendor_name = nullable_htmlentities($row['vendor_name']);
$associated_vendors[] = $vendor_id;
?>
<div class="ml-2">
<a class="ajax-modal" href="#" data-modal-url="modals/vendor/vendor_details.php?id=<?= $vendor_id ?>">
<?php echo $vendor_name; ?>
</a>
<a class="confirm-link float-right" href="post.php?unlink_vendor_from_document&vendor_id=<?php echo $vendor_id; ?>&document_id=<?php echo $document_id; ?>">
<i class="fas fa-fw fa-trash-alt text-secondary"></i>
</a>
</div>
<?php
}
?>
</div>
<?php if ($config_client_portal_enable) { ?>
<div class="card card-body bg-light">
<h6><i class="fas fa-handshake mr-2"></i>Portal Collaboration</h6>
<div class="mt-1">
<i class="fa fa-fw fa-eye<?php if (!$document_client_visible) { echo '-slash'; } ?> text-secondary mr-2"></i>Document is
<a href="#" data-toggle="modal" data-target="#editDocumentClientVisibileModal">
<?php
if ($document_client_visible) {
echo "<span class='text-bold text-dark'>visible</span>";
} else {
echo "<span class='text-muted'>not visible</span>";
}
?>
</a>
</div>
</div>
<?php } ?>
<div class="card card-body bg-light">
<h6><i class="fas fa-history mr-2"></i>Revisions</h6>
<?php
$sql_document_versions = mysqli_query($mysqli, "SELECT * FROM document_versions
LEFT JOIN users ON document_version_created_by = user_id
WHERE document_version_document_id = $document_id
ORDER BY document_version_created_at DESC"
);
while ($row = mysqli_fetch_array($sql_document_versions)) {
$document_version_id = intval($row['document_version_id']);
$document_version_name = nullable_htmlentities($row['document_version_name']);
$document_version_description = nullable_htmlentities($row['document_version_description']);
$document_version_author = nullable_htmlentities($row['user_name']);
$document_version_created_date = nullable_htmlentities($row['document_version_created_at']);
?>
<div class="mt-1 <?php if($document_id === $document_version_id){ echo "text-bold"; } ?>">
<i class="fas fa-fw fa-history text-secondary mr-2"></i>
<a class="ajax-modal" href="#"
data-modal-size="lg"
data-modal-url="modals/document/document_version_view.php?id=<?= $document_version_id ?>">
<?php echo "$document_version_created_date | $document_version_author"; ?>
</a>
<a class="confirm-link float-right" href="post.php?delete_document_version=<?php echo $document_version_id; ?>">
<i class="fas fa-fw fa-trash-alt text-secondary"></i>
</a>
</div>
<?php
}
?>
</div>
</div>
</div>
<script src="../js/pretty_content.js"></script>
<?php
require_once "modals/document/document_link_file.php";
require_once "modals/document/document_link_contact.php";
require_once "modals/document/document_link_asset.php";
require_once "modals/document/document_link_software.php";
require_once "modals/document/document_link_vendor.php";
require_once "modals/document/document_edit_visibility.php";
require_once "modals/share_modal.php";
require_once "../includes/footer.php";

484
agent/documents.php Normal file
View File

@@ -0,0 +1,484 @@
<?php
// Default Column Sortby Filter
$sort = "document_name";
$order = "ASC";
require_once "includes/inc_all_client.php";
// Perms
enforceUserPermission('module_support');
// Folder
if (!empty($_GET['folder_id'])) {
$folder = intval($_GET['folder_id']);
} else {
$folder = 0;
}
// Search query SQL snippet
if (!empty($q)) {
$query_snippet = "AND (MATCH(document_content_raw) AGAINST ('$q') OR document_name LIKE '%$q%')";
} else {
$query_snippet = ""; // empty
}
//Rebuild URL
$url_query_strings_sort = http_build_query($get_copy);
// Folder ID
$get_folder_id = 0;
if (!empty($_GET['folder_id'])) {
$get_folder_id = intval($_GET['folder_id']);
}
// Set Folder Location Var used when creating folders
$folder_location = 0;
if ($get_folder_id == 0 && isset($_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_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_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()"));
// Breadcrumbs
// Build the full folder path
$folder_id = $get_folder_id;
$folder_path = array();
while ($folder_id > 0) {
$sql_folder = mysqli_query($mysqli, "SELECT folder_name, parent_folder FROM folders WHERE folder_id = $folder_id");
if ($row_folder = mysqli_fetch_assoc($sql_folder)) {
$folder_name = nullable_htmlentities($row_folder['folder_name']);
$parent_folder = intval($row_folder['parent_folder']);
// Prepend the folder to the beginning of the array
array_unshift($folder_path, array('folder_id' => $folder_id, 'folder_name' => $folder_name));
// Move up to the parent folder
$folder_id = $parent_folder;
} else {
// If the folder is not found, break the loop
break;
}
}
?>
<div class="card card-dark">
<div class="card-header py-2">
<h3 class="card-title mt-2">
<i class="fa fa-fw fa-folder mr-2"></i>Documents
</h3>
<div class="card-tools">
<div class="btn-group">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addDocumentModal">
<i class="fas fa-plus mr-2"></i>New Document
</button>
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#createFolderModal">
<i class="fa fa-fw fa-folder-plus mr-2"></i>New Folder
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#addDocumentFromTemplateModal">From Template</a>
</div>
</div>
</div>
</div>
<div class="card-body">
<form autocomplete="off">
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<input type="hidden" name="folder_id" value="<?php echo $get_folder_id; ?>">
<div class="row">
<div class="col-md-4">
<div class="input-group mb-3 mb-md-0">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search documents in <?php if($get_folder_id == 0) { echo "all folders"; } else { echo "current folder"; } ?>">
<div class="input-group-append">
<button class="btn btn-dark"><i class="fa fa-search"></i></button>
</div>
</div>
</div>
<div class="col-md-8">
<div class="btn-group float-right">
<div class="dropdown ml-2" id="bulkActionButton" hidden>
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">
<i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>)
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkMoveDocumentModal">
<i class="fas fa-fw fa-exchange-alt mr-2"></i>Move
</a>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-danger text-bold"
type="submit" form="bulkActions" name="bulk_delete_documents">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</button>
</div>
</div>
</div>
</div>
</div>
</form>
<hr>
<div class="row">
<div class="col-md-3 border-right mb-3">
<h4>Folders</h4>
<hr>
<ul class="nav nav-pills flex-column bg-light">
<li class="nav-item">
<div class="row">
<div class="col-10">
<?php
// Get a count of documents that have no folder
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('document_id') AS num FROM documents WHERE document_folder_id = 0 AND document_client_id = $client_id AND document_archived_at IS NULL"));
$num_documents = intval($row['num']);
?>
<a class="nav-link <?php if ($get_folder_id == 0) { echo "active"; } ?>" href="?client_id=<?php echo $client_id; ?>&folder_id=0">
/ <?php if ($num_documents > 0) { echo "<span class='badge badge-pill badge-dark float-right mt-1'>$num_documents</span>"; } ?>
</a>
</div>
<div class="col-2">
</div>
</div>
</li>
<?php
// Function to check if a folder is an ancestor of the current folder
function is_ancestor_folder($folder_id, $current_folder_id, $client_id) {
global $mysqli;
// Base case: if current_folder_id is 0 or equal to folder_id
if ($current_folder_id == 0) {
return false;
}
if ($current_folder_id == $folder_id) {
return true;
}
// Get the parent folder of the current folder
$result = mysqli_query($mysqli, "SELECT parent_folder FROM folders WHERE folder_id = $current_folder_id AND folder_client_id = $client_id");
if ($row = mysqli_fetch_assoc($result)) {
$parent_folder_id = intval($row['parent_folder']);
// Recursive call to check the parent folder
return is_ancestor_folder($folder_id, $parent_folder_id, $client_id);
} else {
// Folder not found
return false;
}
}
// Recursive function to display folders and subfolders
function display_folders($parent_folder_id, $client_id, $indent = 0) {
global $mysqli, $get_folder_id, $session_user_role;
$sql_folders = mysqli_query($mysqli, "SELECT * FROM folders WHERE parent_folder = $parent_folder_id AND folder_location = 0 AND folder_client_id = $client_id ORDER BY folder_name ASC");
while ($row = mysqli_fetch_array($sql_folders)) {
$folder_id = intval($row['folder_id']);
$folder_name = nullable_htmlentities($row['folder_name']);
// Get the number of documents in the folder
$row2 = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('document_id') AS num FROM documents WHERE document_folder_id = $folder_id AND document_archived_at IS NULL"));
$num_documents = intval($row2['num']);
// Get the number of subfolders
$subfolder_result = mysqli_query($mysqli, "SELECT COUNT(*) AS count FROM folders WHERE parent_folder = $folder_id AND folder_client_id = $client_id");
$subfolder_count = intval(mysqli_fetch_assoc($subfolder_result)['count']);
echo '<li class="nav-item">';
echo '<div class="row">';
echo '<div class="col-10">';
echo '<a class="nav-link ';
if ($get_folder_id == $folder_id) { echo "active"; }
echo '" href="?client_id=' . $client_id . '&folder_id=' . $folder_id . '">';
// Indentation for subfolders
echo str_repeat('&nbsp;', $indent * 4);
// Determine if the folder is open
if ($get_folder_id == $folder_id || is_ancestor_folder($folder_id, $get_folder_id, $client_id)) {
echo '<i class="fas fa-fw fa-folder-open"></i>';
} else {
echo '<i class="fas fa-fw fa-folder"></i>';
}
echo ' ' . $folder_name;
if ($num_documents > 0) {
echo "<span class='badge badge-pill badge-dark float-right mt-1'>$num_documents</span>";
}
echo '</a>';
echo '</div>';
echo '<div class="col-2">';
?>
<div class="dropdown">
<button class="btn btn-sm" type="button" data-toggle="dropdown">
<i class="fas fa-ellipsis-v"></i>
</button>
<div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/folder/folder_rename.php?id=<?= $folder_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Rename
</a>
<?php
// Only show delete option if user is admin, folder has no documents, and no subfolders
if ($session_user_role == 3 && $num_documents == 0 && $subfolder_count == 0) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_folder=<?php echo $folder_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</a>
<?php } ?>
</div>
</div>
<?php
echo '</div>';
echo '</div>';
if ($subfolder_count > 0) {
// Display subfolders
echo '<ul class="nav nav-pills flex-column bg-light">';
display_folders($folder_id, $client_id, $indent + 1);
echo '</ul>';
}
echo '</li>';
}
}
// Start displaying folders from the root (parent_folder = 0)
display_folders(0, $client_id);
?>
</ul>
<?php require_once "modals/folder/folder_add.php"; ?>
</div>
<div class="col-md-9">
<nav>
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="?client_id=<?php echo $client_id; ?>&folder_id=0">
<i class="fas fa-fw fa-folder mr-2"></i>Root
</a>
</li>
<?php
// Output breadcrumb items for each folder in the path
foreach ($folder_path as $folder) {
$bread_crumb_folder_id = $folder['folder_id']; // Already Sanitized before it was pushed into array
$bread_crumb_folder_name = $folder['folder_name']; // Already Sanitized before it was pushed into array
?>
<li class="breadcrumb-item">
<a href="?client_id=<?php echo $client_id; ?>&folder_id=<?php echo $bread_crumb_folder_id; ?>">
<i class="fas fa-fw fa-folder-open mr-2"></i><?php echo $bread_crumb_folder_name; ?>
</a>
</li>
<?php
}
?>
</ol>
</nav>
<form id="bulkActions" action="post.php" method="post">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<div class="table-responsive-sm">
<table class="table table-border">
<thead class="thead-light <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
<tr>
<td class="bg-light pr-0">
<div class="form-check">
<input class="form-check-input" id="selectAllCheckbox" type="checkbox" onclick="checkAll(this)">
</div>
</td>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=document_name&order=<?php echo $disp; ?>">
Name <?php if ($sort == 'document_name') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=document_created_at&order=<?php echo $disp; ?>">
Created <?php if ($sort == 'document_created_at') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=document_updated_at&order=<?php echo $disp; ?>">
Last Update <?php if ($sort == 'document_updated_at') { echo $order_icon; } ?>
</a>
</th>
<th></th>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql)) {
$document_id = intval($row['document_id']);
$document_name = nullable_htmlentities($row['document_name']);
$document_description = nullable_htmlentities($row['document_description']);
$document_content = nullable_htmlentities($row['document_content']);
$document_created_by_name = nullable_htmlentities($row['user_name']);
$document_created_at = date("m/d/Y",strtotime($row['document_created_at']));
if ($row['document_updated_at']) {
$document_updated_at_display = date("m/d/Y",strtotime($row['document_updated_at']));
} else {
$document_updated_at_display = "-";
}
$document_folder_id = intval($row['document_folder_id']);
// Check if shared
$sql_shared = mysqli_query(
$mysqli,
"SELECT * FROM shared_items
WHERE item_client_id = $client_id
AND item_active = 1
AND item_views != item_view_limit
AND item_expire_at > NOW()
AND item_type = 'Document'
AND item_related_id = $document_id
LIMIT 1"
);
$row = mysqli_fetch_array($sql_shared);
if($row) {
$item_id = intval($row['item_id']);
$item_active = nullable_htmlentities($row['item_active']);
$item_key = nullable_htmlentities($row['item_key']);
$item_type = nullable_htmlentities($row['item_type']);
$item_related_id = intval($row['item_related_id']);
$item_note = nullable_htmlentities($row['item_note']);
$item_recipient = nullable_htmlentities($row['item_recipient']);
$item_views = nullable_htmlentities($row['item_views']);
$item_view_limit = nullable_htmlentities($row['item_view_limit']);
$item_created_at = nullable_htmlentities($row['item_created_at']);
$item_expire_at = nullable_htmlentities($row['item_expire_at']);
$item_expire_at_human = timeAgo($row['item_expire_at']);
}
?>
<tr>
<td class="bg-light pr-0">
<div class="form-check">
<input class="form-check-input bulk-select" type="checkbox" name="document_ids[]" value="<?php echo $document_id ?>">
</div>
</td>
<td>
<a href="document_details.php?client_id=<?php echo $client_id; ?>&document_id=<?php echo $document_id; ?>"><i class="fas fa-fw fa-file-alt"></i> <?php echo $document_name; ?></a>
<div class="text-secondary mt-1"><?php echo $document_description; ?>
</td>
<td>
<?php echo $document_created_at; ?>
<div class="text-secondary mt-1"><?php echo $document_created_by_name; ?>
</td>
<td><?php echo $document_updated_at_display; ?></td>
<td>
<?php if (mysqli_num_rows($sql_shared) > 0) { ?>
<div class="media" title="Expires <?php echo $item_expire_at_human; ?>">
<i class="fas fa-link mr-2 mt-1"></i>
<div class="media-body">Shared
<br>
<small class="text-secondary"><?php echo $item_recipient; ?></small>
</div>
</div>
<?php } ?>
</td>
<td>
<div class="dropdown dropleft text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i>
</button>
<div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#"
data-modal-size="lg"
data-modal-url="modals/document/document_view.php?id=<?= $document_id ?>">
<i class="fas fa-fw fa-eye mr-2"></i>Quick View
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item ajax-modal" href="#"
data-modal-size="lg"
data-modal-url="modals/document/document_edit.php?id=<?= $document_id ?>">
<i class="fas fa-fw fa-pencil-alt mr-2"></i>Edit
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#shareModal" onclick="populateShareModal(<?php echo "$client_id, 'Document', $document_id"; ?>)">
<i class="fas fa-fw fa-share mr-2"></i>Share
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/document/document_rename.php?id=<?= $document_id ?>">
<i class="fas fa-fw fa-pencil-alt mr-2"></i>Rename
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/document/document_move.php?id=<?= $document_id ?>">
<i class="fas fa-fw fa-exchange-alt mr-2"></i>Move
</a>
<?php if ($session_user_role == 3) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_document=<?php echo $document_id; ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_document=<?php echo $document_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</a>
<?php } ?>
</div>
</div>
</td>
</tr>
<?php
}
?>
</tbody>
</table>
<br>
</div>
<?php require_once "modals/document/document_bulk_move.php"; ?>
</form>
<?php require_once "../includes/filter_footer.php";
?>
</div>
</div>
</div>
</div>
<script src="../js/bulk_actions.js"></script>
<?php
require_once "modals/share_modal.php";
require_once "modals/document/document_add.php";
require_once "modals/document/document_add_from_template.php";
require_once "../includes/footer.php";

371
agent/domains.php Normal file
View File

@@ -0,0 +1,371 @@
<?php
// Default Column Sortby Filter
$sort = "domain_name";
$order = "ASC";
// If client_id is in URI then show client Side Bar and client header
if (isset($_GET['client_id'])) {
require_once "includes/inc_all_client.php";
$client_query = "AND domain_client_id = $client_id";
$client_url = "client_id=$client_id&";
// Overide Filter Header Archived
if (isset($_GET['archived']) && $_GET['archived'] == 1) {
$archived = 1;
$archive_query = "domain_archived_at IS NOT NULL";
} else {
$archived = 0;
$archive_query = "domain_archived_at IS NULL";
}
} else {
require_once "includes/inc_client_overview_all.php";
$client_query = '';
$client_url = '';
// Overide Filter Header Archived
if (isset($_GET['archived']) && $_GET['archived'] == 1) {
$archived = 1;
$archive_query = "(client_archived_at IS NOT NULL OR domain_archived_at IS NOT NULL)";
} else {
$archived = 0;
$archive_query = "(client_archived_at IS NULL AND domain_archived_at IS NULL)";
}
}
// Perms
enforceUserPermission('module_support');
if (!$client_url) {
// Client Filter
if (isset($_GET['client']) & !empty($_GET['client'])) {
$client_query = 'AND (domain_client_id = ' . intval($_GET['client']) . ')';
$client = intval($_GET['client']);
} else {
// Default - any
$client_query = '';
$client = '';
}
}
$sql = mysqli_query($mysqli, "SELECT SQL_CALC_FOUND_ROWS domains.*, clients.*,
registrar.vendor_id AS registrar_id,
registrar.vendor_name AS registrar_name,
dnshost.vendor_id AS dnshost_id,
dnshost.vendor_name AS dnshost_name,
mailhost.vendor_id AS mailhost_id,
mailhost.vendor_name AS mailhost_name,
webhost.vendor_id AS webhost_id,
webhost.vendor_name AS webhost_name
FROM domains
LEFT JOIN clients ON client_id = domain_client_id
LEFT JOIN vendors AS registrar ON domains.domain_registrar = registrar.vendor_id
LEFT JOIN vendors AS dnshost ON domains.domain_dnshost = dnshost.vendor_id
LEFT JOIN vendors AS mailhost ON domains.domain_mailhost = mailhost.vendor_id
LEFT JOIN vendors AS webhost ON domains.domain_webhost = webhost.vendor_id
WHERE (domains.domain_name LIKE '%$q%' OR domains.domain_description LIKE '%$q%' OR registrar.vendor_name LIKE '%$q%' OR dnshost.vendor_name LIKE '%$q%' OR mailhost.vendor_name LIKE '%$q%' OR webhost.vendor_name LIKE '%$q%' OR client_name LIKE '%$q%')
AND $archive_query
$access_permission_query
$client_query
ORDER BY $sort $order LIMIT $record_from, $record_to");
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?>
<div class="card card-dark">
<div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fa fa-fw fa-globe mr-2"></i>Domains</h3>
<div class="card-tools">
<div class="btn-group">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addDomainModal"><i class="fas fa-plus mr-2"></i>New Domain</button>
<?php if ($num_rows[0] > 0) { ?>
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#exportDomainModal">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
</div>
<?php } ?>
</div>
</div>
</div>
<div class="card-body">
<form autocomplete="off">
<?php if ($client_url) { ?>
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<?php } ?>
<input type="hidden" name="archived" value="<?php echo $archived; ?>">
<div class="row">
<div class="col-md-4">
<div class="input-group mb-3 mb-md-0">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search Domains">
<div class="input-group-append">
<button class="btn btn-dark"><i class="fa fa-search"></i></button>
</div>
</div>
</div>
<?php if ($client_url) { ?>
<div class="col-md-2"></div>
<?php } else { ?>
<div class="col-md-2">
<div class="input-group mb-3 mb-md-0">
<select class="form-control select2" name="client" onchange="this.form.submit()">
<option value="" <?php if ($client == "") { echo "selected"; } ?>>- All Clients -</option>
<?php
$sql_clients_filter = mysqli_query($mysqli, "
SELECT DISTINCT client_id, client_name
FROM clients
JOIN domains ON domain_client_id = client_id
WHERE $archive_query
$access_permission_query
ORDER BY client_name ASC
");
while ($row = mysqli_fetch_array($sql_clients_filter)) {
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
?>
<option <?php if ($client == $client_id) { echo "selected"; } ?> value="<?php echo $client_id; ?>"><?php echo $client_name; ?></option>
<?php
}
?>
</select>
</div>
</div>
<?php } ?>
<div class="col-md-6">
<div class="btn-group float-right">
<a href="?<?php echo $client_url; ?>archived=<?php if($archived == 1){ echo 0; } else { echo 1; } ?>"
class="btn btn-<?php if($archived == 1){ echo "primary"; } else { echo "default"; } ?>">
<i class="fa fa-fw fa-archive mr-2"></i>Archived
</a>
<div class="dropdown ml-2" id="bulkActionButton" hidden>
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">
<i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>)
</button>
<div class="dropdown-menu">
<?php if ($archived) { ?>
<button class="dropdown-item text-info"
type="submit" form="bulkActions" name="bulk_unarchive_domains">
<i class="fas fa-fw fa-redo mr-2"></i>Unarchive
</button>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-danger text-bold"
type="submit" form="bulkActions" name="bulk_delete_domains">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</button>
<?php } else { ?>
<button class="dropdown-item text-danger confirm-link"
type="submit" form="bulkActions" name="bulk_archive_domains">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</button>
<?php } ?>
</div>
</div>
</div>
</div>
</div>
</form>
<hr>
<div class="table-responsive-sm">
<form id="bulkActions" action="post.php" method="post">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<?php if ($client_url) { ?>
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<?php } ?>
<table class="table table-striped table-borderless table-hover">
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?> text-nowrap">
<tr>
<td class="pr-0">
<div class="form-check">
<input class="form-check-input" id="selectAllCheckbox" type="checkbox" onclick="checkAll(this)">
</div>
</td>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=domain_name&order=<?php echo $disp; ?>">
Domain <?php if ($sort == 'domain_name') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=registrar_name&order=<?php echo $disp; ?>">
Registrar <?php if ($sort == 'registrar_name') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=webhost_name&order=<?php echo $disp; ?>">
Web Host <?php if ($sort == 'webhost_name') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=dnshost_name&order=<?php echo $disp; ?>">
DNS Host <?php if ($sort == 'dnshost_name') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=mailhost_name&order=<?php echo $disp; ?>">
Mail Host <?php if ($sort == 'mailhost_name') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=domain_expire&order=<?php echo $disp; ?>">
Expires <?php if ($sort == 'domain_expire') { echo $order_icon; } ?>
</a>
</th>
<?php if (!$client_url) { ?>
<th>
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=client_name&order=<?php echo $disp; ?>">
Client <?php if ($sort == 'client_name') { echo $order_icon; } ?>
</a>
</th>
<?php } ?>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql)) {
$domain_id = intval($row['domain_id']);
$domain_name = nullable_htmlentities($row['domain_name']);
$domain_description = nullable_htmlentities($row['domain_description']);
$domain_expire = nullable_htmlentities($row['domain_expire']);
$domain_expire_ago = timeAgo($domain_expire);
// Convert the expiry date to a timestamp
$domain_expire_timestamp = strtotime($row['domain_expire'] ?? '');
$current_timestamp = time(); // Get current timestamp
// Calculate the difference in days
$days_until_expiry = ($domain_expire_timestamp - $current_timestamp) / (60 * 60 * 24);
// Determine the class based on the number of days until expiry
if ($days_until_expiry <= 0) {
$tr_class = "table-secondary";
} elseif ($days_until_expiry <= 14) {
$tr_class = "table-danger";
} elseif ($days_until_expiry <= 90) {
$tr_class = "table-warning";
} else {
$tr_class = '';
}
$domain_registrar_id = intval($row['registrar_id']);
$domain_webhost_id = intval($row['webhost_id']);
$domain_dnshost_id = intval($row['dnshost_id']);
$domain_mailhost_id = intval($row['mailhost_id']);
$domain_registrar_name = nullable_htmlentities($row['registrar_name']);
$domain_webhost_name = nullable_htmlentities($row['webhost_name']);
$domain_dnshost_name = nullable_htmlentities($row['dnshost_name']);
$domain_mailhost_name = nullable_htmlentities($row['mailhost_name']);
$domain_created_at = nullable_htmlentities($row['domain_created_at']);
$domain_archived_at = nullable_htmlentities($row['domain_archived_at']);
$client_id = intval($row['domain_client_id']);
$client_name = nullable_htmlentities($row['client_name']);
// Add - if empty on the table
$domain_registrar_name_display = $domain_registrar_name ? "
<a class='ajax-modal' href='#' data-modal-url='modals/vendor/vendor_details.php?id=$domain_registrar_id'>
$domain_registrar_name
</a>" : "-";
$domain_webhost_name_display = $domain_webhost_name ? "
<a class='ajax-modal' href='#' data-modal-url='modals/vendor/vendor_details.php?id=$domain_webhost_id'>
$domain_webhost_name
</a>" : "-";
$domain_dnshost_name_display = $domain_dnshost_name ? "
<a class='ajax-modal' href='#' data-modal-url='modals/vendor/vendor_details.php?id=$domain_dnshost_id'>
$domain_dnshost_name
</a>" : "-";
$domain_mailhost_name_display = $domain_mailhost_name ? "
<a class='ajax-modal' href='#' data-modal-url='modals/vendor/vendor_details.php?id=$domain_mailhost_id'>
$domain_mailhost_name
</a>" : "-";
?>
<tr class="<?php echo $tr_class; ?>">
<td class="pr-0">
<div class="form-check">
<input class="form-check-input bulk-select" type="checkbox" name="domain_ids[]" value="<?php echo $domain_id ?>">
</div>
</td>
<td class="">
<a class="text-dark ajax-modal" href="#"
data-modal-size="lg"
data-modal-url="modals/domain/domain_edit.php?<?= $client_url ?>&id=<?= $domain_id ?>">
<div class="media">
<i class="fa fa-fw fa-2x fa-globe mr-3"></i>
<div class="media-body">
<div><?php echo $domain_name; ?></div>
<div><small class="text-secondary"><?php echo $domain_description; ?></small></div>
</div>
</div>
</a>
</td>
<td><?php echo $domain_registrar_name_display; ?></td>
<td><?php echo $domain_webhost_name_display; ?></td>
<td><?php echo $domain_dnshost_name_display; ?></td>
<td><?php echo $domain_mailhost_name_display; ?></td>
<td>
<div><?php echo $domain_expire; ?></div>
<div><small><?php echo $domain_expire_ago; ?></small></div>
</td>
<?php if (!$client_url) { ?>
<td><a href="domains.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
<?php } ?>
<td>
<div class="dropdown dropleft text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i>
</button>
<div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#"
data-modal-size="lg"
data-modal-url="modals/domain/domain_edit.php?<?= $client_url ?>&id=<?= $domain_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit
</a>
<?php if ($session_user_role == 3) { ?>
<?php if ($domain_archived_at) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-info confirm-link" href="post.php?unarchive_domain=<?php echo $domain_id; ?>">
<i class="fas fa-fw fa-redo mr-2"></i>Unarchive
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_domain=<?php echo $domain_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</a>
<?php } else { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_domain=<?php echo $domain_id; ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</a>
<?php } ?>
<?php } ?>
</div>
</div>
</td>
</tr>
<?php
}
?>
</tbody>
</table>
</form>
</div>
<?php require_once "../includes/filter_footer.php";
?>
</div>
</div>
<?php
require_once "modals/domain/domain_add.php";
require_once "modals/domain/domain_export.php";
?>
<script src="../js/bulk_actions.js"></script>
<?php require_once "../includes/footer.php";

382
agent/expenses.php Normal file
View File

@@ -0,0 +1,382 @@
<?php
// Default Column Sortby/Order Filter
$sort = "expense_date";
$order = "DESC";
require_once "includes/inc_all.php";
// Perms
enforceUserPermission('module_financial');
// Account Filter
if (isset($_GET['account']) & !empty($_GET['account'])) {
$account_query = 'AND (expense_account_id = ' . intval($_GET['account']) . ')';
$account_filter = intval($_GET['account']);
} else {
// Default - any
$account_query = '';
$account_filter = '';
}
// Vendor Filter
if (isset($_GET['vendor']) & !empty($_GET['vendor'])) {
$vendor_query = 'AND (vendor_id = ' . intval($_GET['vendor']) . ')';
$vendor_filter = intval($_GET['vendor']);
} else {
// Default - any
$vendor_query = '';
$vendor_filter = '';
}
// Category Filter
if (isset($_GET['category']) & !empty($_GET['category'])) {
$category_query = 'AND (category_id = ' . intval($_GET['category']) . ')';
$category_filter = intval($_GET['category']);
} else {
// Default - any
$category_query = '';
$category_filter = '';
}
$sql = mysqli_query(
$mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM expenses
LEFT JOIN categories ON expense_category_id = category_id
LEFT JOIN vendors ON expense_vendor_id = vendor_id
LEFT JOIN accounts ON expense_account_id = account_id
LEFT JOIN clients ON expense_client_id = client_id
WHERE expense_vendor_id > 0
AND DATE(expense_date) BETWEEN '$dtf' AND '$dtt'
$vendor_query
$category_query
AND (vendor_name LIKE '%$q%' OR client_name LIKE '%$q%' OR category_name LIKE '%$q%' OR account_name LIKE '%$q%' OR expense_description LIKE '%$q%' OR expense_amount LIKE '%$q%')
$account_query
ORDER BY $sort $order LIMIT $record_from, $record_to"
);
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?>
<div class="card card-dark">
<div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fas fa-fw fa-shopping-cart mr-2"></i>Expenses</h3>
<div class="card-tools">
<div class="btn-group">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addExpenseModal"><i class="fas fa-plus mr-2"></i>New Expense</button>
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#exportExpensesModal">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
</div>
</div>
</div>
</div>
<div class="card-body">
<form class="mb-4" autocomplete="off">
<div class="row">
<div class="col-sm-4">
<div class="input-group">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search Expenses">
<div class="input-group-append">
<button class="btn btn-secondary" type="button" data-toggle="collapse" data-target="#advancedFilter"><i class="fas fa-filter"></i></button>
<button class="btn btn-primary"><i class="fa fa-search"></i></button>
</div>
</div>
</div>
<div class="col-sm-8">
<div class="btn-group float-right">
<div class="dropdown ml-2" id="bulkActionButton" hidden>
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">
<i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>)
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkEditCategoryModal">
<i class="fas fa-fw fa-list mr-2"></i>Set Category
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkEditAccountModal">
<i class="fas fa-fw fa-piggy-bank mr-2"></i>Set Account
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkEditClientModal">
<i class="fas fa-fw fa-user mr-2"></i>Set Client
</a>
<?php if ($session_user_role == 3) { ?>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-danger text-bold"
type="submit" form="bulkActions" name="bulk_delete_expenses">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</button>
<?php } ?>
</div>
</div>
</div>
</div>
</div>
<div class="collapse mt-3 <?php if (isset($_GET['dtf']) || $_GET['canned_date'] !== "custom" || $account_filter || $vendor_filter || $category_filter) { echo "show"; } ?>" id="advancedFilter">
<div class="row">
<div class="col-md-2">
<div class="form-group">
<label>Canned Date</label>
<select onchange="this.form.submit()" class="form-control select2" name="canned_date">
<option <?php if ($_GET['canned_date'] == "custom") { echo "selected"; } ?> value="">Custom</option>
<option <?php if ($_GET['canned_date'] == "today") { echo "selected"; } ?> value="today">Today</option>
<option <?php if ($_GET['canned_date'] == "yesterday") { echo "selected"; } ?> value="yesterday">Yesterday</option>
<option <?php if ($_GET['canned_date'] == "thisweek") { echo "selected"; } ?> value="thisweek">This Week</option>
<option <?php if ($_GET['canned_date'] == "lastweek") { echo "selected"; } ?> value="lastweek">Last Week</option>
<option <?php if ($_GET['canned_date'] == "thismonth") { echo "selected"; } ?> value="thismonth">This Month</option>
<option <?php if ($_GET['canned_date'] == "lastmonth") { echo "selected"; } ?> value="lastmonth">Last Month</option>
<option <?php if ($_GET['canned_date'] == "thisyear") { echo "selected"; } ?> value="thisyear">This Year</option>
<option <?php if ($_GET['canned_date'] == "lastyear") { echo "selected"; } ?> value="lastyear">Last Year</option>
</select>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>Date From</label>
<input onchange="this.form.submit()" type="date" class="form-control" name="dtf" max="2999-12-31" value="<?php echo nullable_htmlentities($dtf); ?>">
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>Date To</label>
<input onchange="this.form.submit()" type="date" class="form-control" name="dtt" max="2999-12-31" value="<?php echo nullable_htmlentities($dtt); ?>">
</div>
</div>
<div class="col-sm-2">
<div class="form-group">
<label>Vendor</label>
<select class="form-control select2" name="vendor" onchange="this.form.submit()">
<option value="">- All Vendors -</option>
<?php
$sql_vendors_filter = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE EXISTS (SELECT 1 FROM expenses WHERE expense_vendor_id = vendor_id) ORDER BY vendor_name ASC");
while ($row = mysqli_fetch_array($sql_vendors_filter)) {
$vendor_id = intval($row['vendor_id']);
$vendor_name = nullable_htmlentities($row['vendor_name']);
?>
<option <?php if ($vendor_filter == $vendor_id) { echo "selected"; } ?> value="<?php echo $vendor_id; ?>"><?php echo $vendor_name; ?></option>
<?php
}
?>
</select>
</div>
</div>
<div class="col-sm-2">
<div class="form-group">
<label>Category</label>
<select class="form-control select2" name="category" onchange="this.form.submit()">
<option value="">- All Categories -</option>
<?php
$sql_categories_filter = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Expense' AND EXISTS (SELECT 1 FROM expenses WHERE expense_category_id = category_id) ORDER BY category_name ASC");
while ($row = mysqli_fetch_array($sql_categories_filter)) {
$category_id = intval($row['category_id']);
$category_name = nullable_htmlentities($row['category_name']);
?>
<option <?php if ($category_filter == $category_id) { echo "selected"; } ?> value="<?php echo $category_id; ?>"><?php echo $category_name; ?></option>
<?php
}
?>
</select>
</div>
</div>
<div class="col-sm-2">
<div class="form-group">
<label>Account</label>
<select class="form-control select2" name="account" onchange="this.form.submit()">
<option value="">- All Accounts -</option>
<?php
$sql_accounts_filter = mysqli_query($mysqli, "SELECT account_id, account_name FROM accounts WHERE EXISTS (SELECT 1 FROM expenses WHERE expense_account_id = account_id) ORDER BY account_name ASC");
while ($row = mysqli_fetch_array($sql_accounts_filter)) {
$account_id = intval($row['account_id']);
$account_name = nullable_htmlentities($row['account_name']);
?>
<option <?php if ($account_filter == $account_id) { echo "selected"; } ?> value="<?php echo $account_id; ?>"><?php echo $account_name; ?></option>
<?php
}
?>
</select>
</div>
</div>
</div>
</div>
</form>
<hr>
<form id="bulkActions" action="post.php" method="post" enctype="multipart/form-data">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<div class="table-responsive-sm">
<table class="table table-striped table-borderless table-hover">
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
<tr>
<td class="bg-light pr-0">
<div class="form-check">
<input class="form-check-input" id="selectAllCheckbox" type="checkbox" onclick="checkAll(this)">
</div>
</td>
<th>
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=expense_date&order=<?php echo $disp; ?>">
Date <?php if ($sort == 'expense_date') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=category_name&order=<?php echo $disp; ?>">
Category <?php if ($sort == 'category_name') { echo $order_icon; } ?>
</a>
/
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=expense_description&order=<?php echo $disp; ?>">
Description <?php if ($sort == 'expense_description') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=vendor_name&order=<?php echo $disp; ?>">
Vendor <?php if ($sort == 'vendor_name') { echo $order_icon; } ?>
</a>
</th>
<th class="text-right">
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=expense_amount&order=<?php echo $disp; ?>">
Amount <?php if ($sort == 'expense_amount') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=account_name&order=<?php echo $disp; ?>">
Account <?php if ($sort == 'account_name') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=client_name&order=<?php echo $disp; ?>">
Client <?php if ($sort == 'client_name') { echo $order_icon; } ?>
</a>
</th>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql)) {
$expense_id = intval($row['expense_id']);
$expense_date = nullable_htmlentities($row['expense_date']);
$expense_amount = floatval($row['expense_amount']);
$expense_currency_code = nullable_htmlentities($row['expense_currency_code']);
$expense_description = nullable_htmlentities($row['expense_description']);
$expense_receipt = nullable_htmlentities($row['expense_receipt']);
$expense_reference = nullable_htmlentities($row['expense_reference']);
$expense_created_at = nullable_htmlentities($row['expense_created_at']);
$expense_vendor_id = intval($row['expense_vendor_id']);
$vendor_name = nullable_htmlentities($row['vendor_name']);
$expense_category_id = intval($row['expense_category_id']);
$category_name = nullable_htmlentities($row['category_name']);
$account_name = nullable_htmlentities($row['account_name']);
$expense_account_id = intval($row['expense_account_id']);
$client_name = nullable_htmlentities($row['client_name']);
if(empty($client_name)) {
$client_name_display = "-";
} else {
$client_name_display = $client_name;
}
$expense_client_id = intval($row['expense_client_id']);
if (empty($expense_receipt)) {
$receipt_attached = "";
} else {
$path_info = pathinfo($expense_receipt);
$ext = $path_info['extension'];
$receipt_attached = "<a class='text-secondary mr-2' target='_blank' href='../uploads/expenses/$expense_receipt' download='$expense_date-$vendor_name-$category_name-$expense_id.$ext'><i class='fa fa-file'></i></a>";
}
?>
<tr>
<td class="pr-0 bg-light">
<div class="form-check">
<input class="form-check-input bulk-select" type="checkbox" name="expense_ids[]" value="<?php echo $expense_id ?>">
</div>
</td>
<td>
<?php echo $receipt_attached; ?>
<a class="text-dark ajax-modal" href="#" title="Created: <?php echo $expense_created_at; ?>"
data-modal-size="lg"
data-modal-url="modals/expense/expense_edit.php?id=<?= $expense_id ?>">
<?php echo $expense_date; ?>
</a>
</td>
<td>
<?php echo $category_name; ?>
<div class="text-secondary"><small><?php echo truncate($expense_description, 60); ?></small></div>
</td>
<td><?php echo $vendor_name; ?></td>
<td class="text-bold text-right"><?php echo numfmt_format_currency($currency_format, $expense_amount, $expense_currency_code); ?></td>
<td><?php echo $account_name; ?></td>
<td><?php echo $client_name_display; ?></td>
<td>
<div class="dropdown dropleft text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i>
</button>
<div class="dropdown-menu">
<?php
if (!empty($expense_receipt)) { ?>
<a class="dropdown-item" href="<?php echo "../uploads/expenses/$expense_receipt"; ?>" download="<?php echo "$expense_date-$vendor_name-$category_name-$expense_id.pdf"; ?>">
<i class="fas fa-fw fa-download mr-2"></i>Download
</a>
<div class="dropdown-divider"></div>
<?php } ?>
<a class="dropdown-item ajax-modal" href="#"
data-modal-size="lg"
data-modal-url="modals/expense/expense_edit.php?id=<?= $expense_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit
</a>
<a class="dropdown-item ajax-modal" href="#"
data-modal-size="lg"
data-modal-url="modals/expense/expense_copy.php?id=<?= $expense_id ?>">
<i class="fas fa-fw fa-copy mr-2"></i>Copy
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item ajax-modal" href="#"
data-modal-size="lg"
data-modal-url="modals/expense/expense_refund.php?id=<?= $expense_id ?>">
<i class="fas fa-fw fa-undo-alt mr-2"></i>Refund
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_expense=<?php echo $expense_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</a>
</div>
</div>
</td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
<?php require_once "modals/expense/expense_bulk_edit_category.php"; ?>
<?php require_once "modals/expense/expense_bulk_edit_account.php"; ?>
<?php require_once "modals/expense/expense_bulk_edit_client.php"; ?>
</form>
<?php require_once "../includes/filter_footer.php";
?>
</div>
</div>
<script src="../js/bulk_actions.js"></script>
<?php
require_once "modals/expense/expense_add.php";
require_once "modals/expense/expense_export.php";
require_once "../includes/footer.php";

626
agent/files.php Normal file
View File

@@ -0,0 +1,626 @@
<?php
// Default Column Sortby Filter
$sort = "file_name";
$order = "ASC";
require_once "includes/inc_all_client.php";
// Folder
if (!empty($_GET['folder_id'])) {
$folder_id = intval($_GET['folder_id']);
} else {
$folder_id = 0;
}
//Rebuild URL
$url_query_strings_sort = http_build_query($get_copy);
// Folder ID
$get_folder_id = 0;
if (!empty($_GET['folder_id'])) {
$get_folder_id = intval($_GET['folder_id']);
}
// View Mode -- 0 List, 1 Thumbnail
if (!empty($_GET['view'])) {
$view = intval($_GET['view']);
} else {
$view = 0;
}
if ($view == 1) {
$query_images = "AND (file_ext LIKE 'JPG' OR file_ext LIKE 'jpg' OR file_ext LIKE 'JPEG' OR file_ext LIKE 'jpeg' OR file_ext LIKE 'png' OR file_ext LIKE 'PNG' OR file_ext LIKE 'webp' OR file_ext LIKE 'WEBP')";
} else {
$query_images = '';
}
// Set Folder Location Var used when creating folders
$folder_location = 1;
if ($get_folder_id == 0 && isset($_GET["q"])) {
$sql = mysqli_query(
$mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM files
LEFT JOIN users ON file_created_by = user_id
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
LEFT JOIN users ON file_created_by = user_id
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()"));
$num_of_files = mysqli_num_rows($sql);
// Breadcrumbs
// Build the full folder path
$folder_id = $get_folder_id;
$folder_path = array();
while ($folder_id > 0) {
$sql_folder = mysqli_query($mysqli, "SELECT folder_name, parent_folder FROM folders WHERE folder_id = $folder_id");
if ($row_folder = mysqli_fetch_assoc($sql_folder)) {
$folder_name = nullable_htmlentities($row_folder['folder_name']);
$parent_folder = intval($row_folder['parent_folder']);
// Prepend the folder to the beginning of the array
array_unshift($folder_path, array('folder_id' => $folder_id, 'folder_name' => $folder_name));
// Move up to the parent folder
$folder_id = $parent_folder;
} else {
// If the folder is not found, break the loop
break;
}
}
?>
<div class="card card-dark">
<div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fa fa-fw fa-paperclip mr-2"></i>Files</h3>
<div class="card-tools">
<div class="btn-group">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#uploadFilesModal">
<i class="fas fa-fw fa-cloud-upload-alt mr-2"></i>Upload
</button>
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#createFolderModal">
<i class="fa fa-fw fa-folder-plus mr-2"></i>New Folder
</a>
</div>
</div>
</div>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-3 border-right mb-3">
<h4>Folders</h4>
<hr>
<ul class="nav nav-pills flex-column bg-light">
<li class="nav-item">
<a class="nav-link <?php if ($get_folder_id == 0) { echo "active"; } ?>" href="?client_id=<?php echo $client_id; ?>&folder_id=0">/</a>
</li>
<?php
// Function to check if a folder is an ancestor of the current folder
function is_ancestor_folder($folder_id, $current_folder_id, $client_id) {
global $mysqli;
// Base case: if current_folder_id is 0 or equal to folder_id
if ($current_folder_id == 0) {
return false;
}
if ($current_folder_id == $folder_id) {
return true;
}
// Get the parent folder of the current folder
$result = mysqli_query($mysqli, "SELECT parent_folder FROM folders WHERE folder_id = $current_folder_id AND folder_client_id = $client_id");
if ($row = mysqli_fetch_assoc($result)) {
$parent_folder_id = intval($row['parent_folder']);
// Recursive call to check the parent folder
return is_ancestor_folder($folder_id, $parent_folder_id, $client_id);
} else {
// Folder not found
return false;
}
}
// Recursive function to display folders and subfolders
function display_folders($parent_folder_id, $client_id, $indent = 0) {
global $mysqli, $get_folder_id, $session_user_role;
$sql_folders = mysqli_query($mysqli, "SELECT * FROM folders WHERE parent_folder = $parent_folder_id AND folder_location = 1 AND folder_client_id = $client_id ORDER BY folder_name ASC");
while ($row = mysqli_fetch_array($sql_folders)) {
$folder_id = intval($row['folder_id']);
$folder_name = nullable_htmlentities($row['folder_name']);
// Get the number of files in the folder
$row2 = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('file_id') AS num FROM files WHERE file_folder_id = $folder_id AND file_archived_at IS NULL"));
$num_files = intval($row2['num']);
// Get the number of subfolders
$subfolder_result = mysqli_query($mysqli, "SELECT COUNT(*) AS count FROM folders WHERE parent_folder = $folder_id AND folder_client_id = $client_id");
$subfolder_count = intval(mysqli_fetch_assoc($subfolder_result)['count']);
echo '<li class="nav-item">';
echo '<div class="row">';
echo '<div class="col-10">';
echo '<a class="nav-link ';
if ($get_folder_id == $folder_id) { echo "active"; }
echo '" href="?client_id=' . $client_id . '&folder_id=' . $folder_id . '">';
// Indentation for subfolders
echo str_repeat('&nbsp;', $indent * 4);
// Determine if the folder is open
if ($get_folder_id == $folder_id || is_ancestor_folder($folder_id, $get_folder_id, $client_id)) {
echo '<i class="fas fa-fw fa-folder-open"></i>';
} else {
echo '<i class="fas fa-fw fa-folder"></i>';
}
echo ' ' . $folder_name;
if ($num_files > 0) {
echo "<span class='badge badge-pill badge-dark float-right mt-1'>$num_files</span>";
}
echo '</a>';
echo '</div>';
echo '<div class="col-2">';
?>
<div class="dropdown">
<button class="btn btn-sm" type="button" data-toggle="dropdown">
<i class="fas fa-ellipsis-v"></i>
</button>
<div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/folder/folder_rename.php?id=<?= $folder_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Rename
</a>
<?php
// Only show delete option if user is admin, folder has no files, and no subfolders
if ($session_user_role == 3 && $num_files == 0 && $subfolder_count == 0) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_folder=<?php echo $folder_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</a>
<?php } ?>
</div>
</div>
<?php
echo '</div>';
echo '</div>';
if ($subfolder_count > 0) {
// Display subfolders
echo '<ul class="nav nav-pills flex-column bg-light">';
display_folders($folder_id, $client_id, $indent + 1);
echo '</ul>';
}
echo '</li>';
}
}
// Start displaying folders from the root (parent_folder = 0)
display_folders(0, $client_id);
?>
</ul>
<?php require_once "modals/folder/folder_add.php"; ?>
</div>
<div class="col-md-9">
<form autocomplete="off">
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<input type="hidden" name="view" value="<?php echo $view; ?>">
<input type="hidden" name="folder_id" value="<?php echo $get_folder_id; ?>">
<div class="row">
<div class="col-md-5">
<div class="input-group mb-3 mb-md-0">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search for files in <?php if($get_folder_id == 0) { echo "all folders"; } else { echo "current folder"; } ?>">
<div class="input-group-append">
<button class="btn btn-dark"><i class="fa fa-search"></i></button>
</div>
</div>
</div>
<div class="col-md-7">
<div class="btn-group float-right">
<a href="?<?php echo $url_query_strings_sort; ?>&view=0" class="btn <?php if($view == 0){ echo "btn-primary"; } else { echo "btn-outline-secondary"; } ?>"><i class="fas fa-list-ul"></i></a>
<a href="?<?php echo $url_query_strings_sort; ?>&view=1" class="btn <?php if($view == 1){ echo "btn-primary"; } else { echo "btn-outline-secondary"; } ?>"><i class="fas fa-th-large"></i></a>
<div class="dropdown ml-2" id="bulkActionButton" hidden>
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">
<i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>)
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkMoveFilesModal">
<i class="fas fa-fw fa-exchange-alt mr-2"></i>Move
</a>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-danger text-bold"
type="submit" form="bulkActions" name="bulk_delete_files">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</button>
</div>
</div>
</div>
</div>
</div>
</form>
<nav class="mt-3">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="?client_id=<?php echo $client_id; ?>&folder_id=0">
<i class="fas fa-fw fa-folder mr-2"></i>Root
</a>
</li>
<?php
// Output breadcrumb items for each folder in the path
foreach ($folder_path as $folder) {
$bread_crumb_folder_id = $folder['folder_id']; // Already Sanitized before it was pushed into array
$bread_crumb_folder_name = $folder['folder_name']; // Already Sanitized before it was pushed into array
?>
<li class="breadcrumb-item">
<a href="?client_id=<?php echo $client_id; ?>&folder_id=<?php echo $bread_crumb_folder_id; ?>">
<i class="fas fa-fw fa-folder-open mr-2"></i><?php echo $bread_crumb_folder_name; ?>
</a>
</li>
<?php
}
?>
</ol>
</nav>
<hr>
<?php
if($view == 1){
?>
<div class="row">
<?php
$files = [];
while ($row = mysqli_fetch_array($sql)) {
$file_id = intval($row['file_id']);
$file_name = nullable_htmlentities($row['file_name']);
$file_reference_name = nullable_htmlentities($row['file_reference_name']);
$file_ext = nullable_htmlentities($row['file_ext']);
$file_size = intval($row['file_size']);
$file_size_KB = number_format($file_size / 1024);
$file_mime_type = nullable_htmlentities($row['file_mime_type']);
$file_uploaded_by = nullable_htmlentities($row['user_name']);
// Store file data into an array for JS
$files[] = [
'id' => $file_id,
'name' => $file_name,
'preview' => "../uploads/clients/$client_id/$file_reference_name"
];
?>
<div class="col-xl-2 col-lg-2 col-md-6 col-sm-6 mb-3 text-center">
<a href="#" onclick="openModal(<?php echo count($files)-1; ?>)"><!-- passing the index -->
<img class="img-thumbnail" src="<?php echo "../uploads/clients/$client_id/$file_reference_name"; ?>" alt="<?php echo $file_reference_name ?>">
</a>
<div>
<div class="dropdown float-right">
<button class="btn btn-link btn-sm" type="button" data-toggle="dropdown">
<i class="fas fa-ellipsis-v"></i>
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="<?php echo "../uploads/clients/$client_id/$file_reference_name"; ?>" download="<?php echo $file_name; ?>">
<i class="fas fa-fw fa-cloud-download-alt mr-2"></i>Download
</a>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#shareModal" onclick="populateShareModal(<?php echo "$client_id, 'File', $file_id"; ?>)">
<i class="fas fa-fw fa-share mr-2"></i>Share
</a>
<a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/file/file_rename.php?id=<?= $file_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Rename
</a>
<a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/file/file_move.php?id=<?= $file_id ?>">
<i class="fas fa-fw fa-exchange-alt mr-2"></i>Move
</a>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#linkAssetToFileModal<?php echo $file_id; ?>">
<i class="fas fa-fw fa-desktop mr-2"></i>Asset
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_file=<?php echo $file_id; ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</a>
<?php if ($session_user_role == 3) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold" href="#" data-toggle="modal" data-target="#deleteFileModal" onclick="populateFileDeleteModal(<?php echo "$file_id , '$file_name'" ?>)">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</a>
<?php } ?>
</div>
</div>
<small class="text-secondary"><?php echo $file_name; ?></small>
</div>
</div>
<?php
require "modals/file/file_view.php";
}
?>
<script>
// Pass PHP array to JavaScript
var files = <?php echo json_encode($files); ?>;
var currentIndex = 0; // Keep track of which file is displayed
</script>
</div>
<?php } else { ?>
<form id="bulkActions" action="post.php" method="post">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<div class="table-responsive-sm">
<table class="table border">
<thead class="thead-light <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
<tr>
<td class="bg-light pr-0">
<div class="form-check">
<input class="form-check-input" id="selectAllCheckbox" type="checkbox" onclick="checkAll(this)">
</div>
</td>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=file_name&order=<?php echo $disp; ?>">
Name <?php if ($sort == 'file_name') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=file_mime_type&order=<?php echo $disp; ?>">
Type <?php if ($sort == 'file_mime_type') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=file_size&order=<?php echo $disp; ?>">
Size <?php if ($sort == 'file_size') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=file_created_at&order=<?php echo $disp; ?>">
Uploaded <?php if ($sort == 'file_created_at') { echo $order_icon; } ?>
</a>
</th>
<th></th>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql)) {
$file_id = intval($row['file_id']);
$file_name = nullable_htmlentities($row['file_name']);
$file_description = nullable_htmlentities($row['file_description']);
$file_reference_name = nullable_htmlentities($row['file_reference_name']);
$file_ext = nullable_htmlentities($row['file_ext']);
if ($file_ext == 'pdf') {
$file_icon = "file-pdf";
} elseif ($file_ext == 'gz' || $file_ext == 'tar' || $file_ext == 'zip' || $file_ext == '7z' || $file_ext == 'rar') {
$file_icon = "file-archive";
} elseif ($file_ext == 'txt' || $file_ext == 'md') {
$file_icon = "file-alt";
} elseif ($file_ext == 'msg') {
$file_icon = "envelope";
} elseif ($file_ext == 'doc' || $file_ext == 'docx' || $file_ext == 'odt') {
$file_icon = "file-word";
} elseif ($file_ext == 'xls' || $file_ext == 'xlsx' || $file_ext == 'ods') {
$file_icon = "file-excel";
} elseif ($file_ext == 'pptx' || $file_ext == 'odp') {
$file_icon = "file-powerpoint";
} elseif ($file_ext == 'mp3' || $file_ext == 'wav' || $file_ext == 'ogg') {
$file_icon = "file-audio";
} elseif ($file_ext == 'mov' || $file_ext == 'mp4' || $file_ext == 'av1') {
$file_icon = "file-video";
} elseif ($file_ext == 'jpg' || $file_ext == 'jpeg' || $file_ext == 'png' || $file_ext == 'gif' || $file_ext == 'webp' || $file_ext == 'bmp' || $file_ext == 'tif') {
$file_icon = "file-image";
} else {
$file_icon = "file";
}
$file_size = intval($row['file_size']);
$file_size_KB = number_format($file_size / 1024);
$file_mime_type = nullable_htmlentities($row['file_mime_type']);
$file_size = intval($row['file_size']);
$file_uploaded_by = nullable_htmlentities($row['user_name']);
$file_created_at = nullable_htmlentities($row['file_created_at']);
$file_folder_id = intval($row['file_folder_id']);
// Check if shared
$sql_shared = mysqli_query(
$mysqli,
"SELECT * FROM shared_items
WHERE item_client_id = $client_id
AND item_active = 1
AND item_views != item_view_limit
AND item_expire_at > NOW()
AND item_type = 'File'
AND item_related_id = $file_id
LIMIT 1"
);
$file_shared = (mysqli_num_rows($sql_shared) > 0) ? true : false;
if ($file_shared) {
$row = mysqli_fetch_array($sql_shared);
$item_id = intval($row['item_id']);
$item_active = nullable_htmlentities($row['item_active']);
$item_key = nullable_htmlentities($row['item_key']);
$item_type = nullable_htmlentities($row['item_type']);
$item_related_id = intval($row['item_related_id']);
$item_note = nullable_htmlentities($row['item_note']);
$item_recipient = nullable_htmlentities($row['item_recipient']);
$item_views = nullable_htmlentities($row['item_views']);
$item_view_limit = nullable_htmlentities($row['item_view_limit']);
$item_created_at = nullable_htmlentities($row['item_created_at']);
$item_expire_at = nullable_htmlentities($row['item_expire_at']);
$item_expire_at_human = timeAgo($row['item_expire_at']);
}
?>
<tr>
<td class="bg-light pr-0">
<div class="form-check">
<input class="form-check-input bulk-select" type="checkbox" name="file_ids[]" value="<?php echo $file_id ?>">
</div>
</td>
<td>
<a href="<?php echo "../uploads/clients/$client_id/$file_reference_name"; ?>" target="_blank">
<div class="media">
<i class="fa fa-fw fa-2x fa-<?php echo $file_icon; ?> text-dark mr-3"></i>
<div class="media-body">
<p>
<?php echo basename($file_name); ?>
<br>
<small class="text-secondary"><?php echo $file_description; ?></small>
</p>
</div>
</div>
</a>
</td>
<td><?php echo $file_mime_type; ?></td>
<td><?php echo $file_size_KB; ?> KB</td>
<td>
<?php echo $file_created_at; ?>
<div class="text-secondary mt-1"><?php echo $file_uploaded_by; ?></div>
</td>
<td>
<?php if ($file_shared) { ?>
<div class="media" title="Expires <?php echo $item_expire_at_human; ?>">
<i class="fas fa-link mr-2 mt-1"></i>
<div class="media-body">Shared
<br>
<small class="text-secondary"><?php echo $item_recipient; ?></small>
</div>
</div>
<?php } ?>
</td>
<td>
<div class="dropdown dropleft text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i>
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="<?php echo "../uploads/clients/$client_id/$file_reference_name"; ?>" download="<?php echo $file_name; ?>">
<i class="fas fa-fw fa-cloud-download-alt mr-2"></i>Download
</a>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#shareModal" onclick="populateShareModal(<?php echo "$client_id, 'File', $file_id"; ?>)">
<i class="fas fa-fw fa-share mr-2"></i>Share
</a>
<a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/file/file_rename.php?id=<?= $file_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Rename
</a>
<a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/file/file_move.php?id=<?= $file_id ?>">
<i class="fas fa-fw fa-exchange-alt mr-2"></i>Move
</a>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#linkAssetToFileModal<?php echo $file_id; ?>">
<i class="fas fa-fw fa-desktop mr-2"></i>Asset
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_file=<?php echo $file_id; ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</a>
<?php if ($session_user_role == 3) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold" href="#" data-toggle="modal" data-target="#deleteFileModal" onclick="populateFileDeleteModal(<?php echo "$file_id , '$file_name'" ?>)">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</a>
<?php } ?>
</div>
</div>
</td>
</tr>
<?php
require "modals/file/file_link_asset.php";
}
?>
</tbody>
</table>
</div>
<?php require_once "modals/file/file_bulk_move.php"; ?>
</form>
<?php } ?>
<?php require_once "../includes/filter_footer.php";
?>
</div>
</div>
</div>
</div>
<script>
function openModal(index) {
currentIndex = index;
updateModalContent();
$('#viewFileModal').modal('show');
}
function updateModalContent() {
document.getElementById('modalTitle').innerText = files[currentIndex].name;
document.getElementById('modalImage').src = files[currentIndex].preview;
}
function nextFile() {
currentIndex = (currentIndex + 1) % files.length; // loop around
updateModalContent();
}
function prevFile() {
currentIndex = (currentIndex - 1 + files.length) % files.length; // loop around
updateModalContent();
}
</script>
<script src="../js/bulk_actions.js"></script>
<?php
require_once "modals/file/file_upload.php";
require_once "modals/share_modal.php";
require_once "modals/file/file_delete.php";
require_once "../includes/footer.php";

860
agent/global_search.php Normal file
View File

@@ -0,0 +1,860 @@
<?php
require_once "includes/inc_all.php";
// Initialize the HTML Purifier to prevent XSS
require "../plugins/htmlpurifier/HTMLPurifier.standalone.php";
$purifier_config = HTMLPurifier_Config::createDefault();
$purifier_config->set('URI.AllowedSchemes', ['data' => true, 'src' => true, 'http' => true, 'https' => true]);
$purifier = new HTMLPurifier($purifier_config);
if (isset($_GET['query'])) {
$query = sanitizeInput($_GET['query']);
$phone_query = preg_replace("/[^0-9]/", '', $query);
if (empty($phone_query)) {
$phone_query = $query;
}
$ticket_num_query = str_replace("$config_ticket_prefix", "", "$query");
$sql_clients = mysqli_query($mysqli, "SELECT * FROM clients
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%' OR client_abbreviation LIKE '%$query%')
$access_permission_query
ORDER BY client_id DESC LIMIT 5"
);
$sql_contacts = mysqli_query($mysqli, "SELECT * FROM contacts
LEFT JOIN clients ON client_id = contact_client_id
WHERE contact_archived_at IS NULL
AND (contact_name LIKE '%$query%'
OR contact_title LIKE '%$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"
);
$sql_vendors = mysqli_query($mysqli, "SELECT * FROM vendors
LEFT JOIN clients ON vendor_client_id = client_id
WHERE vendor_archived_at IS NULL
AND (vendor_name LIKE '%$query%' OR vendor_phone LIKE '%$phone_query%')
$access_permission_query
ORDER BY vendor_id DESC LIMIT 5"
);
$sql_domains = mysqli_query($mysqli, "SELECT * FROM domains
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"
);
$sql_products = mysqli_query($mysqli, "SELECT * FROM products
WHERE product_archived_at IS NULL
AND product_name LIKE '%$query%'
ORDER BY product_id DESC LIMIT 5"
);
$sql_documents = mysqli_query($mysqli, "SELECT * FROM documents
LEFT JOIN clients on document_client_id = clients.client_id
WHERE document_archived_at IS NULL
AND MATCH(document_content_raw) AGAINST ('$query')
$access_permission_query
ORDER BY document_id DESC LIMIT 5"
);
$sql_files = mysqli_query($mysqli, "SELECT * FROM files
LEFT JOIN clients ON file_client_id = client_id
LEFT JOIN folders ON folder_id = file_folder_id
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"
);
$sql_tickets = mysqli_query($mysqli, "SELECT * FROM tickets
LEFT JOIN clients on tickets.ticket_client_id = clients.client_id
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
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"
);
$sql_recurring_tickets = mysqli_query($mysqli, "SELECT * FROM recurring_tickets
LEFT JOIN clients ON recurring_ticket_client_id = client_id
WHERE (recurring_ticket_subject LIKE '%$query%'
OR recurring_ticket_details LIKE '%$query%')
$access_permission_query
ORDER BY recurring_ticket_id DESC LIMIT 5"
);
$sql_credentials = mysqli_query($mysqli, "SELECT * FROM credentials
LEFT JOIN contacts ON credential_contact_id = contact_id
LEFT JOIN clients ON credential_client_id = client_id
WHERE credential_archived_at IS NULL
AND (credential_name LIKE '%$query%' OR credential_description LIKE '%$query%')
$access_permission_query
ORDER BY credential_id DESC LIMIT 5"
);
$sql_invoices = mysqli_query($mysqli, "SELECT * FROM invoices
LEFT JOIN clients ON invoice_client_id = client_id
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"
);
$sql_assets = mysqli_query($mysqli,"SELECT * FROM assets
LEFT JOIN contacts ON asset_contact_id = contact_id
LEFT JOIN locations ON asset_location_id = location_id
LEFT JOIN clients ON asset_client_id = client_id
LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1
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 interface_ip LIKE '%$query%' OR interface_nat_ip LIKE '%$query%' OR interface_mac LIKE '%$query%' OR asset_status LIKE '%$query%')
$access_permission_query
ORDER BY asset_name DESC LIMIT 5"
);
$sql_ticket_replies = mysqli_query($mysqli,"SELECT * FROM ticket_replies
LEFT JOIN tickets ON ticket_reply_ticket_id = ticket_id
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"
);
$q = nullable_htmlentities($_GET['query']);
?>
<div class="card card-dark">
<div class="card-header mb-3">
<h4 class="card-title text-center"><i class="fas fa-fw fa-search mr-2"></i>Global Search</h4>
</div>
<div class="card-body">
<div class="row">
<?php if (mysqli_num_rows($sql_clients) > 0) { ?>
<!-- Clients-->
<div class="col-sm-6">
<div class="card card-dark mb-3">
<div class="card-header">
<h6 class="card-title"><i class="fas fa-fw fa-users mr-2"></i>Clients</h6>
</div>
<div class="card-body">
<table class="table table-striped table-borderless">
<thead>
<tr>
<th>Name</th>
<th>Phone</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_clients)) {
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
$location_phone_country_code = nullable_htmlentities($row['location_phone_country_code']);
$location_phone = nullable_htmlentities(formatPhoneNumber($row['location_phone'], $location_phone_country_code));
$client_website = nullable_htmlentities($row['client_website']);
?>
<tr>
<td><a href="client_overview.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
<td><?php echo $location_phone; ?></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
<?php } ?>
<?php if (mysqli_num_rows($sql_contacts) > 0) { ?>
<!-- Contacts-->
<div class="col-sm-6">
<div class="card card-dark mb-3">
<div class="card-header">
<h6 class="card-title"><i class="fas fa-fw fa-users mr-2"></i>Contacts</h6>
</div>
<div class="card-body">
<table class="table table-striped table-borderless">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
<th>Cell</th>
<th>Client</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_contacts)) {
$contact_id = intval($row['contact_id']);
$contact_name = nullable_htmlentities($row['contact_name']);
$contact_title = nullable_htmlentities($row['contact_title']);
$contact_phone_country_code = nullable_htmlentities($row['contact_phone_country_code']);
$contact_phone = nullable_htmlentities(formatPhoneNumber($row['contact_phone'], $contact_phone_country_code));
$contact_extension = nullable_htmlentities($row['contact_extension']);
$contact_mobile_country_code = nullable_htmlentities($row['contact_mobile_country_code']);
$contact_mobile = nullable_htmlentities(formatPhoneNumber($row['contact_mobile'], $contact_mobile_country_code));
$contact_email = nullable_htmlentities($row['contact_email']);
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
$contact_department = nullable_htmlentities($row['contact_department']);
?>
<tr>
<td><a href="contact_details.php?client_id=<?php echo $client_id; ?>&contact_id=<?php echo $contact_id; ?>"><?php echo $contact_name; ?></a>
<br><small class="text-secondary"><?php echo $contact_title; ?></small>
</td>
<td><?php echo $contact_email; ?></td>
<td><?php echo "$contact_phone $contact_extension"; ?></td>
<td><?php echo $contact_mobile; ?></td>
<td><a href="client_overview.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
<?php } ?>
<?php if (mysqli_num_rows($sql_vendors) > 0) { ?>
<!-- Vendors -->
<div class="col-sm-6">
<div class="card card-dark mb-3">
<div class="card-header">
<h6 class="card-title"><i class="fas fa-fw fa-building mr-2"></i>Vendors</h6>
</div>
<div class="card-body">
<table class="table table-striped table-borderless">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Phone</th>
<th>Client</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_vendors)) {
$vendor_name = nullable_htmlentities($row['vendor_name']);
$vendor_description = nullable_htmlentities($row['vendor_description']);
$vendor_phone_country_code = nullable_htmlentities($row['vendor_phone_country_code']);
$vendor_phone = nullable_htmlentities(formatPhoneNumber($row['vendor_phone'], $vendor_phone_country_code));
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
?>
<tr>
<td><a href="vendors.php?q=<?php echo $q ?>"><?php echo $vendor_name; ?></a></td>
<td><?php echo $vendor_description; ?></td>
<td><?php echo $vendor_phone; ?></td>
<td><a href="vendors.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
<?php } ?>
<?php if (mysqli_num_rows($sql_domains) > 0) { ?>
<!-- Domains -->
<div class="col-sm-6">
<div class="card card-dark mb-3">
<div class="card-header">
<h6 class="card-title"><i class="fas fa-fw fa-globe mr-2"></i>Domains</h6>
</div>
<div class="card-body">
<table class="table table-striped table-borderless">
<thead>
<tr>
<th>Name</th>
<th>Expiry</th>
<th>Client</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_domains)) {
$domain_name = nullable_htmlentities($row['domain_name']);
$domain_expiry = nullable_htmlentities($row['domain_expire']);
$domain_id = intval($row['domain_id']);
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
?>
<tr>
<td><a href="domains.php?client_id=<?php echo $client_id; ?>&domain_id=<?php echo $domain_id; ?>"><?php echo $domain_name; ?></a>
<td><?php echo $domain_expiry; ?></td>
<td><a href="client_overview.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
<?php } ?>
<?php if (mysqli_num_rows($sql_products) > 0) { ?>
<!-- Products -->
<div class="col-sm-6">
<div class="card card-dark mb-3">
<div class="card-header">
<h6 class="card-title"><i class="fas fa-fw fa-box mr-2"></i>Products</h6>
</div>
<div class="card-body">
<table class="table table-striped table-borderless">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_products)) {
$product_name = nullable_htmlentities($row['product_name']);
$product_description = nullable_htmlentities($row['product_description']);
?>
<tr>
<td><a href="products.php?q=<?php echo $q ?>"><?php echo $product_name; ?></a></td>
<td><?php echo $product_description; ?></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
<?php } ?>
<?php if (mysqli_num_rows($sql_documents) > 0) { ?>
<!-- Documents -->
<div class="col-sm-6">
<div class="card card-dark mb-3">
<div class="card-header">
<h6 class="card-title"><i class="fas fa-fw fa-file-alt mr-2"></i>Documents</h6>
</div>
<div class="card-body">
<table class="table table-striped table-borderless">
<thead>
<tr>
<th>Document</th>
<th>Client</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_documents)) {
$document_id = intval($row['document_id']);
$document_name = nullable_htmlentities($row['document_name']);
$client_id = intval($row['document_client_id']);
$client_name = nullable_htmlentities($row['client_name']);
?>
<tr>
<td><a href="document_details.php?client_id=<?php echo $client_id ?>&document_id=<?php echo $document_id; ?>"><?php echo $document_name; ?></a></td>
<td>
<a href="documents.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a>
</td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
<?php } ?>
<?php if (mysqli_num_rows($sql_files) > 0) { ?>
<!-- Files -->
<div class="col-sm-6">
<div class="card card-dark mb-3">
<div class="card-header">
<h6 class="card-title"><i class="fas fa-fw fa-paperclip mr-2"></i>Files</h6>
</div>
<div class="card-body">
<table class="table table-striped table-borderless">
<thead>
<tr>
<th>File Name</th>
<th>Description</th>
<th>Client</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_files)) {
$file_id = intval($row['file_id']);
$file_name = nullable_htmlentities($row['file_name']);
$file_reference_name = nullable_htmlentities($row['file_reference_name']);
$file_description = nullable_htmlentities($row['file_description']);
$folder_id = intval($row['folder_id']);
$folder_name = nullable_htmlentities($row['folder_name']);
$client_id = intval($row['file_client_id']);
$client_name = nullable_htmlentities($row['client_name']);
?>
<tr>
<td><a href="../uploads/clients/<?php echo $client_id; ?>/<?php echo $file_reference_name; ?>" download="<?php echo $file_name; ?>"><?php echo "$folder_name/$file_name"; ?></a></td>
<td><?php echo $file_description; ?></td>
<td>
<a href="files.php?client_id=<?php echo $client_id; ?>&folder_id=<?php echo $folder_id; ?>"><?php echo $client_name; ?></a>
</td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
<?php } ?>
<?php if (mysqli_num_rows($sql_tickets) > 0) { ?>
<!-- Tickets -->
<div class="col-sm-6">
<div class="card card-dark mb-3">
<div class="card-header">
<h6 class="card-title"><i class="fas fa-fw fa-life-ring mr-2"></i>Tickets</h6>
</div>
<div class="card-body">
<table class="table table-striped table-borderless">
<thead>
<tr>
<th>Ticket ID</th>
<th>Description</th>
<th>Status</th>
<th>Client</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_tickets)) {
$ticket_id = intval($row['ticket_id']);
$ticket_prefix = nullable_htmlentities($row['ticket_prefix']);
$ticket_number = intval($row['ticket_number']);
$ticket_subject = nullable_htmlentities($row['ticket_subject']);
$ticket_status_name = nullable_htmlentities($row['ticket_status_name']);
$client_name = nullable_htmlentities($row['client_name']);
$client_id = intval($row['ticket_client_id']);
?>
<tr>
<td><a href="ticket.php?ticket_id=<?php echo $ticket_id ?>"><?php echo $ticket_prefix . $ticket_number; ?></a></td>
<td><?php echo $ticket_subject; ?></td>
<td><?php echo $ticket_status_name; ?></td>
<td><a href="tickets.php?client_id=<?php echo $client_id ?>"><?php echo $client_name; ?></a></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
<?php } ?>
<?php if (mysqli_num_rows($sql_recurring_tickets) > 0) { ?>
<!-- Recurring Tickets -->
<div class="col-sm-6">
<div class="card card-dark mb-3">
<div class="card-header">
<h6 class="card-title"><i class="fas fa-fw fa-undo-alt mr-2"></i>Recurring Tickets</h6>
</div>
<div class="card-body">
<table class="table table-striped table-borderless">
<thead>
<tr>
<th>Subject</th>
<th>Frequency</th>
<th>Next</th>
<th>Client</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_recurring_tickets)) {
$recurring_ticket_id = intval($row['recurring_ticket_id']);
$recurring_ticket_subject = nullable_htmlentities($row['recurring_ticket_subject']);
$recurring_ticket_frequency = nullable_htmlentities($row['recurring_ticket_frequency']);
$recurring_ticket_next_run = nullable_htmlentities($row['recurring_ticket_next_run']);
$client_name = nullable_htmlentities($row['client_name']);
$client_id = intval($row['client_id']);
?>
<tr>
<td><a href="recurring_tickets.php"><?php echo $recurring_ticket_subject; ?></a></td>
<td><?php echo $recurring_ticket_frequency; ?></td>
<td><?php echo $recurring_ticket_next_run; ?></td>
<td><a href="recurring_tickets.php?client_id=<?php echo $client_id ?>"><?php echo $client_name; ?></a></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
<?php } ?>
<?php if (mysqli_num_rows($sql_credentials) > 0) { ?>
<!-- Credentials -->
<div class="col-sm-6">
<div class="card card-dark mb-3">
<div class="card-header">
<h3 class="card-title"><i class="fas fa-fw fa-key mr-2"></i>Credentials</h3>
</div>
<div class="card-body">
<table class="table table-striped table-borderless">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Username</th>
<th>Password</th>
<th>Client</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_credentials)) {
$credential_name = nullable_htmlentities($row['credential_name']);
$credential_description = nullable_htmlentities($row['credential_description']);
$credential_client_id = intval($row['credential_client_id']);
$credential_username = nullable_htmlentities(decryptCredentialEntry($row['credential_username']));
$credential_password = nullable_htmlentities(decryptCredentialEntry($row['credential_password']));
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
?>
<tr>
<td><a href="credentials.php?client_id=<?php echo $credential_client_id ?>&q=<?php echo $q ?>"><?php echo $credential_name; ?></a></td>
<td><?php echo $credential_description; ?></td>
<td><?php echo $credential_username; ?></td>
<td><a tabindex="0" class="btn btn-sm" data-toggle="popover" data-trigger="focus" data-placement="left" data-content="<?php echo $credential_password; ?>"><i class="far fa-eye text-secondary"></i></a><button class="btn btn-sm clipboardjs" data-clipboard-text="<?php echo $credential_password; ?>"><i class="far fa-copy text-secondary"></i></button>
</td>
<td><a href="credentials.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
<?php } ?>
<?php if (mysqli_num_rows($sql_invoices) > 0) { ?>
<!-- Contacts-->
<div class="col-sm-6">
<div class="card card-dark mb-3">
<div class="card-header">
<h6 class="card-title"><i class="fas fa-fw fa-file-invoice mr-2"></i>Invoices</h6>
</div>
<div class="card-body">
<table class="table table-striped table-borderless">
<thead>
<tr>
<th>Number</th>
<th>Status</th>
<th>Amount</th>
<th>Client</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_invoices)) {
$invoice_id = intval($row['invoice_id']);
$invoice_prefix = nullable_htmlentities($row['invoice_prefix']);
$invoice_number = intval($row['invoice_number']);
$invoice_amount = floatval($row['invoice_amount']);
$invoice_currency_code = nullable_htmlentities($row['invoice_currency_code']);
$invoice_status = nullable_htmlentities($row['invoice_status']);
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
?>
<tr>
<td><a href="invoice.php?invoice_id=<?php echo $invoice_id; ?>"><?php echo "$invoice_prefix$invoice_number"; ?></a></td>
<td><?php echo $invoice_status; ?></td>
<td><?php echo numfmt_format_currency($currency_format, $invoice_amount, $invoice_currency_code); ?></td>
<td><a href="client_overview.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
<?php } ?>
<?php if (mysqli_num_rows($sql_assets) > 0) { ?>
<!-- Contacts-->
<div class="col-sm-6">
<div class="card card-dark mb-3">
<div class="card-header">
<h6 class="card-title"><i class="fas fa-fw fa-desktop mr-2"></i>Assets</h6>
</div>
<div class="card-body">
<table class="table table-striped table-borderless">
<thead>
<tr>
<th>Asset</th>
<th>Type</th>
<th>Serial</th>
<th>Client</th>
<th>Assigned</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_assets)) {
$client_id = intval($row['asset_client_id']);
$client_name = nullable_htmlentities($row['client_name']);
$asset_id = intval($row['asset_id']);
$asset_type = nullable_htmlentities($row['asset_type']);
$asset_name = nullable_htmlentities($row['asset_name']);
$asset_description = nullable_htmlentities($row['asset_description']);
if (empty($asset_description)) {
$asset_description_display = "-";
} else {
$asset_description_display = $asset_description;
}
$asset_make = nullable_htmlentities($row['asset_make']);
$asset_model = nullable_htmlentities($row['asset_model']);
$asset_serial = nullable_htmlentities($row['asset_serial']);
if (empty($asset_serial)) {
$asset_serial_display = "-";
} else {
$asset_serial_display = $asset_serial;
}
$asset_uri = nullable_htmlentities($row['asset_uri']);
$asset_status = nullable_htmlentities($row['asset_status']);
$asset_created_at = nullable_htmlentities($row['asset_created_at']);
$asset_location_id = intval($row['asset_location_id']);
$asset_contact_id = intval($row['asset_contact_id']);
$device_icon = getAssetIcon($asset_type);
$contact_name = nullable_htmlentities($row['contact_name']);
$contact_id = nullable_htmlentities($row['contact_id']);
if (empty($contact_name)) {
$contact_name_display = "-";
}else{
$contact_name_display = "<a href='contact_details.php?client_id=$client_id&contact_id=$contact_id'>$contact_name</a>";
}
$contact_archived_at = nullable_htmlentities($row['contact_archived_at']);
if (empty($contact_archived_at)) {
$contact_archived_display = "";
} else {
$contact_archived_display = "Archived - ";
}
?>
<tr>
<td>
<i class="fa fa-fw text-secondary fa-<?php echo $device_icon; ?> mr-2"></i><a href="asset_details.php?client_id=<?php echo $client_id; ?>&asset_id=<?php echo $asset_id; ?>"><?php echo $asset_name; ?></a>
<?php if(!empty($asset_uri)){ ?>
<a href="<?php echo $asset_uri; ?>" target="_blank"><i class="fas fa-fw fa-external-link-alt ml-2"></i></a>
<?php } ?>
</td>
<td><?php echo $asset_type; ?></td>
<td><?php echo $asset_serial_display; ?></td>
<td><a href="assets.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
<td><?php echo $contact_name_display; ?></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
<?php } ?>
<?php if (mysqli_num_rows($sql_ticket_replies) > 0) { ?>
<!-- Ticket Replies -->
<div class="col-sm-6">
<div class="card card-dark">
<div class="card-header">
<h6 class="card-title"><i class="fas fa-fw fa-reply mr-2"></i>Ticket Replies</h6>
</div>
<div class="card-body">
<?php
$last_ticket_id = null; // Track the last ticket ID processed
while ($row = mysqli_fetch_array($sql_ticket_replies)) {
$ticket_id = intval($row['ticket_id']);
// Only output the ticket header if we're at a new ticket
if ($ticket_id !== $last_ticket_id) {
if ($last_ticket_id !== null) {
// Close the previous ticket's card (except for the very first ticket)
echo '</div></div>';
}
$ticket_prefix = nullable_htmlentities($row['ticket_prefix']);
$ticket_number = intval($row['ticket_number']);
$ticket_subject = nullable_htmlentities($row['ticket_subject']);
$client_id = intval($row['ticket_client_id']);
$client_name = nullable_htmlentities($row['client_name']);
// Output the ticket header
?>
<div class="card card-outline">
<div class="card-header">
<h3 class="card-title">
<?php echo "$client_name - $ticket_prefix$ticket_number - $ticket_subject"; ?>
</h3>
<div class="card-tools">
<a href="ticket.php?ticket_id=<?php echo $ticket_id; ?>" target="_blank">Open <i class="fa fa-fw fa-external-link-alt"></i></a>
</div>
</div>
<div class="card-body prettyContent">
<?php
}
$ticket_reply = $purifier->purify($row['ticket_reply']);
// Output the ticket reply
?>
<div class="media">
<i class="fas fa-fw fa-reply mr-3"></i>
<div class="media-body">
<?php echo $ticket_reply; ?>
</div>
</div>
<hr>
<?php
$last_ticket_id = $ticket_id; // Update the last ticket ID
}
if ($last_ticket_id !== null) {
// Close the last ticket's card
echo '</div></div>';
}
?>
</div>
</div>
</div>
</div>
<?php } ?>
</div>
</div>
</div>
<?php
}
require_once "../includes/footer.php";
?>
<script src="../js/pretty_content.js"></script>

View File

@@ -0,0 +1,172 @@
<?php
// Badge Counts
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('contact_id') AS num FROM contacts LEFT JOIN clients ON contact_client_id = client_id WHERE contact_archived_at IS NULL AND client_archived_at IS NULL"));
$num_contacts = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('location_id') AS num FROM locations LEFT JOIN clients ON location_client_id = client_id WHERE location_archived_at IS NULL AND client_archived_at IS NULL"));
$num_locations = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('asset_id') AS num FROM assets LEFT JOIN clients ON asset_client_id = client_id WHERE asset_archived_at IS NULL AND client_archived_at IS NULL"));
$num_assets = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('service_id') AS num FROM services LEFT JOIN clients ON service_client_id = client_id WHERE client_archived_at IS NULL"));
$num_services = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('credential_id') AS num FROM credentials LEFT JOIN clients ON credential_client_id = client_id WHERE credential_archived_at IS NULL AND client_archived_at IS NULL"));
$num_credentials = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('network_id') AS num FROM networks LEFT JOIN clients ON network_client_id = client_id WHERE network_archived_at IS NULL AND client_archived_at IS NULL"));
$num_networks = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('domain_id') AS num FROM domains LEFT JOIN clients ON domain_client_id = client_id WHERE domain_archived_at IS NULL AND client_archived_at IS NULL"));
$num_domains = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('certificate_id') AS num FROM certificates LEFT JOIN clients ON certificate_client_id = client_id WHERE certificate_archived_at IS NULL AND client_archived_at IS NULL"));
$num_certificates = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('software_id') AS num FROM software LEFT JOIN clients ON software_client_id = client_id WHERE software_archived_at IS NULL AND client_archived_at IS NULL"));
$num_software = $row['num'];
?>
<!-- Main Sidebar Container -->
<aside class="main-sidebar sidebar-dark-primary d-print-none">
<a class="pb-1 mt-1 brand-link" href="clients.php">
<p class="h6"><i class="nav-icon fas fa-arrow-left ml-3 mr-2"></i>
<span class="brand-text ">Back | <strong>Client Overview</strong>
</p>
</a>
<!-- Sidebar -->
<div class="sidebar">
<!-- Sidebar Menu -->
<nav>
<ul class="nav nav-pills nav-sidebar flex-column mt-2" data-widget="treeview" data-accordion="false">
<?php if (lookupUserPermission("module_support") >= 1) { ?>
<li class="nav-item">
<a href="contacts.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "contacts.php" || basename($_SERVER["PHP_SELF"]) == "contact_details.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-address-book"></i>
<p>
Contacts
<?php
if ($num_contacts > 0) { ?>
<span class="right badge text-light"><?php echo $num_contacts; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="locations.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "locations.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-map-marker-alt"></i>
<p>
Locations
<?php
if ($num_locations > 0) { ?>
<span class="right badge text-light"><?php echo $num_locations; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="assets.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "assets.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-desktop"></i>
<p>
Assets
<?php
if ($num_assets > 0) { ?>
<span class="right badge text-light"><?php echo $num_assets; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="software.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "software.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-cube"></i>
<p>
Licenses
<?php
if ($num_software > 0) { ?>
<span class="right badge text-light"><?php echo $num_software; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="credentials.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "credentials.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-key"></i>
<p>
Credentials
<?php
if ($num_credentials > 0) { ?>
<span class="right badge text-light"><?php echo $num_credentials; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="networks.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "networks.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-network-wired"></i>
<p>
Networks
<?php
if ($num_networks > 0) { ?>
<span class="right badge text-light"><?php echo $num_networks; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="certificates.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "certificates.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-lock"></i>
<p>
Certificates
<?php
if ($num_certificates > 0) { ?>
<span class="right badge text-light"><?php echo $num_certificates; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="domains.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "domains.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-globe"></i>
<p>
Domains
<?php
if ($num_domains > 0) { ?>
<span class="right badge text-light"><?php echo $num_domains; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="services.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "services.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-stream"></i>
<p>
Services
<?php
if ($num_services > 0) { ?>
<span class="right badge text-light"><?php echo $num_services; ?></span>
<?php } ?>
</p>
</a>
</li>
<?php } ?>
</ul>
</nav>
<!-- /.sidebar-menu -->
<div class="sidebar-custom mb-3">
</div>
</div>
<!-- /.sidebar -->
</aside>

View File

@@ -0,0 +1,354 @@
<!-- Main Sidebar Container -->
<aside class="main-sidebar sidebar-dark-<?php if (isset($_GET['client_id'])) { echo "gray"; } else { echo nullable_htmlentities($config_theme); } ?> d-print-none">
<a class="brand-link pb-1 mt-1" href="clients.php">
<p class="h5">
<i class="nav-icon fas fa-arrow-left ml-3 mr-2"></i>
<span class="brand-text">
Back | <strong><?php echo $client_abbreviation; ?></strong>
</span>
</p>
</a>
<!-- Sidebar -->
<div class="sidebar">
<!-- Sidebar Menu -->
<nav>
<ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
<li class="nav-item mt-3">
<a href="client_overview.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "client_overview.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-tachometer-alt"></i>
<p>Overview</p>
</a>
</li>
<li class="nav-item">
<a href="contacts.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "contacts.php" || basename($_SERVER["PHP_SELF"]) == "contact_details.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-address-book"></i>
<p>
Contacts
<?php
if ($num_contacts > 0) { ?>
<span class="right badge text-light"><?php echo $num_contacts; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="locations.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "locations.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-map-marker-alt"></i>
<p>
Locations
<?php
if ($num_locations > 0) { ?>
<span class="right badge text-light"><?php echo $num_locations; ?></span>
<?php } ?>
</p>
</a>
</li>
<?php if ($config_module_enable_ticketing == 1 && lookupUserPermission("module_support") >= 1) { ?>
<li class="nav-header mt-3">SUPPORT</li>
<li class="nav-item">
<a href="tickets.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "tickets.php" || basename($_SERVER["PHP_SELF"]) == "ticket.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-life-ring"></i>
<p>
Tickets
<?php
if ($num_active_tickets > 0) { ?>
<span class="right badge <?php if ($num_active_tickets > 0) { ?> badge-danger <?php } ?> text-light"><?php echo $num_active_tickets; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="recurring_tickets.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "recurring_tickets.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-redo-alt"></i>
<p>
Recurring Tickets
<?php
if ($num_recurring_tickets) { ?>
<span class="right badge"><?php echo $num_recurring_tickets; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="projects.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "projects.php" || basename($_SERVER["PHP_SELF"]) == "project_details.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-project-diagram"></i>
<p>
Projects
<?php if ($num_active_projects) { ?>
<span class="right badge text-light" data-toggle="tooltip" title="Open Projects"><?php echo $num_active_projects; ?></span>
<?php } ?>
</p>
</a>
</li>
<?php } ?>
<li class="nav-item">
<a href="vendors.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "vendors.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-building"></i>
<p>
Vendors
<?php
if ($num_vendors > 0) { ?>
<span class="right badge text-light"><?php echo $num_vendors; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="calendar.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "calendar.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-calendar-alt"></i>
<p>
Calendar
<?php
if ($num_calendar_events > 0) { ?>
<span class="right badge text-light"><?php echo $num_calendar_events; ?></span>
<?php } ?>
</p>
</a>
</li>
<?php if ($config_module_enable_itdoc == 1) { ?>
<li class="nav-header mt-3">DOCUMENTATION</li>
<?php if (lookupUserPermission("module_support") >= 1) { ?>
<li class="nav-item">
<a href="assets.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "assets.php" || basename($_SERVER["PHP_SELF"]) == "client_asset_details.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-desktop"></i>
<p>
Assets
<?php
if ($num_assets > 0) { ?>
<span class="right badge text-light"><?php echo $num_assets; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="software.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "software.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-cube"></i>
<p>
Licenses
<?php
if ($num_software > 0) { ?>
<span class="right badge <?php if ($num_software_expiring > 0) { ?> badge-warning text-dark <?php } ?> <?php if ($num_software_expired > 0) { ?> badge-danger <?php } ?> text-white"><?php echo $num_software; ?></span>
<?php } ?>
</p>
</a>
</li>
<?php if (lookupUserPermission("module_credential") >= 1) { ?>
<li class="nav-item">
<a href="credentials.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "credentials.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-key"></i>
<p>
Credentials
<?php
if ($num_credentials > 0) { ?>
<span class="right badge text-light"><?php echo $num_credentials; ?></span>
<?php } ?>
</p>
</a>
</li>
<?php } ?>
<li class="nav-item">
<a href="networks.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "networks.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-network-wired"></i>
<p>
Networks
<?php
if ($num_networks > 0) { ?>
<span class="right badge text-light"><?php echo $num_networks; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="racks.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "racks.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-server"></i>
<p>
Racks
<?php
if ($num_racks > 0) { ?>
<span class="right badge text-light"><?php echo $num_racks; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="certificates.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "certificates.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-lock"></i>
<p>
Certificates
<?php
if ($num_certificates > 0) { ?>
<span class="right badge <?php if ($num_certificates_expiring > 0) { ?> badge-warning text-dark <?php } ?> <?php if ($num_certificates_expired > 0) { ?> badge-danger <?php } ?> text-white"><?php echo $num_certificates; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="domains.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "domains.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-globe"></i>
<p>
Domains
<?php
if ($num_domains > 0) { ?>
<span class="right badge <?php if (isset($num_domains_expiring)) { ?> badge-warning text-dark<?php } ?> <?php if (isset($num_domains_expired)) { ?> badge-danger <?php } ?> text-white"><?php echo $num_domains; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="services.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "services.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-stream"></i>
<p>
Services
<?php
if ($num_services > 0) { ?>
<span class="right badge text-light"><?php echo $num_services; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="documents.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "documents.php" || basename($_SERVER["PHP_SELF"]) == "document_details.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-folder"></i>
<p>
Documents
<?php
if ($num_documents > 0) { ?>
<span class="right badge text-light"><?php echo $num_documents; ?></span>
<?php } ?>
</p>
</a>
</li>
<?php } ?>
<!-- Allow files even without module_support for things like contracts, etc. ) -->
<li class="nav-item">
<a href="files.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "files.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-paperclip"></i>
<p>
Files
<?php
if ($num_files > 0) { ?>
<span class="right badge text-light"><?php echo $num_files; ?></span>
<?php } ?>
</p>
</a>
</li>
<?php } ?>
<?php if ($config_module_enable_accounting == 1) { ?>
<li class="nav-header mt-3">BILLING</li>
<?php if (lookupUserPermission("module_sales") >= 1) { ?>
<li class="nav-item">
<a href="invoices.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "invoices.php" || basename($_SERVER["PHP_SELF"]) == "invoice.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-file-invoice"></i>
<p>
Invoices
<?php
if ($num_invoices > 0) { ?>
<span class="right badge <?php if ($num_invoices_open > 0) { ?> badge-danger <?php } ?> text-light"><?php echo $num_invoices; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="recurring_invoices.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "recurring_invoices.php" || basename($_SERVER["PHP_SELF"]) == "recurring_invoice.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-redo-alt"></i>
<p>
Recurring Invoices
<?php
if ($num_recurring_invoices) { ?>
<span class="right badge"><?php echo $num_recurring_invoices; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="quotes.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "quotes.php" || basename($_SERVER["PHP_SELF"]) == "quote.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-comment-dollar"></i>
<p>
Quotes
<?php
if ($num_quotes > 0) { ?>
<span class="right badge text-light"><?php echo $num_quotes; ?></span>
<?php } ?>
</p>
</a>
</li>
<?php } ?>
<?php if (lookupUserPermission("module_financial") >= 1) { ?>
<li class="nav-item">
<a href="payments.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "payments.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-credit-card"></i>
<p>
Payments
<?php
if ($num_payments > 0) { ?>
<span class="right badge text-light"><?php echo $num_payments; ?></span>
<?php } ?>
</p>
</a>
</li>
<?php } ?>
<li class="nav-item">
<a href="trips.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "trips.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-route"></i>
<p>
Trips
<?php
if ($num_trips > 0) { ?>
<span class="right badge text-light"><?php echo $num_trips; ?></span>
<?php } ?>
</p>
</a>
</li>
<?php } ?>
</ul>
</nav>
<!-- /.sidebar-menu -->
<div class="mb-3"></div>
</div>
<!-- /.sidebar -->
</aside>

View File

@@ -0,0 +1,34 @@
<?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 $access_permission_query"));
$num_active_clients = $row['num'];
// Active Ticket Count
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('ticket_id') AS num FROM tickets LEFT JOIN clients ON client_id = ticket_client_id WHERE ticket_archived_at IS NULL AND ticket_closed_at IS NULL AND ticket_status != 4 $access_permission_query"));
$num_active_tickets = $row['num'];
// Recurring Ticket Count
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('recurring_ticket_id') AS num FROM recurring_tickets LEFT JOIN clients ON client_id = recurring_ticket_client_id WHERE 1 = 1 $access_permission_query"));
$num_recurring_tickets = $row['num'];
// Active Project Count
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('project_id') AS num FROM projects WHERE project_archived_at IS NULL AND project_completed_at IS NULL"));
$num_active_projects = $row['num'];
// Open Invoices Count
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('invoice_id') AS num FROM invoices WHERE (invoice_status = 'Sent' OR invoice_status = 'Viewed' OR invoice_status = 'Partial') AND invoice_archived_at IS NULL"));
$num_open_invoices = $row['num'];
// Recurring Invoice Count
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('recurring_invoice_id') AS num FROM recurring_invoices WHERE recurring_invoice_archived_at IS NULL"));
$num_recurring_invoices = $row['num'];
// Open Quotes Count
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('quote_id') AS num FROM quotes WHERE (quote_status = 'Sent' OR quote_status = 'Viewed') AND quote_archived_at IS NULL"));
$num_open_quotes = $row['num'];
// Recurring Expenses Count
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('recurring_expense_id') AS num FROM recurring_expenses WHERE recurring_expense_archived_at IS NULL"));
$num_recurring_expenses = $row['num'];

View File

@@ -0,0 +1,20 @@
<?php
// Configuration & core
require_once "../config.php";
require_once "../functions.php";
require_once "../includes/router.php";
require_once "../includes/check_login.php";
// Page setup
require_once "../includes/page_title.php";
// Layout UI
require_once "../includes/header.php";
require_once "../includes/top_nav.php";
require_once "includes/get_side_nav_counts.php";
require_once "includes/side_nav.php";
// Wrapper & alerts
require_once "../includes/inc_wrapper.php";
require_once "../includes/inc_alert_feedback.php";
require_once "../includes/filter_header.php";

View File

@@ -0,0 +1,314 @@
<?php
require_once "../config.php";
require_once "../functions.php";
require_once "../includes/router.php";
require_once "../includes/check_login.php";
require_once "../includes/page_title.php";
// Perms
enforceUserPermission('module_client');
if (isset($_GET['client_id'])) {
$client_id = intval($_GET['client_id']);
// Client Access Check
// Ensure the user has permission to access this client (admins ignored)
if (!in_array($client_id, $client_access_array) AND !empty($client_access_string) AND !$session_is_admin) {
// 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(
$mysqli,
"SELECT * FROM clients
LEFT JOIN locations ON clients.client_id = locations.location_client_id AND location_primary = 1
LEFT JOIN contacts ON clients.client_id = contacts.contact_client_id AND contact_primary = 1
WHERE client_id = $client_id"
);
if (mysqli_num_rows($sql) == 0) {
require_once "../includes/header.php";
echo "<center><h1 class='text-secondary mt-5'>Nothing to see here</h1></center>";
} else {
$row = mysqli_fetch_array($sql);
$client_name = nullable_htmlentities($row['client_name']);
$client_is_lead = intval($row['client_lead']);
$client_type = nullable_htmlentities($row['client_type']);
$client_website = nullable_htmlentities($row['client_website']);
$client_referral = nullable_htmlentities($row['client_referral']);
$client_currency_code = nullable_htmlentities($row['client_currency_code']);
$client_net_terms = intval($row['client_net_terms']);
$client_tax_id_number = nullable_htmlentities($row['client_tax_id_number']);
$client_abbreviation = nullable_htmlentities($row['client_abbreviation']);
$client_rate = floatval($row['client_rate']);
$client_notes = nullable_htmlentities($row['client_notes']);
$client_created_at = nullable_htmlentities($row['client_created_at']);
$client_archived_at = nullable_htmlentities($row['client_archived_at']);
$contact_id = intval($row['contact_id']);
$contact_name = nullable_htmlentities($row['contact_name']);
$contact_title = nullable_htmlentities($row['contact_title']);
$contact_email = nullable_htmlentities($row['contact_email']);
$contact_phone_country_code = nullable_htmlentities($row['contact_phone_country_code']);
$contact_phone = nullable_htmlentities(formatPhoneNumber($row['contact_phone'], $contact_phone_country_code));
$contact_extension = nullable_htmlentities($row['contact_extension']);
$contact_mobile_country_code = nullable_htmlentities($row['contact_mobile_country_code']);
$contact_mobile = nullable_htmlentities(formatPhoneNumber($row['contact_mobile'], $contact_mobile_country_code));
$contact_primary = intval($row['contact_primary']);
$location_id = intval($row['location_id']);
$location_name = nullable_htmlentities($row['location_name']);
$location_address = nullable_htmlentities($row['location_address']);
$location_city = nullable_htmlentities($row['location_city']);
$location_state = nullable_htmlentities($row['location_state']);
$location_zip = nullable_htmlentities($row['location_zip']);
$location_country = nullable_htmlentities($row['location_country']);
$location_phone_country_code = nullable_htmlentities($row['location_phone_country_code']);
$location_phone = nullable_htmlentities(formatPhoneNumber($row['location_phone'], $location_phone_country_code));
$location_primary = intval($row['location_primary']);
// Tab Title // No Sanitizing needed
$tab_title = $row['client_name'];
// 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.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']);
$client_tag_name = nullable_htmlentities($row['tag_name']);
$client_tag_color = nullable_htmlentities($row['tag_color']);
if (empty($client_tag_color)) {
$client_tag_color = "dark";
}
$client_tag_icon = nullable_htmlentities($row['tag_icon']);
if (empty($client_tag_icon)) {
$client_tag_icon = "tag";
}
$client_tag_id_array[] = $client_tag_id;
$client_tag_name_display_array[] = "<span class='badge text-light p-1 mr-1' style='background-color: $client_tag_color;'><i class='fa fa-fw fa-$client_tag_icon mr-2'></i>$client_tag_name</span>";
}
$client_tags_display = implode('', $client_tag_name_display_array);
//Add up all the payments for the invoice and get the total amount paid to the invoice
$sql_invoice_amounts = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS invoice_amounts FROM invoices WHERE invoice_client_id = $client_id AND invoice_status != 'Draft' AND invoice_status != 'Cancelled' AND invoice_status != 'Non-Billable'");
$row = mysqli_fetch_array($sql_invoice_amounts);
$invoice_amounts = floatval($row['invoice_amounts']);
$sql_amount_paid = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS amount_paid FROM payments, invoices WHERE payment_invoice_id = invoice_id AND invoice_client_id = $client_id");
$row = mysqli_fetch_array($sql_amount_paid);
$amount_paid = floatval($row['amount_paid']);
$balance = $invoice_amounts - $amount_paid;
//Get Monthly Recurring Total
$sql_recurring_monthly_total = mysqli_query($mysqli, "SELECT SUM(recurring_invoice_amount) AS recurring_monthly_total FROM recurring_invoices WHERE recurring_invoice_status = 1 AND recurring_invoice_frequency = 'month' AND recurring_invoice_client_id = $client_id");
$row = mysqli_fetch_array($sql_recurring_monthly_total);
$recurring_monthly_total = floatval($row['recurring_monthly_total']);
//Get Yearly Recurring Total
$sql_recurring_yearly_total = mysqli_query($mysqli, "SELECT SUM(recurring_invoice_amount) AS recurring_yearly_total FROM recurring_invoices WHERE recurring_invoice_status = 1 AND recurring_invoice_frequency = 'year' AND recurring_invoice_client_id = $client_id");
$row = mysqli_fetch_array($sql_recurring_yearly_total);
$recurring_yearly_total = floatval($row['recurring_yearly_total']) / 12;
$recurring_monthly = $recurring_monthly_total + $recurring_yearly_total;
// Get Credit Balance
$sql_credit_balance = mysqli_query($mysqli, "SELECT SUM(credit_amount) AS credit_balance FROM credits WHERE credit_client_id = $client_id");
$row = mysqli_fetch_array($sql_credit_balance);
$credit_balance = floatval($row['credit_balance']);
// Badge Counts
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('contact_id') AS num FROM contacts WHERE contact_archived_at IS NULL AND contact_client_id = $client_id"));
$num_contacts = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('location_id') AS num FROM locations WHERE location_archived_at IS NULL AND location_client_id = $client_id"));
$num_locations = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('asset_id') AS num FROM assets WHERE asset_archived_at IS NULL AND asset_client_id = $client_id"));
$num_assets = $row['num'];
$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 AND ticket_client_id = $client_id"));
$num_active_tickets = $row['num'];
$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 NOT NULL AND ticket_client_id = $client_id"));
$num_closed_tickets = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('recurring_ticket_id') AS num FROM recurring_tickets WHERE recurring_ticket_client_id = $client_id"));
$num_recurring_tickets = $row['num'];
// Active Project Count
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('project_id') AS num FROM projects WHERE project_archived_at IS NULL AND project_completed_at IS NULL AND project_client_id = $client_id"));
$num_active_projects = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('service_id') AS num FROM services WHERE service_client_id = $client_id"));
$num_services = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('vendor_id') AS num FROM vendors WHERE vendor_archived_at IS NULL AND vendor_client_id = $client_id"));
$num_vendors = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('credential_id') AS num FROM credentials WHERE credential_archived_at IS NULL AND credential_client_id = $client_id"));
$num_credentials = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('network_id') AS num FROM networks WHERE network_archived_at IS NULL AND network_client_id = $client_id"));
$num_networks = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('rack_id') AS num FROM racks WHERE rack_archived_at IS NULL AND rack_client_id = $client_id"));
$num_racks = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('domain_id') AS num FROM domains WHERE domain_archived_at IS NULL AND domain_client_id = $client_id"));
$num_domains = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('certificate_id') AS num FROM certificates WHERE certificate_archived_at IS NULL AND certificate_client_id = $client_id"));
$num_certificates = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('software_id') AS num FROM software WHERE software_archived_at IS NULL AND software_client_id = $client_id"));
$num_software = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('invoice_id') AS num FROM invoices WHERE (invoice_status = 'Sent' OR invoice_status = 'Viewed' OR invoice_status = 'Partial') AND invoice_archived_at IS NULL AND invoice_client_id = $client_id"));
$num_invoices_open = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('invoice_id') AS num FROM invoices WHERE invoice_status = 'Draft' AND invoice_archived_at IS NULL AND invoice_client_id = $client_id"));
$num_invoices_draft = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('invoice_id') AS num FROM invoices WHERE invoice_status = 'Sent' AND invoice_archived_at IS NULL AND invoice_client_id = $client_id"));
$num_invoices_sent = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('invoice_id') AS num FROM invoices WHERE invoice_status = 'Viewed' AND invoice_archived_at IS NULL AND invoice_client_id = $client_id"));
$num_invoices_viewed = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('invoice_id') AS num FROM invoices WHERE invoice_status = 'Partial' AND invoice_archived_at IS NULL AND invoice_client_id = $client_id"));
$num_invoices_partial = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('invoice_id') AS num FROM invoices WHERE invoice_status = 'Paid' AND invoice_archived_at IS NULL AND invoice_client_id = $client_id"));
$num_invoices_paid = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('invoice_id') AS num FROM invoices WHERE invoice_archived_at IS NULL AND invoice_client_id = $client_id"));
$num_invoices = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('quote_id') AS num FROM quotes WHERE quote_archived_at IS NULL AND quote_client_id = $client_id"));
$num_quotes = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('recurring_invoice_id') AS num FROM recurring_invoices WHERE recurring_invoice_archived_at IS NULL AND recurring_invoice_client_id = $client_id"));
$num_recurring_invoices = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('payment_id') AS num FROM payments, invoices WHERE payment_invoice_id = invoice_id AND invoice_client_id = $client_id"));
$num_payments = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('file_id') AS num FROM files WHERE file_archived_at IS NULL AND file_client_id = $client_id"));
$num_files = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('document_id') AS num FROM documents WHERE document_archived_at IS NULL AND document_client_id = $client_id"));
$num_documents = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('event_id') AS num FROM calendar_events WHERE event_client_id = $client_id"));
$num_calendar_events = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('trip_id') AS num FROM trips WHERE trip_archived_at IS NULL AND trip_client_id = $client_id"));
$num_trips = $row['num'];
// Expiring Items
// Count Domains Expiring within 45 Days
$row = mysqli_fetch_assoc(mysqli_query(
$mysqli,
"SELECT COUNT('domain_id') AS num FROM domains
WHERE domain_client_id = $client_id
AND domain_expire IS NOT NULL
AND domain_expire < CURRENT_DATE + INTERVAL 45 DAY
AND domain_archived_at IS NULL"
));
$num_domains_expiring_warning= intval($row['num']);
// Count Domains Expired or within 7 days
$row = mysqli_fetch_assoc(mysqli_query(
$mysqli,
"SELECT COUNT('domain_id') AS num FROM domains
WHERE domain_client_id = $client_id
AND domain_expire IS NOT NULL
AND (
domain_expire < CURRENT_DATE
OR domain_expire < CURRENT_DATE + INTERVAL 7 DAY
)
AND domain_archived_at IS NULL"
));
$num_domains_urgent = intval($row['num']);
// Count Certificates Expiring within 7 Days
$row = mysqli_fetch_assoc(mysqli_query(
$mysqli,
"SELECT COUNT('certificate_id') AS num FROM certificates
WHERE certificate_client_id = $client_id
AND certificate_expire IS NOT NULL
AND certificate_expire < CURRENT_DATE + INTERVAL 7 DAY
AND certificate_archived_at IS NULL"
));
$num_certificates_expiring = intval($row['num']);
// Count Certificates Expired or within 7 days
$row = mysqli_fetch_assoc(mysqli_query(
$mysqli,
"SELECT COUNT('certificate_id') AS num FROM certificates
WHERE certificate_client_id = $client_id
AND certificate_expire IS NOT NULL
AND (
certificate_expire < CURRENT_DATE
OR certificate_expire < CURRENT_DATE + INTERVAL 1 DAY
)
AND certificate_archived_at IS NULL"
));
$num_certificates_expired = intval($row['num']);
// Count Software Expiring within 90 Days
$row = mysqli_fetch_assoc(mysqli_query(
$mysqli,
"SELECT COUNT('software_id') AS num FROM software
WHERE software_client_id = $client_id
AND software_expire IS NOT NULL
AND software_expire < CURRENT_DATE + INTERVAL 45 DAY
AND software_archived_at IS NULL"
));
$num_software_expiring = intval($row['num']);
// Count Software Expired or within 14 days
$row = mysqli_fetch_assoc(mysqli_query(
$mysqli,
"SELECT COUNT('software_id') AS num FROM software
WHERE software_client_id = $client_id
AND software_expire IS NOT NULL
AND (
software_expire < CURRENT_DATE
OR software_expire < CURRENT_DATE + INTERVAL 7 DAY
)
AND software_archived_at IS NULL"
));
$num_software_expired = intval($row['num']);
}
}
require_once "../includes/header.php";
require_once "../includes/top_nav.php";
require_once "includes/client_side_nav.php";
require_once "../includes/inc_wrapper.php";
require_once "../includes/inc_alert_feedback.php";
require_once "includes/inc_client_top_head.php";
require_once "../includes/filter_header.php";

View File

@@ -0,0 +1,14 @@
<?php
require_once "../config.php";
require_once "../functions.php";
require_once "../includes/router.php";
require_once "../includes/check_login.php";
require_once "../includes/page_title.php";
require_once "../includes/header.php";
require_once "../includes/top_nav.php";
require_once "includes/user_side_nav.php";
require_once "../includes/inc_wrapper.php";
require_once "../includes/inc_alert_feedback.php";
require_once "../includes/filter_header.php";

View File

@@ -0,0 +1,14 @@
<?php
require_once "../config.php";
require_once "../functions.php";
require_once "../includes/router.php";
require_once "../includes/check_login.php";
require_once "../includes/page_title.php";
require_once "../includes/header.php";
require_once "../includes/top_nav.php";
require_once "includes/client_overview_side_nav.php";
require_once "../includes/inc_wrapper.php";
require_once "../includes/inc_alert_feedback.php";
require_once "../includes/filter_header.php";

View File

@@ -0,0 +1,188 @@
<?php $show_add_credit = 0; // Remove once credits is added hides the button ?>
<div class="card d-print-none">
<div class="card-header pb-1 pt-2 px-3">
<div class="card-title">
<a href="#" data-toggle="collapse" data-target="#clientHeader"><h4 class="text-dark" data-toggle="tooltip" data-placement="right" title="Client ID: <?php echo $client_id; ?>"><strong><?php echo $client_name; ?></strong> <?php if ($client_archived_at) { echo "(archived)"; } ?></h4></a>
</div>
<?php if (!empty($client_tag_name_display_array)) { ?><div class="card-title ml-2"><?php echo $client_tags_display; ?></div> <?php } ?>
<?php if (lookupUserPermission("module_client") >= 2) { ?>
<div class="card-tools">
<div class="dropdown dropleft text-center">
<button class="btn btn-dark btn-sm" type="button" data-toggle="dropdown">
<i class="fas fa-fw fa-ellipsis-v"></i>
</button>
<div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/client/client_edit.php?id=<?= $client_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit Client
</a>
<?php if (lookupUserPermission("module_billing") >= 2) { ?>
<?php if ($show_add_credit) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#addCreditModal">
<i class="fas fa-fw fa-wallet mr-2"></i>Add Credit
</a>
<?php } ?>
<?php } ?>
<?php if (lookupUserPermission("module_client") >= 3) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#exportClientPDFModal">
<i class="fas fa-fw fa-file-pdf mr-2"></i>Export Data
</a>
<?php } ?>
<?php if (empty($client_archived_at)) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_client=<?php echo $client_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive Client
</a>
<?php } else { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-primary confirm-link" href="post.php?undo_archive_client=<?php echo $client_id; ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Unarchive Client
</a>
<?php } ?>
<?php if (lookupUserPermission("module_client") >= 3 && $client_archived_at) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold" href="#" data-toggle="modal" data-target="#deleteClientModal<?php echo $client_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete Client
</a>
<?php } ?>
</div>
</div>
</div>
<?php } ?>
</div>
</div>
<div class="collapse <?php if (basename($_SERVER["PHP_SELF"]) == "client_overview.php") { echo "show"; } ?>" id="clientHeader">
<div class="card-group mb-3">
<div class="card card-body px-3 py-2">
<h5>Primary Location</h5>
<?php if (!empty($location_address)) { ?>
<div>
<a href="//maps.<?php echo $session_map_source; ?>.com/?q=<?php echo "$location_address $location_zip"; ?>" target="_blank">
<i class="fa fa-fw fa-map-marker-alt text-secondary ml-1 mr-2"></i><?php echo $location_address; ?>
<div>
<i class="fa fa-fw ml-1 mr-2"></i><?php echo "$location_city $location_state $location_zip"; ?>
</div>
<div>
<i class="fa fa-fw ml-1 mr-2"></i><small><?php echo $location_country; ?></small>
</div>
</a>
</div>
<?php }
if (!empty($location_phone)) { ?>
<div>
<i class="fa fa-fw fa-phone text-secondary ml-1 mr-2"></i><a href="tel:<?php echo $location_phone?>"><?php echo $location_phone; ?></a>
</div>
<hr class="my-2">
<?php }
if (!empty($client_website)) { ?>
<div class="mt-1">
<i class="fa fa-fw fa-globe text-secondary ml-1 mr-2"></i><a target="_blank" href="//<?php echo $client_website; ?>"><?php echo $client_website; ?></a>
</div>
<?php } ?>
</div>
<div class="card card-body px-3 py-2">
<h5>Primary Contact</h5>
<?php
if (!empty($contact_name)) { ?>
<div>
<i class="fa fa-fw fa-user text-secondary ml-1 mr-2"></i><?php echo $contact_name; ?>
</div>
<?php }
if (!empty($contact_email)) { ?>
<div class="mt-1">
<i class="fa fa-fw fa-envelope text-secondary ml-1 mr-2"></i><a href="mailto:<?php echo $contact_email; ?>"><?php echo $contact_email; ?></a>
</div>
<?php
}
if (!empty($contact_phone)) { ?>
<div class="mt-1">
<i class="fa fa-fw fa-phone text-secondary ml-1 mr-2"></i><a href="tel:<?php echo $contact_phone; ?>"><?php echo $contact_phone; ?></a>
<?php
if (!empty($contact_extension)) {
echo "<small>x$contact_extension</small>";
}
?>
</div>
<?php
}
if (!empty($contact_mobile)) { ?>
<div class="mt-1">
<i class="fa fa-fw fa-mobile-alt text-secondary ml-1 mr-2"></i><a href="tel:<?php echo $contact_mobile; ?>"><?php echo $contact_mobile; ?></a>
</div>
<?php } ?>
</div>
<?php if (lookupUserPermission("module_financial") >= 1 && $config_module_enable_accounting == 1) { ?>
<div class="card card-body px-3 py-2">
<h5>Billing</h5>
<div class="ml-1 text-secondary">Hourly Rate
<span class="text-dark float-right"> <?php echo numfmt_format_currency($currency_format, $client_rate, $client_currency_code); ?></span>
</div>
<div class="ml-1 mt-1 text-secondary">Paid
<span class="text-dark float-right"> <?php echo numfmt_format_currency($currency_format, $amount_paid, $client_currency_code); ?></span>
</div>
<div class="ml-1 mt-1 text-secondary">Balance
<span class="<?php if ($balance > 0) { echo "text-danger"; }else{ echo "text-dark"; } ?> float-right"> <?php echo numfmt_format_currency($currency_format, $balance, $client_currency_code); ?></span>
</div>
<?php /* Credit Not Ready 2025-08-27 JQ
if ($credit_balance) { ?>
<div class="ml-1 mt-1 text-secondary">Credit
<span class="text-success float-right"><?php echo numfmt_format_currency($currency_format, $credit_balance, $client_currency_code); ?></span>
</div>
<?php } */?>
<div class="ml-1 mt-1 text-secondary">Monthly Recurring
<span class="text-dark float-right"> <?php echo numfmt_format_currency($currency_format, $recurring_monthly, $client_currency_code); ?></span>
</div>
<div class="ml-1 mt-1 text-secondary">Net Terms
<span class="text-dark float-right">
<?php if ($client_net_terms) { ?>
<?= $client_net_terms; ?><small class="text-secondary ml-1">Days</small>
<?php } else { ?>
On Receipt
<?php } ?>
</span>
</div>
<?php if(!empty($client_tax_id_number)) { ?>
<div class="ml-1 mt-1 text-secondary">Tax ID
<span class="text-dark float-right"><?php echo $client_tax_id_number; ?></span>
</div>
<?php } ?>
</div>
<?php } ?>
<?php if (lookupUserPermission("module_support") >= 1 && $config_module_enable_ticketing == 1) { ?>
<div class="card card-body px-3 py-2">
<h5>Support</h5>
<div class="ml-1 text-secondary">Open Tickets
<span class="text-dark float-right"><?php echo $num_active_tickets; ?></span>
</div>
<div class="ml-1 text-secondary mt-1">Closed Tickets
<span class="text-dark float-right"><?php echo $num_closed_tickets; ?></span>
</div>
</div>
<?php } ?>
</div>
</div>
<?php
// require_once "modals/client/client_credit_add.php"; --Credit Not Ready 2025-08-27
require_once "modals/client/client_delete.php";
require_once "modals/client/client_download_pdf.php";

236
agent/includes/side_nav.php Normal file
View File

@@ -0,0 +1,236 @@
<!-- Main Sidebar Container -->
<aside class="main-sidebar sidebar-dark-<?php echo nullable_htmlentities($config_theme); ?> d-print-none">
<a class="brand-link" href="dashboard.php">
<div class="brand-image"></div>
<span class="brand-text h4"><?php echo nullable_htmlentities($session_company_name); ?></span>
</a>
<!-- Sidebar -->
<div class="sidebar">
<!-- Sidebar Menu -->
<nav>
<ul class="nav nav-pills nav-sidebar flex-column mt-3" data-widget="treeview" data-accordion="false">
<li class="nav-item">
<a href="dashboard.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "dashboard.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-tachometer-alt"></i>
<p>Dashboard</p>
</a>
</li>
<?php if (lookupUserPermission("module_client") >= 1) { ?>
<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-users"></i>
<p>
Clients
<?php if ($num_active_clients) { ?>
<span class="right badge text-light" data-toggle="tooltip" title="Active Clients"><?php echo $num_active_clients; ?></span>
<?php } ?>
</p>
</a>
</li>
<?php } ?>
<?php if (lookupUserPermission("module_support") >= 1) { ?>
<?php if ($config_module_enable_ticketing == 1) { ?>
<li class="nav-header mt-3">SUPPORT</li>
<li class="nav-item">
<a href="tickets.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "tickets.php" || basename($_SERVER["PHP_SELF"]) == "ticket.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-life-ring"></i>
<p>
Tickets
<?php if ($num_active_tickets) { ?>
<span class="right badge text-light" data-toggle="tooltip" title="Open Tickets"><?php echo $num_active_tickets; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="recurring_tickets.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "recurring_tickets.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-redo-alt"></i>
<p>
Recurring Tickets
<?php if ($num_recurring_tickets) { ?>
<span class="right badge text-light" data-toggle="tooltip" title="Active Recurring Tickets"><?php echo $num_recurring_tickets; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="projects.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "projects.php" || basename($_SERVER["PHP_SELF"]) == "project_details.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-project-diagram"></i>
<p>
Projects
<?php if ($num_active_projects) { ?>
<span class="right badge text-light" data-toggle="tooltip" title="Open Projects"><?php echo $num_active_projects; ?></span>
<?php } ?>
</p>
</a>
</li>
<?php } ?>
<?php } ?>
<li class="nav-item">
<a href="calendar.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "calendar.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-calendar-alt"></i>
<p>Calendar</p>
</a>
</li>
<?php if ($config_module_enable_accounting == 1 && lookupUserPermission("module_sales") >= 1) { ?>
<li class="nav-header mt-3">BILLING</li>
<li class="nav-item">
<a href="quotes.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "quotes.php" || basename($_SERVER["PHP_SELF"]) == "quote.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-comment-dollar"></i>
<p>
Quotes
<?php if ($num_open_quotes) { ?>
<span class="right badge text-light" data-toggle="tooltip" title="Active Quotes"><?php echo $num_open_quotes; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="invoices.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "invoices.php" || basename($_SERVER["PHP_SELF"]) == "invoice.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-file-invoice"></i>
<p>
Invoices
<?php if ($num_open_invoices) { ?>
<span class="right badge text-light" data-toggle="tooltip" title="Open Invoices"><?php echo $num_open_invoices; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="recurring_invoices.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "recurring_invoices.php" || basename($_SERVER["PHP_SELF"]) == "recurring_invoice.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-redo-alt"></i>
<p>
Recurring Invoices
<?php if ($num_recurring_invoices) { ?>
<span class="right badge text-light" data-toggle="tooltip" title="Active Recurring Invoices"><?php echo $num_recurring_invoices; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="revenues.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "revenues.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-hand-holding-usd"></i>
<p>Revenues</p>
</a>
</li>
<li class="nav-item">
<a href="products.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "products.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-box-open"></i>
<p>Products</p>
</a>
</li>
<?php } ?>
<?php if ($config_module_enable_accounting == 1 && lookupUserPermission("module_financial") >= 1) { ?>
<li class="nav-header mt-3">FINANCE</li>
<li class="nav-item">
<a href="payments.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "payments.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-credit-card"></i>
<p>Payments</p>
</a>
</li>
<li class="nav-item">
<a href="vendors.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "vendors.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-building"></i>
<p>Vendors</p>
</a>
</li>
<li class="nav-item">
<a href="expenses.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "expenses.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-shopping-cart"></i>
<p>Expenses</p>
</a>
</li>
<li class="nav-item">
<a href="recurring_expenses.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "recurring_expenses.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-redo-alt"></i>
<p>
Recurring Expenses
<?php if ($num_recurring_expenses) { ?>
<span class="right badge text-light" data-toggle="tooltip" title="Recurring Expenses"><?php echo $num_recurring_expenses; ?></span>
<?php } ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="accounts.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "accounts.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-piggy-bank"></i>
<p>Accounts</p>
</a>
</li>
<li class="nav-item">
<a href="transfers.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "transfers.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-exchange-alt"></i>
<p>Transfers</p>
</a>
</li>
<li class="nav-item">
<a href="trips.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "trips.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-route"></i>
<p>Trips</p>
</a>
</li>
<?php } ?>
<?php if (lookupUserPermission("module_client") >= 1) { ?>
<li class="nav-item mt-3">
<a href="contacts.php" class="nav-link">
<i class="fas fa-users nav-icon"></i>
<p>Client Overview</p>
<i class="fas fa-angle-right nav-icon float-right"></i>
</a>
</li>
<?php } ?>
<?php if (lookupUserPermission("module_reporting") >= 1) { ?>
<li class="nav-item mt-3">
<a href="reports/" class="nav-link">
<i class="fas fa-chart-line nav-icon"></i>
<p>Reports</p>
<i class="fas fa-angle-right nav-icon float-right"></i>
</a>
</li>
<?php } ?>
<?php
$sql_custom_links = mysqli_query($mysqli, "SELECT * FROM custom_links WHERE custom_link_location = 1 AND custom_link_archived_at IS NULL
ORDER BY custom_link_order ASC, custom_link_name ASC"
);
while ($row = mysqli_fetch_array($sql_custom_links)) {
$custom_link_name = nullable_htmlentities($row['custom_link_name']);
$custom_link_uri = sanitize_url($row['custom_link_uri']);
$custom_link_icon = nullable_htmlentities($row['custom_link_icon']);
$custom_link_new_tab = intval($row['custom_link_new_tab']);
if ($custom_link_new_tab == 1) {
$target = "target='_blank' rel='noopener noreferrer'";
} else {
$target = "";
}
?>
<li class="nav-item">
<a href="<?php echo $custom_link_uri; ?>" <?php echo $target; ?> class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == basename($custom_link_uri)) { echo "active"; } ?>">
<i class="fas fa-<?php echo $custom_link_icon; ?> nav-icon"></i>
<p><?php echo $custom_link_name; ?></p>
<i class="fas fa-angle-right nav-icon float-right"></i>
</a>
</li>
<?php } ?>
</ul>
</nav>
<!-- /.sidebar-menu -->
<div class="mb-3"></div>
</div>
<!-- /.sidebar -->
</aside>

View File

@@ -0,0 +1,57 @@
<!-- Main Sidebar Container -->
<aside class="main-sidebar sidebar-dark-<?php echo nullable_htmlentities($config_theme); ?> d-print-none">
<a class="brand-link pb-1 mt-1" href="clients.php">
<p class="h5">
<i class="nav-icon fas fa-arrow-left ml-3 mr-2"></i>
<span class="brand-text">
Back | <strong>Account</strong>
</span>
</p>
</a>
<!-- Sidebar -->
<div class="sidebar">
<!-- Sidebar Menu -->
<nav>
<ul class="nav nav-pills nav-sidebar flex-column mt-2" data-widget="treeview" role="menu" data-accordion="false">
<li class="nav-item">
<a href="user_details.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "user_details.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-user"></i>
<p>Details</p>
</a>
</li>
<li class="nav-item mt-2">
<a href="user_security.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "user_security.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-shield-alt"></i>
<p>Security</p>
</a>
</li>
<li class="nav-item mt-2">
<a href="user_preferences.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "user_preferences.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-cogs"></i>
<p>Preferences</p>
</a>
</li>
<li class="nav-item mt-2">
<a href="user_activity.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "user_activity.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-clock"></i>
<p>Activity</p>
</a>
</li>
</ul>
</nav>
<!-- /.sidebar-menu -->
<div class="mb-3"></div>
</div>
<!-- /.sidebar -->
</aside>

22
agent/index.php Normal file
View File

@@ -0,0 +1,22 @@
<?php
require_once "includes/inc_all.php";
?>
<!-- Breadcrumbs-->
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="index.php">Dashboard</a>
</li>
<li class="breadcrumb-item active">Blank Page</li>
</ol>
<!-- Page Content -->
<h1>Blank Page</h1>
<hr>
<meta http-equiv="refresh" content="0;url=<?php echo $config_start_page; ?>">
<?php
require_once "../includes/footer.php";

820
agent/invoice.php Normal file
View File

@@ -0,0 +1,820 @@
<?php
// If client_id is in URI then show client Side Bar and client header
if (isset($_GET['client_id'])) {
require_once "includes/inc_all_client.php";
} else {
require_once "includes/inc_all.php";
}
// Perms
enforceUserPermission('module_sales');
if (isset($_GET['invoice_id'])) {
$invoice_id = intval($_GET['invoice_id']);
$sql = mysqli_query(
$mysqli,
"SELECT * FROM invoices
LEFT JOIN clients ON invoice_client_id = client_id
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
WHERE invoice_id = $invoice_id
$access_permission_query
LIMIT 1"
);
if (mysqli_num_rows($sql) == 0) {
if (isset($_GET['client_id'])) {
$backlink_append = "?client_id=$client_id";
} else {
$backlink_append = '';
}
echo "<h1 class='text-secondary pt-5' style='text-align: center'>There is no Invoice here<br><small><a href='invoices.php$backlink_append'><i class='fas fa-arrow-left mr-2'></i>Back to Invoices</a></small></h1>";
require_once "../includes/footer.php";
exit();
}
$row = mysqli_fetch_array($sql);
$invoice_id = intval($row['invoice_id']);
$invoice_prefix = nullable_htmlentities($row['invoice_prefix']);
$invoice_number = intval($row['invoice_number']);
$invoice_scope = nullable_htmlentities($row['invoice_scope']);
$invoice_status = nullable_htmlentities($row['invoice_status']);
$invoice_date = nullable_htmlentities($row['invoice_date']);
$invoice_due = nullable_htmlentities($row['invoice_due']);
$invoice_amount = floatval($row['invoice_amount']);
$invoice_discount = floatval($row['invoice_discount_amount']);
$invoice_credit = floatval($row['invoice_credit_amount']);
$invoice_currency_code = nullable_htmlentities($row['invoice_currency_code']);
$invoice_note = nullable_htmlentities($row['invoice_note']);
$invoice_url_key = nullable_htmlentities($row['invoice_url_key']);
$invoice_created_at = nullable_htmlentities($row['invoice_created_at']);
$category_id = intval($row['invoice_category_id']);
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
$location_address = nullable_htmlentities($row['location_address']);
$location_city = nullable_htmlentities($row['location_city']);
$location_state = nullable_htmlentities($row['location_state']);
$location_zip = nullable_htmlentities($row['location_zip']);
$location_country = nullable_htmlentities($row['location_country']);
$contact_email = nullable_htmlentities($row['contact_email']);
$contact_phone_country_code = nullable_htmlentities($row['contact_phone_country_code']);
$contact_phone = nullable_htmlentities(formatPhoneNumber($row['contact_phone'], $contact_phone_country_code));
$contact_extension = nullable_htmlentities($row['contact_extension']);
$contact_mobile_country_code = nullable_htmlentities($row['contact_mobile_country_code']);
$contact_mobile = nullable_htmlentities(formatPhoneNumber($row['contact_mobile'], $contact_mobile_country_code));
$client_website = nullable_htmlentities($row['client_website']);
$client_currency_code = nullable_htmlentities($row['client_currency_code']);
$client_net_terms = intval($row['client_net_terms']);
if ($client_net_terms == 0) {
$client_net_terms = $config_default_net_terms;
}
// Override Tab Title // No Sanitizing needed as this var will opnly be used in the tab title
$tab_title = $row['client_name'];
$page_title = "{$row['invoice_prefix']}{$row['invoice_number']}";
$sql = mysqli_query($mysqli, "SELECT * FROM companies WHERE company_id = 1");
$row = mysqli_fetch_array($sql);
$company_id = intval($row['company_id']);
$company_name = nullable_htmlentities($row['company_name']);
$company_country = nullable_htmlentities($row['company_country']);
$company_address = nullable_htmlentities($row['company_address']);
$company_city = nullable_htmlentities($row['company_city']);
$company_state = nullable_htmlentities($row['company_state']);
$company_zip = nullable_htmlentities($row['company_zip']);
$company_phone_country_code = nullable_htmlentities($row['company_phone_country_code']);
$company_phone = nullable_htmlentities(formatPhoneNumber($row['company_phone'], $company_phone_country_code));
$company_email = nullable_htmlentities($row['company_email']);
$company_website = nullable_htmlentities($row['company_website']);
$company_tax_id = nullable_htmlentities($row['company_tax_id']);
if ($config_invoice_show_tax_id && !empty($company_tax_id)) {
$company_tax_id_display = "Tax ID: $company_tax_id";
} else {
$company_tax_id_display = "";
}
$company_logo = nullable_htmlentities($row['company_logo']);
$sql_history = mysqli_query($mysqli, "SELECT * FROM history WHERE history_invoice_id = $invoice_id ORDER BY history_id DESC");
$sql_payments = mysqli_query($mysqli, "SELECT * FROM payments, accounts WHERE payment_account_id = account_id AND payment_invoice_id = $invoice_id ORDER BY payments.payment_id DESC");
$sql_tickets = mysqli_query($mysqli, "
SELECT
tickets.*,
SEC_TO_TIME(SUM(TIME_TO_SEC(STR_TO_DATE(ticket_reply_time_worked, '%H:%i:%s')))) AS 'total_time_worked'
FROM
tickets
LEFT JOIN
ticket_replies ON tickets.ticket_id = ticket_replies.ticket_reply_ticket_id
WHERE
ticket_invoice_id = $invoice_id
GROUP BY
tickets.ticket_id
ORDER BY
ticket_id DESC
");
//Get billable, and unbilled tickets to add to invoice
$sql_tickets_billable = mysqli_query(
$mysqli, "
SELECT
*
FROM
tickets
WHERE
ticket_client_id = $client_id
AND
ticket_billable = 1
AND
ticket_invoice_id = 0
AND
ticket_status = 5;
");
//Add up all the payments for the invoice and get the total amount paid to the invoice
$sql_amount_paid = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS amount_paid FROM payments WHERE payment_invoice_id = $invoice_id");
$row = mysqli_fetch_array($sql_amount_paid);
$amount_paid = floatval($row['amount_paid']);
$balance = $invoice_amount - $amount_paid;
// Get Credit Balance
$sql_credit_balance = mysqli_query($mysqli, "SELECT SUM(credit_amount) AS credit_balance FROM credits WHERE credit_client_id = $client_id");
$row = mysqli_fetch_array($sql_credit_balance);
$credit_balance = floatval($row['credit_balance']);
//check to see if overdue
if ($invoice_status !== "Paid" && $invoice_status !== "Draft" && $invoice_status !== "Cancelled" && $invoice_status !== "Non-Billable") {
$unixtime_invoice_due = strtotime($invoice_due) + 86400;
if ($unixtime_invoice_due < time()) {
$invoice_overdue = "Overdue";
}
}
//Set Badge color based off of invoice status
$invoice_badge_color = getInvoiceBadgeColor($invoice_status);
//Product autocomplete
$products_sql = mysqli_query($mysqli, "
SELECT
product_name AS label,
product_type AS type,
product_description AS description,
product_price AS price,
product_tax_id AS tax,
tax_percent,
product_id AS prod_id,
COALESCE(SUM(product_stock.stock_qty), 0) AS available_stock
FROM products
LEFT JOIN product_stock ON product_id = stock_product_id
LEFT JOIN taxes ON product_tax_id = tax_id
WHERE product_archived_at IS NULL
GROUP BY product_id
");
if (mysqli_num_rows($products_sql) > 0) {
while ($row = mysqli_fetch_array($products_sql)) {
$products[] = $row;
}
$json_products = json_encode($products);
}
// Saved Payment Methods
$sql_saved_payment_methods = mysqli_query($mysqli, "
SELECT * FROM client_saved_payment_methods
LEFT JOIN payment_providers
ON client_saved_payment_methods.saved_payment_provider_id = payment_providers.payment_provider_id
WHERE saved_payment_client_id = $client_id
AND payment_provider_active = 1;
");
?>
<ol class="breadcrumb d-print-none">
<?php if (isset($_GET['client_id'])) { ?>
<li class="breadcrumb-item">
<a href="client_overview.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a>
</li>
<li class="breadcrumb-item">
<a href="invoices.php?client_id=<?php echo $client_id; ?>">Invoices</a>
</li>
<?php } else { ?>
<li class="breadcrumb-item">
<a href="invoices.php">Invoices</a>
</li>
<li class="breadcrumb-item">
<a href="invoices.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a>
</li>
<?php } ?>
<li class="breadcrumb-item active"><?php echo "$invoice_prefix$invoice_number"; ?></li>
<?php if (isset($invoice_overdue)) { ?>
<span class="p-2 ml-2 badge badge-danger"><?php echo $invoice_overdue; ?></span>
<?php } ?>
</ol>
<div class="card">
<div class="card-header d-print-none">
<div class="row">
<div class="col-8">
<?php if (lookupUserPermission("module_sales") >= 2) { ?>
<?php if ($invoice_status == 'Draft') { ?>
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">
<i class="fas fa-fw fa-paper-plane mr-2"></i>Send
</button>
<div class="dropdown-menu">
<?php if (!empty($config_smtp_host) && !empty($contact_email)) { ?>
<a class="dropdown-item" href="post.php?email_invoice=<?php echo $invoice_id; ?>">
<i class="fas fa-fw fa-paper-plane mr-2"></i>Send Email
</a>
<div class="dropdown-divider"></div>
<?php } ?>
<a class="dropdown-item" href="post.php?mark_invoice_sent=<?php echo $invoice_id; ?>">
<i class="fas fa-fw fa-check mr-2"></i>Mark Sent
</a>
</div>
<?php } ?>
<?php if ($invoice_status !== 'Paid' && $invoice_status !== 'Cancelled' && $invoice_status !== 'Draft' && $invoice_status !== 'Non-Billable' && $invoice_amount != 0) { ?>
<div class="btn-group">
<button type="button" class="btn btn-success ajax-modal" data-modal-url="modals/invoice/invoice_pay.php?id=<?= $invoice_id ?>"><i class="fa fa-fw fa-credit-card mr-2"></i>Add Payment</button>
<?php if (mysqli_num_rows($sql_saved_payment_methods) > 0 && ($invoice_status === 'Sent' || $invoice_status === 'Viewed')) { ?>
<button type="button" class="btn btn-success dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/invoice/invoice_saved_method_pay.php?id=<?= $invoice_id ?>"><i class="fas fa-fw fa-wallet mr-2"></i>Pay with Saved Card</a>
</div>
<?php } ?>
</div>
<?php } ?>
<?php if (($invoice_status == 'Sent' || $invoice_status == 'Viewed') && $invoice_amount == 0 && $invoice_status !== 'Non-Billable') { ?>
<a class="btn btn-dark" href="post.php?mark_invoice_non-billable=<?php echo $invoice_id; ?>">
Mark Non-Billable
</a>
<?php } ?>
<?php } ?>
</div>
<div class="col-4">
<div class="dropdown dropleft text-center float-right">
<button class="btn btn-secondary" type="button" data-toggle="dropdown">
<i class="fas fa-ellipsis-v"></i>
</button>
<div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/invoice/invoice_edit.php?id=<?= $invoice_id ?>">
<i class="fa fa-fw fa-edit text-secondary mr-2"></i>Edit
</a>
<a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/invoice/invoice_copy.php?id=<?= $invoice_id ?>">
<i class="fa fa-fw fa-copy text-secondary mr-2"></i>Copy
</a>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#addInvoiceRecurringModal<?php echo $invoice_id; ?>">
<i class="fa fa-fw fa-sync-alt text-secondary mr-2"></i>Recurring
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#" onclick="window.print();">
<i class="fa fa-fw fa-print text-secondary mr-2"></i>Print
</a>
<a class="dropdown-item" href="post.php?export_invoice_pdf=<?php echo $invoice_id; ?>" target="_blank">
<i class="fa fa-fw fa-download text-secondary mr-2"></i>Download PDF
</a>
<?php if (!empty($config_smtp_host) && !empty($contact_email)) { ?>
<a class="dropdown-item" href="post.php?email_invoice=<?php echo $invoice_id; ?>">
<i class="fa fa-fw fa-paper-plane text-secondary mr-2"></i>Send Email
</a>
<?php } ?>
<a class="dropdown-item clipboardjs" href="#" data-clipboard-text="https://<?= $config_base_url ?>/guest/guest_view_invoice.php?invoice_id=<?php echo "$invoice_id&url_key=$invoice_url_key"; ?>">
<i class="fa fa-fw fa-copy text-secondary mr-2"></i>Copy Guest URL
</a>
<?php if ($invoice_status !== 'Cancelled' && $invoice_status !== 'Paid' && $invoice_status !== 'Non-Billable') { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?cancel_invoice=<?php echo $invoice_id; ?>">
<i class="fa fa-fw fa-times mr-2"></i>Cancel
</a>
<?php } ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_invoice=<?php echo $invoice_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</a>
</div>
</div>
</div>
</div>
</div>
<div class="card-body">
<div class="row mb-3">
<?php if (file_exists("../uploads/settings/$company_logo")) { ?>
<div class="col-sm-2">
<img class="img-fluid" src="<?php echo "../uploads/settings/$company_logo"; ?>" alt="Company logo">
</div>
<?php } ?>
<div class="col-sm-6 <?php if (!file_exists("../uploads/settings/$company_logo")) { echo "col-sm-8"; } ?>">
<ul class="list-unstyled">
<li><h4><strong><?php echo $company_name; ?></strong></h4></li>
<li><?php echo $company_address; ?></li>
<li><?php echo "$company_city $company_state $company_zip, $company_country"; ?></li>
<li><?php echo "$company_email | $company_phone"; ?></li>
<li><?php echo $company_website; ?></li>
<?php if ($company_tax_id_display) { ?>
<li><?php echo $company_tax_id_display; ?></li>
<?php } ?>
</ul>
</div>
<div class="col-sm-4">
<h3 class="text-right"><strong>INVOICE</strong></h3>
<h5 class="badge badge-<?php echo $invoice_badge_color; ?> p-2 float-right">
<?php echo "$invoice_status"; ?>
</h5>
<table class="table table-sm table-borderless">
<tr>
<th>Invoice #:</th>
<td class="text-right"><?php echo "$invoice_prefix$invoice_number"; ?></td>
</tr>
<tr>
<th>Date:</th>
<td class="text-right"><?php echo $invoice_date; ?></td>
</tr>
<tr>
<th>Due:</th>
<td class="text-right"><?php echo $invoice_due; ?></td>
</tr>
</table>
</div>
</div>
<div class="row mb-3 bg-light p-3">
<div class="col">
<h6><strong>Bill To:</strong></h6>
<ul class="list-unstyled mb-0">
<li><?php echo $client_name; ?></li>
<li><?php echo $location_address; ?></li>
<li><?php echo "$location_city $location_state $location_zip, $location_country"; ?></li>
<li><?php echo "$contact_email | $contact_phone $contact_extension"; ?></li>
</ul>
</div>
</div>
<?php $sql_invoice_items = mysqli_query($mysqli, "SELECT * FROM invoice_items WHERE item_invoice_id = $invoice_id ORDER BY item_order ASC"); ?>
<div class="row mb-3">
<div class="col-md-12">
<div class="card">
<div class="table-responsive">
<table class="table table-hover mb-0" id="items">
<thead class="bg-light">
<tr>
<th class="d-print-none"></th>
<th>Item</th>
<th>Description</th>
<th class="text-center">Qty</th>
<th class="text-right">Unit Price</th>
<th class="text-right">Tax</th>
<th class="text-right">Amount</th>
</tr>
</thead>
<tbody>
<?php
$total_tax = 0.00;
$sub_total = 0.00;
while ($row = mysqli_fetch_array($sql_invoice_items)) {
$item_id = intval($row['item_id']);
$item_name = nullable_htmlentities($row['item_name']);
$item_description = nullable_htmlentities($row['item_description']);
$item_quantity = floatval($row['item_quantity']);
$item_price = floatval($row['item_price']);
$item_tax = floatval($row['item_tax']);
$item_total = floatval($row['item_total']);
$item_created_at = nullable_htmlentities($row['item_created_at']);
$tax_id = intval($row['item_tax_id']);
$item_product_id = intval($row['item_product_id']);
$total_tax = $item_tax + $total_tax;
$sub_total = $item_price * $item_quantity + $sub_total;
?>
<tr data-item-id="<?php echo $item_id; ?>">
<td class="d-print-none">
<?php if ($invoice_status !== "Paid" && $invoice_status !== "Cancelled") { ?>
<div class="btn-group">
<button type="button" class="btn btn-sm btn-link drag-handle">
<i class="fas fa-bars text-muted"></i>
</button>
<div class="dropdown">
<button class="btn btn-sm btn-light" type="button" data-toggle="dropdown">
<i class="fas fa-ellipsis-v"></i>
</button>
<div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/invoice/item_edit.php?id=<?= $item_id ?>">
<i class="fa fa-fw fa-edit mr-2"></i>Edit
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?delete_invoice_item=<?php echo $item_id; ?>"><i class="fa fa-fw fa-trash mr-2"></i>Delete</a>
</div>
</div>
</div>
<?php } ?>
</td>
<td><?php echo $item_name; ?></td>
<td><?php echo nl2br($item_description); ?></td>
<td class="text-center"><?php echo number_format($item_quantity, 2); ?></td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $item_price, $invoice_currency_code); ?></td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $item_tax, $invoice_currency_code); ?></td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $item_total, $invoice_currency_code); ?></td>
</tr>
<?php
}
?>
<tr class="d-print-none" <?php if ($invoice_status == "Paid" || $invoice_status == "Cancelled" || lookupUserPermission("module_sales") <= 1) { echo "hidden"; } ?>>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="invoice_id" value="<?= $invoice_id ?>">
<input type="hidden" id="product_id" name="product_id" value="<?= $item_product_id ?? 0 ?>">
<input type="hidden" name="item_order" value="<?php echo mysqli_num_rows($sql_invoice_items) + 1; ?>">
<td></td>
<td>
<input type="text" class="form-control" id="name" name="name" placeholder="Item" required>
</td>
<td>
<textarea class="form-control" rows="2" id="desc" name="description" placeholder="Enter a Description"></textarea>
</td>
<td>
<input type="text" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" class="form-control" style="text-align: center;" id="qty" name="qty" placeholder="Qty">
</td>
<td>
<input type="text" class="form-control" inputmode="numeric" pattern="-?[0-9]*\.?[0-9]{0,2}" style="text-align: right;" id="price" name="price" placeholder="Price (<?php echo $invoice_currency_code; ?>)">
</td>
<td>
<select class="form-control select2" name="tax_id" id="tax" required>
<option value="0">No Tax</option>
<?php
$taxes_sql = mysqli_query($mysqli, "SELECT * FROM taxes WHERE tax_archived_at IS NULL ORDER BY tax_name ASC");
while ($row = mysqli_fetch_array($taxes_sql)) {
$tax_id = intval($row['tax_id']);
$tax_name = nullable_htmlentities($row['tax_name']);
$tax_percent = floatval($row['tax_percent']);
?>
<option value="<?php echo $tax_id; ?>"><?php echo "$tax_name $tax_percent%"; ?></option>
<?php
}
?>
</select>
</td>
<td class="text-center">
<button class="btn btn-light text-success" type="submit" name="add_invoice_item">
<i class="fa fa-check"></i>
</button>
</td>
</form>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="row mb-3">
<div class="col-sm-7">
<div class="card">
<div class="card-header text-bold">
Notes:
<div class="card-tools d-print-none">
<a href="#" class="btn btn-light btn-tool" data-toggle="modal" data-target="#invoiceNoteModal">
<i class="fas fa-edit"></i>
</a>
</div>
</div>
<div class="card-body">
<?php echo nl2br($invoice_note); ?>
</div>
</div>
</div>
<div class="col-sm-3 offset-sm-2">
<table class="table table-hover mb-0">
<tbody>
<tr>
<td>Subtotal:</td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $sub_total, $invoice_currency_code); ?></td>
</tr>
<?php
if ($invoice_discount > 0) {
?>
<tr>
<td>Discount:</td>
<td class="text-right">-<?php echo numfmt_format_currency($currency_format, $invoice_discount, $invoice_currency_code); ?></td>
</tr>
<?php
}
?>
<?php
if ($invoice_credit > 0) {
?>
<tr>
<td>Credit:</td>
<td class="text-right">-<?php echo numfmt_format_currency($currency_format, $invoice_credit, $invoice_currency_code); ?></td>
</tr>
<?php
}
?>
<?php if ($total_tax > 0) { ?>
<tr>
<td>Tax:</td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $total_tax, $invoice_currency_code); ?></td>
</tr>
<?php } ?>
<tr>
<td>Total:</td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $invoice_amount, $invoice_currency_code); ?></td>
</tr>
<?php
if ($amount_paid > 0) { ?>
<tr>
<td><div class="text-success">Paid:</div></td>
<td class="text-right text-success"><?php echo numfmt_format_currency($currency_format, $amount_paid, $invoice_currency_code); ?></td>
</tr>
<?php } ?>
<tr class="h5 text-bold">
<td>Balance:</td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $balance, $invoice_currency_code); ?></td>
</tr>
</tbody>
</table>
</div>
</div>
<hr class="d-none d-print-block mt-5">
<div class="d-none d-print-block text-center text-secondary"><?php echo nl2br(nullable_htmlentities($config_invoice_footer)); ?></div>
</div>
</div>
<div class="row d-print-none mb-3">
<div class="col-sm">
<div class="card">
<div class="card-header text-bold">
<i class="fa fa-history mr-2"></i>History
<div class="card-tools">
<button type="button" class="btn btn-tool" data-card-widget="collapse">
<i class="fas fa-minus"></i>
</button>
<button type="button" class="btn btn-tool" data-card-widget="remove">
<i class="fas fa-times"></i>
</button>
</div>
</div>
<div class="card-body">
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Status</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_history)) {
$history_created_at = $row['history_created_at'];
$history_status = nullable_htmlentities($row['history_status']);
$history_description = nullable_htmlentities($row['history_description']);
?>
<tr>
<td><?php echo $history_created_at; ?></td>
<td><?php echo $history_status; ?></td>
<td><?php echo $history_description; ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-sm d-print-none <?php if (mysqli_num_rows($sql_payments) == 0) { echo "d-none"; } ?>">
<div class="card">
<div class="card-header text-bold">
<i class="fa fa-credit-card mr-2"></i>Payments
<div class="card-tools">
<button type="button" class="btn btn-tool" data-card-widget="collapse">
<i class="fas fa-minus"></i>
</button>
<button type="button" class="btn btn-tool" data-card-widget="remove">
<i class="fas fa-times"></i>
</button>
</div>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Date</th>
<th class="text-right">Amount</th>
<th>Reference</th>
<th>Account</th>
<th></th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_payments)) {
$payment_id = intval($row['payment_id']);
$payment_date = nullable_htmlentities($row['payment_date']);
$payment_amount = floatval($row['payment_amount']);
$payment_currency_code = nullable_htmlentities($row['payment_currency_code']);
$payment_reference = nullable_htmlentities($row['payment_reference']);
$account_name = nullable_htmlentities($row['account_name']);
?>
<tr>
<td><?php echo $payment_date; ?></td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $payment_amount, $payment_currency_code); ?></td>
<td><?php echo $payment_reference; ?></td>
<td><?php echo $account_name; ?></td>
<td class="text-center"><a class="btn btn-light text-danger confirm-link" href="post.php?delete_payment=<?php echo $payment_id; ?>"><i class="fa fa-times"></i></a></td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="col-sm d-print-none <?php if (mysqli_num_rows($sql_tickets) == 0) { echo "d-none"; } ?>">
<div class="card">
<div class="card-header text-bold">
<i class="fa fa-life-ring mr-2"></i>Tickets
<div class="card-tools">
<?php if (mysqli_num_rows($sql_tickets_billable) > 0) { ?>
<a class="btn btn-tool" href="#" data-toggle="modal" data-target="#addTicketModal">
<i class="fas fa-plus"></i>
</a>
<?php } ?>
<a class="btn btn-tool" href="tickets.php?client_id=<?php echo $client_id; ?>">
<i class="fas fa-external-link-alt"></i>
</a>
<button type="button" class="btn btn-tool" data-card-widget="collapse">
<i class="fas fa-minus"></i>
</button>
<button type="button" class="btn btn-tool" data-card-widget="remove">
<i class="fas fa-times"></i>
</button>
</div>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Subject</th>
<th class="text-right">Time Worked</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_tickets)) {
$ticket_id = intval($row['ticket_id']);
$ticket_created_at = nullable_htmlentities($row['ticket_created_at']);
$ticket_subject = nullable_htmlentities($row['ticket_subject']);
$ticket_total_time_worked = floatval($row['total_time_worked']);
?>
<tr>
<td><?php echo $ticket_created_at; ?></td>
<td><?php echo $ticket_subject; ?></td>
<td class="text-right"><?php echo $ticket_total_time_worked; ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<?php
include_once "modals/invoice/invoice_add_ticket.php";
include_once "modals/invoice/invoice_recurring_add.php";
include_once "modals/invoice/invoice_note.php";
}
require_once "../includes/footer.php";
?>
<!-- JSON Autocomplete / type ahead -->
<link rel="stylesheet" href="../plugins/jquery-ui/jquery-ui.min.css">
<script src="../plugins/jquery-ui/jquery-ui.min.js"></script>
<script>
$(function() {
var availableProducts = <?php echo $json_products ?? '[]'?>;
$("#name").autocomplete({
source: availableProducts,
minLength: 1,
delay: 0,
select: function (event, ui) {
$("#name").val(ui.item.label);
$("#desc").val(ui.item.description);
$("#qty").val(1);
$("#price").val(ui.item.price);
$("#tax").val(ui.item.tax);
$("#product_id").val(ui.item.prod_id);
return false;
}
});
// Keep it simple: default jQuery UI look, just richer content
$("#name").autocomplete("instance")._renderItem = function(ul, item) {
var typeText = item.type ? item.type.charAt(0).toUpperCase() + item.type.slice(1).toLowerCase() : "";
var showStock = (typeText.toLowerCase() !== "service");
var taxText = (item.tax_percent != null) ? (parseFloat(item.tax_percent) + "%") : "No tax";
var priceText = (item.price != null && item.price !== "") ? String(item.price) : "";
var infoLeft =
"<div class='d-flex justify-content-between align-items-start'>" +
"<div class='flex-fill pr-2'>" +
"<div class='font-weight-bold'>" + (item.label || "") +
(typeText ? " <small class='text-muted'>(" + typeText + ")</small>" : "") +
"</div>" +
"<div class='small text-muted'>" + (item.description || "") + "</div>" +
"<div class='mt-1'>" +
"<span class='badge badge-secondary mr-1'>Tax: " + taxText + "</span>" +
(showStock ? "<span class='badge " + ((item.available_stock ?? 0) > 0 ? "badge-success" : "badge-danger") + "'>Stock: " + (item.available_stock ?? 0) + "</span>" : "") +
"</div>" +
"</div>" +
"<div class='text-right'>" +
"<div class='font-weight-bold'>" + priceText + "</div>" +
"</div>" +
"</div>";
// Use the jQuery UI wrapper so default hover/focus styles apply
return $("<li>")
.append($("<div class='ui-menu-item-wrapper'>").append(infoLeft))
.appendTo(ul);
};
});
</script>
<script src="../plugins/SortableJS/Sortable.min.js"></script>
<script>
new Sortable(document.querySelector('table#items tbody'), {
handle: '.drag-handle',
animation: 150,
onEnd: function (evt) {
const rows = document.querySelectorAll('table#items tbody tr');
const positions = Array.from(rows).map((row, index) => ({
id: row.dataset.itemId,
order: index
}));
$.post('ajax.php', {
update_invoice_items_order: true,
invoice_id: <?php echo $invoice_id; ?>,
positions: positions
});
}
});
</script>

459
agent/invoices.php Normal file
View File

@@ -0,0 +1,459 @@
<?php
// Default Column Sortby/Order Filter
$sort = "invoice_number";
$order = "DESC";
// If client_id is in URI then show client Side Bar and client header
if (isset($_GET['client_id'])) {
require_once "includes/inc_all_client.php";
$client_query = "AND invoice_client_id = $client_id";
$client_url = "client_id=$client_id&";
} else {
require_once "includes/inc_all.php";
$client_query = '';
$client_url = '';
}
// Perms
enforceUserPermission('module_sales');
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('invoice_id') AS num FROM invoices WHERE invoice_status = 'Sent' $client_query"));
$sent_count = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('invoice_id') AS num FROM invoices WHERE invoice_status = 'Viewed' $client_query"));
$viewed_count = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('invoice_id') AS num FROM invoices WHERE invoice_status = 'Partial' $client_query"));
$partial_count = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('invoice_id') AS num FROM invoices WHERE invoice_status = 'Draft' $client_query"));
$draft_count = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('invoice_id') AS num FROM invoices WHERE invoice_status = 'Cancelled' $client_query"));
$cancelled_count = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('invoice_id') AS num FROM invoices WHERE invoice_status NOT LIKE 'Draft' AND invoice_status NOT LIKE 'Paid' AND invoice_status NOT LIKE 'Cancelled' AND invoice_status NOT LIKE 'Non-Billable' AND invoice_due < CURDATE() $client_query"));
$overdue_count = $row['num'];
$sql_total_draft_amount = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS total_draft_amount FROM invoices WHERE invoice_status = 'Draft' $client_query");
$row = mysqli_fetch_array($sql_total_draft_amount);
$total_draft_amount = floatval($row['total_draft_amount']);
$sql_total_sent_amount = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS total_sent_amount FROM invoices WHERE invoice_status = 'Sent' $client_query");
$row = mysqli_fetch_array($sql_total_sent_amount);
$total_sent_amount = floatval($row['total_sent_amount']);
$sql_total_viewed_amount = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS total_viewed_amount FROM invoices WHERE invoice_status = 'Viewed' $client_query");
$row = mysqli_fetch_array($sql_total_viewed_amount);
$total_viewed_amount = floatval($row['total_viewed_amount']);
$sql_total_cancelled_amount = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS total_cancelled_amount FROM invoices WHERE invoice_status = 'Cancelled' $client_query");
$row = mysqli_fetch_array($sql_total_cancelled_amount);
$total_cancelled_amount = floatval($row['total_cancelled_amount']);
$sql_total_partial_amount = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS total_partial_amount FROM payments, invoices WHERE payment_invoice_id = invoice_id AND invoice_status = 'Partial' $client_query");
$row = mysqli_fetch_array($sql_total_partial_amount);
$total_partial_amount = floatval($row['total_partial_amount']);
$total_partial_count = mysqli_num_rows($sql_total_partial_amount);
$sql_total_overdue_partial_amount = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS total_overdue_partial_amount FROM payments, invoices WHERE payment_invoice_id = invoice_id AND invoice_status = 'Partial' AND invoice_due < CURDATE() $client_query");
$row = mysqli_fetch_array($sql_total_overdue_partial_amount);
$total_overdue_partial_amount = floatval($row['total_overdue_partial_amount']);
$sql_total_overdue_amount = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS total_overdue_amount FROM invoices WHERE invoice_status != 'Draft' AND invoice_status != 'Paid' AND invoice_status != 'Cancelled' AND invoice_status != 'Non-Billable' AND invoice_due < CURDATE() $client_query");
$row = mysqli_fetch_array($sql_total_overdue_amount);
$total_overdue_amount = floatval($row['total_overdue_amount']);
$real_overdue_amount = $total_overdue_amount - $total_overdue_partial_amount;
$total_unpaid_amount = $total_sent_amount + $total_viewed_amount + $total_partial_amount;
$unpaid_count = $sent_count + $viewed_count + $partial_count;
$overdue_query = '';
//Invoice status from GET
if (isset($_GET['status']) && ($_GET['status']) == 'Draft') {
$status_query = "invoice_status = 'Draft'";
} elseif (isset($_GET['status']) && ($_GET['status']) == 'Unpaid') {
$status_query = "invoice_status = 'Sent' OR invoice_status = 'Viewed' OR invoice_status = 'Partial'";
} elseif (isset($_GET['status']) && ($_GET['status']) == 'Overdue') {
$status_query = "invoice_status = 'Sent' OR invoice_status = 'Viewed' OR invoice_status = 'Partial'";
$overdue_query = "AND (invoice_due < CURDATE())";
} else {
$status_query = "invoice_status LIKE '%'";
}
// Category Filter
if (isset($_GET['category']) & !empty($_GET['category'])) {
$category_query = 'AND (category_id = ' . intval($_GET['category']) . ')';
$category_filter = intval($_GET['category']);
} else {
// Default - any
$category_query = '';
$category_filter = '';
}
$sql = mysqli_query(
$mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM invoices
LEFT JOIN clients ON invoice_client_id = client_id
LEFT JOIN categories ON invoice_category_id = category_id
WHERE ($status_query)
$overdue_query
$category_query
AND DATE(invoice_date) BETWEEN '$dtf' AND '$dtt'
AND (CONCAT(invoice_prefix,invoice_number) LIKE '%$q%' OR invoice_scope LIKE '%$q%' OR client_name LIKE '%$q%' OR invoice_status LIKE '%$q%' OR invoice_amount LIKE '%$q%' OR category_name LIKE '%$q%')
$access_permission_query
$client_query
ORDER BY $sort $order LIMIT $record_from, $record_to"
);
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?>
<div class="row">
<div class="col-lg-4">
<!-- small box -->
<a href="?<?php echo $url_query_strings_sort; ?>&status=Draft" class="small-box bg-secondary">
<div class="inner">
<h3><?php echo numfmt_format_currency($currency_format, $total_draft_amount, $session_company_currency); ?></h3>
<p><?php echo $draft_count; ?> Draft</p>
</div>
<div class="icon">
<i class="fa fa-pencil-ruler"></i>
</div>
</a>
</div>
<!-- ./col -->
<div class="col-lg-4">
<!-- small box -->
<a href="?<?php echo $url_query_strings_sort; ?>&status=Unpaid" class="small-box bg-info">
<div class="inner text-white">
<h3><?php echo numfmt_format_currency($currency_format, $total_unpaid_amount, $session_company_currency); ?></h3>
<p><?php echo $unpaid_count; ?> Unpaid</p>
</div>
<div class="icon">
<i class="fa fa-hand-holding-usd"></i>
</div>
</a>
</div>
<!-- ./col -->
<div class="col-lg-4">
<!-- small box -->
<a href="?<?php echo $url_query_strings_sort; ?>&status=Overdue" class="small-box bg-danger">
<div class="inner">
<h3><?php echo numfmt_format_currency($currency_format, $real_overdue_amount, $session_company_currency); ?></h3>
<p><?php echo $overdue_count; ?> Overdue</p>
</div>
<div class="icon">
<i class="fa fa-exclamation-triangle"></i>
</div>
</a>
</div>
<!-- ./col -->
</div>
<div class="card card-dark">
<div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fa fa-fw fa-file-invoice mr-2"></i>Invoices</h3>
<div class="card-tools">
<div class="btn-group">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addInvoiceModal"><i class="fas fa-plus mr-2"></i>New Invoice</button>
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#exportInvoicesModal">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
</div>
</div>
</div>
</div>
<div class="card-body">
<form class="mb-4" autocomplete="off">
<input type="hidden" name="status" value="<?php if (isset($_GET['status'])) { echo nullable_htmlentities($_GET['status']); } ?>">
<?php if ($client_url) { ?>
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<?php } ?>
<div class="row">
<div class="col-sm-4">
<div class="form-group mb-md-0">
<div class="input-group">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) {echo stripslashes(nullable_htmlentities($q));} ?>" placeholder="Search Invoices">
<div class="input-group-append">
<button class="btn btn-secondary" type="button" data-toggle="collapse" data-target="#advancedFilter"><i class="fas fa-filter"></i></button>
<button class="btn btn-primary"><i class="fa fa-search"></i></button>
</div>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="form-group mb-md-0">
<select class="form-control select2" name="category" onchange="this.form.submit()">
<option value="">- All Categories -</option>
<?php
$sql_categories_filter = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Income' AND EXISTS (SELECT 1 FROM invoices WHERE invoice_category_id = category_id) ORDER BY category_name ASC");
while ($row = mysqli_fetch_array($sql_categories_filter)) {
$category_id = intval($row['category_id']);
$category_name = nullable_htmlentities($row['category_name']);
?>
<option <?php if ($category_filter == $category_id) { echo "selected"; } ?> value="<?php echo $category_id; ?>"><?php echo $category_name; ?></option>
<?php
}
?>
</select>
</div>
</div>
<div class="col-md-5">
<div class="btn-group float-right">
<div class="dropdown ml-2" id="bulkActionButton" hidden>
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">
<i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>)
</button>
<div class="dropdown-menu">
<?php if ($client_url && $balance > 0) { ?>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#addBulkPaymentModal">
<i class="fa fa-credit-card mr-2"></i>Batch Payment
</a>
<div class="dropdown-divider"></div>
<?php } ?>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkEditCategoryModal">
<i class="fas fa-fw fa-list-ul mr-2"></i>Set Category
</a>
</div>
</div>
</div>
</div>
</div>
<div class="collapse mt-3 <?php if (!empty($_GET['dtf']) || $_GET['canned_date'] !== "custom" ) { echo "show"; } ?>" id="advancedFilter">
<div class="row">
<div class="col-md-2">
<div class="form-group">
<label>Canned Date</label>
<select onchange="this.form.submit()" class="form-control select2" name="canned_date">
<option <?php if ($_GET['canned_date'] == "custom") { echo "selected"; } ?> value="custom">Custom</option>
<option <?php if ($_GET['canned_date'] == "today") { echo "selected"; } ?> value="today">Today</option>
<option <?php if ($_GET['canned_date'] == "yesterday") { echo "selected"; } ?> value="yesterday">Yesterday</option>
<option <?php if ($_GET['canned_date'] == "thisweek") { echo "selected"; } ?> value="thisweek">This Week</option>
<option <?php if ($_GET['canned_date'] == "lastweek") { echo "selected"; } ?> value="lastweek">Last Week</option>
<option <?php if ($_GET['canned_date'] == "thismonth") { echo "selected"; } ?> value="thismonth">This Month</option>
<option <?php if ($_GET['canned_date'] == "lastmonth") { echo "selected"; } ?> value="lastmonth">Last Month</option>
<option <?php if ($_GET['canned_date'] == "thisyear") { echo "selected"; } ?> value="thisyear">This Year</option>
<option <?php if ($_GET['canned_date'] == "lastyear") { echo "selected"; } ?> value="lastyear">Last Year</option>
</select>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>Date From</label>
<input onchange="this.form.submit()" type="date" class="form-control" name="dtf" max="2999-12-31" value="<?php echo $dtf; ?>">
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>Date To</label>
<input onchange="this.form.submit()" type="date" class="form-control" name="dtt" max="2999-12-31" value="<?php echo $dtt; ?>">
</div>
</div>
</div>
</div>
</form>
<hr>
<form id="bulkActions" action="post.php" method="post" enctype="multipart/form-data">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<div class="table-responsive-sm">
<table class="table table-striped table-borderless table-hover">
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?> text-nowrap">
<tr>
<td class="bg-light pr-0">
<div class="form-check">
<input class="form-check-input" id="selectAllCheckbox" type="checkbox" onclick="checkAll(this)">
</div>
</td>
<th>
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=invoice_number&order=<?php echo $disp ?>">
Number <?php if ($sort == 'invoice_number') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=invoice_scope&order=<?php echo $disp; ?>">
Scope <?php if ($sort == 'invoice_scope') { echo $order_icon; } ?>
</a>
</th>
<?php if (!$client_url) { ?>
<th>
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=client_name&order=<?php echo $disp; ?>">
Client <?php if ($sort == 'client_name') { echo $order_icon; } ?>
</a>
</th>
<?php } ?>
<th class="text-right">
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=invoice_amount&order=<?php echo $disp; ?>">
Amount <?php if ($sort == 'invoice_amount') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=invoice_date&order=<?php echo $disp; ?>">
Date <?php if ($sort == 'invoice_date') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=invoice_due&order=<?php echo $disp; ?>">
Due <?php if ($sort == 'invoice_due') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=category_name&order=<?php echo $disp; ?>">
Category <?php if ($sort == 'category_name') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=invoice_status&order=<?php echo $disp; ?>">
Status <?php if ($sort == 'invoice_status') { echo $order_icon; } ?>
</a>
</th>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql)) {
$invoice_id = intval($row['invoice_id']);
$invoice_prefix = nullable_htmlentities($row['invoice_prefix']);
$invoice_number = nullable_htmlentities($row['invoice_number']);
$invoice_scope = nullable_htmlentities($row['invoice_scope']);
if (empty($invoice_scope)) {
$invoice_scope_display = "-";
} else {
$invoice_scope_display = $invoice_scope;
}
$invoice_status = nullable_htmlentities($row['invoice_status']);
$invoice_date = nullable_htmlentities($row['invoice_date']);
$invoice_due = nullable_htmlentities($row['invoice_due']);
$invoice_discount = floatval($row['invoice_discount_amount']);
$invoice_amount = floatval($row['invoice_amount']);
$invoice_currency_code = nullable_htmlentities($row['invoice_currency_code']);
$invoice_created_at = nullable_htmlentities($row['invoice_created_at']);
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
$category_id = intval($row['category_id']);
$category_name = nullable_htmlentities($row['category_name']);
$client_currency_code = nullable_htmlentities($row['client_currency_code']);
$client_net_terms = intval($row['client_net_terms']);
if ($client_net_terms == 0) {
$client_net_terms = $config_default_net_terms;
}
$now = time();
if (($invoice_status == "Sent" || $invoice_status == "Partial" || $invoice_status == "Viewed") && strtotime($invoice_due) + 86400 < $now) {
$overdue_color = "text-danger font-weight-bold";
} else {
$overdue_color = "";
}
$invoice_badge_color = getInvoiceBadgeColor($invoice_status);
?>
<tr>
<td class="pr-0 bg-light">
<div class="form-check">
<input class="form-check-input bulk-select" type="checkbox" name="invoice_ids[]" value="<?php echo $invoice_id ?>">
</div>
</td>
<td class="text-bold">
<a href="invoice.php?<?php echo $client_url; ?>invoice_id=<?php echo $invoice_id; ?>">
<?php echo "$invoice_prefix$invoice_number"; ?>
</a>
</td>
<td><?php echo $invoice_scope_display; ?></td>
<?php if (!$client_url) { ?>
<td class="text-bold"><a href="invoices.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
<?php } ?>
<td class="text-bold text-right"><?php echo numfmt_format_currency($currency_format, $invoice_amount, $invoice_currency_code); ?></td>
<td><?php echo $invoice_date; ?></td>
<td class="<?php echo $overdue_color; ?>"><?php echo $invoice_due; ?></td>
<td><?php echo $category_name; ?></td>
<td>
<span class="p-2 badge badge-<?php echo $invoice_badge_color; ?>">
<?php echo $invoice_status; ?>
</span>
</td>
<td>
<div class="dropdown dropleft text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i>
</button>
<div class="dropdown-menu">
<?php if ($invoice_status !== 'Paid' && $invoice_status !== 'Cancelled' && $invoice_status !== 'Draft' && $invoice_status !== 'Non-Billable' && $invoice_amount != 0) { ?>
<a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/invoice/invoice_pay.php?id=<?= $invoice_id ?>">
<i class="fa fa-fw fa-credit-card mr-2"></i>Add Payment
</a>
<div class="dropdown-divider"></div>
<?php if ($invoice_status !== 'Partial' && $config_stripe_enable && $stripe_id && $stripe_pm) { ?>
<a class="dropdown-item confirm-link" href="post.php?add_payment_stripe&invoice_id=<?php echo $invoice_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token']; ?>">
<i class="fa fa-fw fa-credit-card mr-2"></i>Pay via saved card
</a>
<div class="dropdown-divider"></div>
<?php } ?>
<?php } ?>
<a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/invoice/invoice_edit.php?id=<?= $invoice_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit
</a>
<a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/invoice/invoice_copy.php?id=<?= $invoice_id ?>">
<i class="fas fa-fw fa-copy mr-2"></i>Copy
</a>
<div class="dropdown-divider"></div>
<?php if (!empty($config_smtp_host)) { ?>
<a class="dropdown-item" href="post.php?email_invoice=<?php echo $invoice_id; ?>">
<i class="fas fa-fw fa-paper-plane mr-2"></i>Send Email
</a>
<div class="dropdown-divider"></div>
<?php } ?>
<?php if ($invoice_status == 'Draft') { ?>
<a class="dropdown-item" href="post.php?mark_invoice_sent=<?php echo $invoice_id; ?>">
<i class="fas fa-fw fa-check mr-2"></i>Mark Sent
</a>
<div class="dropdown-divider"></div>
<?php } ?>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_invoice=<?php echo $invoice_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</a>
</div>
</div>
</td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
<?php require_once "modals/invoice/invoice_bulk_edit_category.php"; ?>
</form>
<?php require_once "../includes/filter_footer.php";
?>
</div>
</div>
<script src="../js/bulk_actions.js"></script>
<?php
require_once "modals/invoice/invoice_add.php";
if ($client_url) { require_once "modals/invoice/invoice_payment_add_bulk.php"; }
require_once "modals/invoice/invoice_export.php";
require_once "../includes/footer.php";

View File

@@ -0,0 +1,14 @@
$('#summaryModal').on('shown.bs.modal', function (e) {
// Perform AJAX request to get the summary
$.ajax({
url: 'post.php?ai_ticket_summary',
method: 'POST',
data: { ticket_id: <?php echo $ticket_id; ?> },
success: function(response) {
$('#summaryContent').html(response);
},
error: function() {
$('#summaryContent').html('Error generating summary.');
}
});
});

View File

@@ -0,0 +1,23 @@
// Initialize Stripe.js
const stripe = Stripe(document.getElementById("stripe_publishable_key").value);
initialize();
// Fetch Checkout Session and retrieve the client secret
async function initialize() {
const fetchClientSecret = async () => {
const response = await fetch("/client/post.php?create_stripe_checkout", {
method: "POST",
});
const { clientSecret } = await response.json();
return clientSecret;
};
// Initialize Checkout
const checkout = await stripe.initEmbeddedCheckout({
fetchClientSecret,
});
// Mount Checkout
checkout.mount('#checkout');
}

View File

@@ -0,0 +1,37 @@
function fetchSSL(type)
{
// Get the domain name input & issued/expire/key fields, based on whether this is a new cert or updating an existing
if (type == 'new') {
var domain = document.getElementById("domain").value;
var issuedBy = document.getElementById("issuedBy");
var expire = document.getElementById("expire");
var publicKey = document.getElementById("publicKey");
}
if (type == 'edit') {
var domain = document.getElementById("editCertificateDomain").value;
var issuedBy = document.getElementById("editCertificateIssuedBy");
var expire = document.getElementById("editCertificateExpire");
var publicKey = document.getElementById("editCertificatePublicKey");
}
//Send a GET request to post.php as post.php?certificate_fetch_parse_json_details=TRUE&domain=DOMAIN
jQuery.get(
"ajax.php",
{certificate_fetch_parse_json_details: 'TRUE', domain: domain},
function(data) {
//If we get a response from post.php, parse it as JSON
const ssl_data = JSON.parse(data);
if (ssl_data.success == "TRUE") {
// Fill the form fields with the cert data
issuedBy.value = ssl_data.issued_by;
expire.value = ssl_data.expire;
publicKey.value = ssl_data.public_key;
}
else{
alert("Error whilst parsing/retrieving details for domain")
}
}
);
}

View File

@@ -0,0 +1,9 @@
// Force the user to correctly type the client name to be deleted before activating the button to delete a client
function validateClientNameDelete(client_id) {
if (document.getElementById("clientNameProvided" + client_id).value === document.getElementById("clientName" + client_id).value) {
document.getElementById("clientDeleteButton" + client_id).className = "btn btn-danger btn-lg px-5";
}
else{
document.getElementById("clientDeleteButton" + client_id).className = "btn btn-danger btn-lg px-5 disabled";
}
}

View File

@@ -0,0 +1,16 @@
function showOTPViaCredentialID(credential_id) {
// Send a GET request to ajax.php as ajax.php?get_totp_token_via_id=true&credential_id=ID
jQuery.get(
"ajax.php", {
get_totp_token_via_id: 'true',
credential_id: credential_id
},
function(data) {
//If we get a response from post.php, parse it as JSON
const token = JSON.parse(data);
document.getElementById("otp_" + credential_id).innerText = token
}
);
}

View File

@@ -0,0 +1,5 @@
function populateFileDeleteModal(file_id, file_name) {
// Dynamically populate the file delete modal with the file id (hidden) and name
document.getElementById("file_delete_id").value = file_id;
document.getElementById("file_delete_name").innerText = file_name;
}

View File

@@ -0,0 +1,14 @@
function generatePassword(login_id) {
// Send a GET request to ajax.php as ajax.php?get_readable_pass=true
jQuery.get(
"ajax.php", {
get_readable_pass: 'true'
},
function(data) {
//If we get a response from post.php, parse it as JSON
const password = JSON.parse(data);
document.getElementById("password").value = password;
}
);
}

View File

@@ -0,0 +1,117 @@
const stripe = Stripe(document.getElementById("stripe_publishable_key").value);
let elements;
initialize();
checkStatus();
document
.querySelector("#payment-form")
.addEventListener("submit", handleSubmit);
let emailAddress = '';
// Fetches a payment intent and captures the client secret
async function initialize() {
const { clientSecret } = await fetch("guest_ajax.php?stripe_create_pi=true", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
invoice_id: document.getElementById("invoice_id").value,
url_key: document.getElementById("url_key").value
}),
}).then((r) => r.json());
elements = stripe.elements({ clientSecret });
const paymentElementOptions = {
layout: "tabs",
};
const paymentElement = elements.create("payment", paymentElementOptions);
paymentElement.mount("#payment-element");
// Unhide the submit button once everything has loaded
document.getElementById("submit").hidden = false;
}
async function handleSubmit(e) {
e.preventDefault();
setLoading(true);
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: window.location.href,
receipt_email: emailAddress,
},
});
// This point will only be reached if there is an immediate error when
// confirming the payment. Otherwise, your customer will be redirected to
// your `return_url`. For some payment methods like iDEAL, your customer will
// be redirected to an intermediate site first to authorize the payment, then
// redirected to the `return_url`.
if (error.type === "card_error" || error.type === "validation_error") {
showMessage(error.message);
} else {
showMessage("An unexpected error occurred.");
}
setLoading(false);
}
// Fetches the payment intent status after payment submission
async function checkStatus() {
const clientSecret = new URLSearchParams(window.location.search).get(
"payment_intent_client_secret"
);
if (!clientSecret) {
return;
}
const { paymentIntent } = await stripe.retrievePaymentIntent(clientSecret);
switch (paymentIntent.status) {
case "succeeded":
showMessage("Payment succeeded!");
break;
case "processing":
showMessage("Your payment is processing.");
break;
case "requires_payment_method":
showMessage("Your payment was not successful, please try again.");
break;
default:
showMessage("Something went wrong.");
break;
}
}
// ------- UI helpers -------
function showMessage(messageText) {
const messageContainer = document.querySelector("#payment-message");
messageContainer.classList.remove("hidden");
messageContainer.textContent = messageText;
setTimeout(function () {
messageContainer.classList.add("hidden");
messageText.textContent = "";
}, 4000);
}
// Show a spinner on payment submission
function setLoading(isLoading) {
if (isLoading) {
// Disable the button and show a spinner
document.querySelector("#submit").disabled = true;
document.querySelector("#spinner").classList.remove("hidden");
document.querySelector("#button-text").classList.add("hidden");
} else {
document.querySelector("#submit").disabled = false;
document.querySelector("#spinner").classList.add("hidden");
document.querySelector("#button-text").classList.remove("hidden");
}
}

18
agent/js/keepalive.js Normal file
View File

@@ -0,0 +1,18 @@
// Keep PHP sessions alive
// Sends requests to keepalive.php in the background every 10 mins to prevent PHP garbage collection ending sessions
function keep_alive() {
//Send a GET request to keepalive.php as keepalive.php?keepalive
jQuery.get(
"../keepalive.php",
{keepalive: 'true'},
function(data) {
// Don't care about a response
}
);
}
// Run every 10 mins
setInterval(keep_alive, 600000);

58
agent/js/share_modal.js Normal file
View File

@@ -0,0 +1,58 @@
function populateShareModal(client_id, item_type, item_ref_id) {
// Populate HTML fields
document.getElementById("share_client_id").value = client_id;
document.getElementById("share_item_type").value = item_type;
document.getElementById("share_item_ref_id").value = item_ref_id;
// (re)Hide the URL/div (incase we're re-generating it)
document.getElementById("div_share_link_output").hidden = true;
document.getElementById("share_link").value = '';
// Show form and generate button
document.getElementById("div_share_link_form").hidden = false;
document.getElementById("div_share_link_generate").hidden = false;
$(document).ready(function() {
$('#share_email').select2({
tags: true,
placeholder: 'Select or type a value',
allowClear: true
});
});
}
function generateShareLink() {
let client_id = document.getElementById("share_client_id").value;
let item_type = document.getElementById("share_item_type").value;
let item_ref_id = document.getElementById("share_item_ref_id").value;
let item_note = document.getElementById("share_note").value;
let item_views = document.getElementById("share_views").checked ? 1 : 0;
let item_expires = document.querySelector('input[name="expires"]:checked').value;
let contact_email = document.getElementById("share_email").value;
// Check values are provided
if (item_expires) {
// Send a GET request to ajax.php as ajax.php?share_generate_link=true....
jQuery.get(
"ajax.php",
{share_generate_link: 'true', client_id: client_id, type: item_type, id: item_ref_id, note: item_note ,views: item_views, expires: item_expires, contact_email},
function(data) {
// If we get a response from ajax.php, parse it as JSON
const response = JSON.parse(data);
// Hide the div/form & button used to generate the link
document.getElementById("div_share_link_form").hidden = true;
document.getElementById("div_share_link_generate").hidden = true;
// Show the readonly input containing the shared link
document.getElementById("div_share_link_output").hidden = false;
document.getElementById("share_link").value = response;
// Copy link to clipboard
navigator.clipboard.writeText(response);
}
);
}
}

View File

@@ -0,0 +1,94 @@
/*
* LISTENERS
*/
// Modal loaded listener - populate client select
const changeClientModalLoad = document.getElementById('clientChangeTicketModalLoad');
changeClientModalLoad.addEventListener('click', function() {
populateChangeClientModal_Clients();
})
// Client selected listener - populate contact select
// We seem to have to use jQuery to listen for events, as the client input is a select2 component?
const clientSelectDropdown = document.getElementById("changeClientSelect");
$(clientSelectDropdown).on('select2:select', function (e) {
let client_id = $(this).find(':selected').val();
populateChangeClientModal_Contacts(client_id);
});
/*
* FUNCTIONS
*/
// Populate client list function
function populateChangeClientModal_Clients() {
// Get current client ID
let current_client_id = document.getElementById("client_id").value;
// Send a GET request to ajax.php as ajax.php?get_active_clients=true
jQuery.get(
"ajax.php",
{get_active_clients: 'true'},
function(data) {
// If we get a response from ajax.php, parse it as JSON
const response = JSON.parse(data);
// Access the data for clients (multiple)
const clients = response.clients;
// Client dropdown already defined in listeners as clientSelectDropdown
// Clear dropdown
let i, L = clientSelectDropdown.options.length - 1;
for (i = L; i >= 0; i--) {
clientSelectDropdown.remove(i);
}
clientSelectDropdown[clientSelectDropdown.length] = new Option('- Client -', '0');
// Populate dropdown
clients.forEach(client => {
if (parseInt(current_client_id) !== parseInt(client.client_id)) {
// Show clients returned (excluding the current client ID - we can't change a ticket client to itself)
clientSelectDropdown[clientSelectDropdown.length] = new Option(client.client_name, client.client_id);
}
});
}
);
}
// Populate client contact function (after a client is selected)
function populateChangeClientModal_Contacts(client_id) {
// Send a GET request to ajax.php as ajax.php?get_client_contacts=true&client_id=NUM
jQuery.get(
"ajax.php",
{get_client_contacts: 'true', client_id: client_id},
function(data) {
// If we get a response from ajax.php, parse it as JSON
const response = JSON.parse(data);
// Access the data for contacts (multiple)
const contacts = response.contacts;
// Contacts dropdown
const contactSelectDropdown = document.getElementById("changeContactSelect");
// Clear Category dropdown
let i, L = contactSelectDropdown.options.length - 1;
for (i = L; i >= 0; i--) {
contactSelectDropdown.remove(i);
}
contactSelectDropdown[contactSelectDropdown.length] = new Option('- Contact -', '0');
// Populate dropdown
contacts.forEach(contact => {
contactSelectDropdown[contactSelectDropdown.length] = new Option(contact.contact_name, contact.contact_id);
});
}
);
}

View File

@@ -0,0 +1,33 @@
// Collision detection
// Adds a "view" entry of the current ticket every 2 mins into the database
// Updates the currently viewing (ticket_collision_viewing) element with anyone that's looked at this ticket in the last two mins
function ticket_collision_detection() {
// Get the page ticket id
var ticket_id = document.getElementById("ticket_id").value;
//Send a GET request to ajax.php as ajax.php?ticket_add_view=true&ticket_id=NUMBER
jQuery.get(
"ajax.php",
{ticket_add_view: 'true', ticket_id: ticket_id},
function(data) {
// We don't care about a response
}
);
//Send a GET request to ajax.php as ajax.php?ticket_query_views=true&ticket_id=NUMBER
jQuery.get(
"ajax.php",
{ticket_query_views: 'true', ticket_id: ticket_id},
function(data) {
//If we get a response from ajax.php, parse it as JSON
const ticket_view_data = JSON.parse(data);
document.getElementById("ticket_collision_viewing").innerHTML = ticket_view_data.message;
}
);
}
// Call on page load
ticket_collision_detection();
// Run every 2 mins
setInterval(ticket_collision_detection, 120*1000);

40
agent/js/ticket_merge.js Normal file
View File

@@ -0,0 +1,40 @@
// Ticket merging
// Gets details of the ticket we're going to merge this ticket into
// Shows the details under the comments box & enables the merge button if the status of the merge into ticket is not closed
function merge_into_number_get_details() {
// Get the ticket number to merge into
var merge_into_ticket_number = document.getElementById("merge_into_ticket_number").value;
// Reset the form
document.getElementById("merge_ticket_btn").disabled = true;
document.getElementById("merge_into_details_div").hidden = true;
// Send a GET request to post.php as post.php?merge_ticket_get_json_details=true&merge_into_ticket_number=NUMBER
jQuery.get(
"ajax.php",
{merge_ticket_get_json_details: 'true', merge_into_ticket_number: merge_into_ticket_number},
function(data){
// If we get a response from post.php, parse it as JSON
const merge_into_ticket_info = JSON.parse(data);
// Check that the current ticket ID isn't also the new/merge ticket ID
if(parseInt(merge_into_ticket_info.ticket_id) !== parseInt(document.getElementById("current_ticket_id").value)){
// Show the div with the parent ("master") ticket details, populate
document.getElementById("merge_into_details_div").hidden = false;
document.getElementById("merge_into_details_number").innerText = "Parent ticket details: " + merge_into_ticket_info.ticket_prefix + merge_into_ticket_info.ticket_number;
document.getElementById("merge_into_details_client").innerText = "Client Contact: " + merge_into_ticket_info.client_name + " / " + merge_into_ticket_info.contact_name;
document.getElementById("merge_into_details_subject").innerText = "Subject: " + merge_into_ticket_info.ticket_subject;
document.getElementById("merge_into_details_priority").innerText = "Priority: " + merge_into_ticket_info.ticket_priority;
document.getElementById("merge_into_details_status").innerText = "Status: " + merge_into_ticket_info.ticket_status_name;
// Enable the merge button if the merge into ticket isn't in a closed state
if(merge_into_ticket_info.ticket_status_name.toLowerCase() != "closed"){
document.getElementById("merge_ticket_btn").disabled = false;
}
}
}
);
}

View File

@@ -0,0 +1,175 @@
(function() {
document.addEventListener("DOMContentLoaded", function() {
// Initialize variables
var timerInterval = null;
var ticketID = getCurrentTicketID();
var elapsedSecs = getElapsedSeconds();
function getCurrentTicketID() {
const urlParams = new URLSearchParams(window.location.search);
return urlParams.get('ticket_id');
}
function getLocalStorageKey(suffix) {
return ticketID + "-" + suffix;
}
function getElapsedSeconds() {
let storedStartTime = parseInt(localStorage.getItem(getLocalStorageKey("startTime")) || "0");
let pausedTime = parseInt(localStorage.getItem(getLocalStorageKey("pausedTime")) || "0");
if (!storedStartTime) return pausedTime;
let timeSinceStart = Math.floor((Date.now() - storedStartTime) / 1000);
return pausedTime + timeSinceStart;
}
function displayTime() {
let totalSeconds = elapsedSecs;
let hours = Math.floor(totalSeconds / 3600);
totalSeconds %= 3600;
let minutes = Math.floor(totalSeconds / 60);
let seconds = totalSeconds % 60;
document.getElementById("hours").value = pad(hours);
document.getElementById("minutes").value = pad(minutes);
document.getElementById("seconds").value = pad(seconds);
}
function pad(val) {
return val < 10 ? "0" + val : val;
}
function countTime() {
elapsedSecs++;
displayTime();
}
function startTimer() {
if (!localStorage.getItem(getLocalStorageKey("startTime"))) {
localStorage.setItem(getLocalStorageKey("startTime"), Date.now().toString());
}
timerInterval = setInterval(countTime, 1000);
document.getElementById("startStopTimer").innerHTML = "<i class='fas fa-pause'></i>";
localStorage.setItem("ticket-timer-running-" + ticketID, "true");
}
function pauseTimer() {
if (timerInterval) {
clearInterval(timerInterval);
timerInterval = null;
}
let currentElapsed = getElapsedSeconds();
localStorage.setItem(getLocalStorageKey("pausedTime"), currentElapsed.toString());
localStorage.removeItem(getLocalStorageKey("startTime"));
document.getElementById("startStopTimer").innerHTML = "<i class='fas fa-play'></i>";
localStorage.setItem("ticket-timer-running-" + ticketID, "false");
}
function clearTimeStorage() {
localStorage.removeItem(getLocalStorageKey("startTime"));
localStorage.removeItem(getLocalStorageKey("pausedTime"));
localStorage.removeItem("ticket-timer-running-" + ticketID);
}
function resetTimer() {
if (confirm("Are you sure you want to reset the timer?")) {
clearInterval(timerInterval);
timerInterval = null;
elapsedSecs = 0;
clearTimeStorage();
displayTime();
document.getElementById("startStopTimer").innerHTML = "<i class='fas fa-play'></i>";
}
localStorage.setItem("ticket-timer-running-" + ticketID, "false");
}
function forceResetTimer() {
clearInterval(timerInterval);
timerInterval = null;
elapsedSecs = 0;
clearTimeStorage();
displayTime();
document.getElementById("startStopTimer").innerHTML = "<i class='fas fa-play'></i>";
}
function handleInputFocus() {
pauseTimer();
}
function updateTimeFromInput() {
const hours = parseInt(document.getElementById("hours").value, 10) || 0;
const minutes = parseInt(document.getElementById("minutes").value, 10) || 0;
const seconds = parseInt(document.getElementById("seconds").value, 10) || 0;
elapsedSecs = (hours * 3600) + (minutes * 60) + seconds;
if (!timerInterval) {
localStorage.setItem(getLocalStorageKey("pausedTime"), elapsedSecs.toString());
} else {
const newStartTime = Date.now() - (elapsedSecs * 1000);
localStorage.setItem(getLocalStorageKey("startTime"), newStartTime.toString());
localStorage.removeItem(getLocalStorageKey("pausedTime"));
}
}
function checkStatusAndPauseTimer() {
var status = document.querySelector('select[name="status"]').value;
if (status.includes("Pending") || status.includes("Close")) {
pauseTimer();
}
}
// Attach input listeners
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);
document.querySelector('select[name="status"]').addEventListener('change', checkStatusAndPauseTimer);
document.getElementById("startStopTimer").addEventListener('click', function() {
if (timerInterval === null) {
startTimer();
} else {
pauseTimer();
}
});
document.getElementById("resetTimer").addEventListener('click', function() {
resetTimer();
});
document.getElementById("ticket_add_reply").addEventListener('click', function() {
setTimeout(forceResetTimer, 100);
});
document.getElementById("ticket_close").addEventListener('click', function() {
setTimeout(clearTimeStorage, 100);
});
// Final initialization logic
try {
displayTime();
// If no timer state, respect ticketAutoStart
if (!localStorage.getItem(getLocalStorageKey("startTime")) && !localStorage.getItem(getLocalStorageKey("pausedTime"))) {
if (ticketAutoStart === 1) {
startTimer();
} else {
pauseTimer();
}
}
// If timer already running, resume it
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);
}
});
})();

View File

@@ -0,0 +1,176 @@
// Used to populate dynamic content in recurring_ticket_add_modal and ticket_add_modal_v2 based on selected client
// Client selected listener
// We seem to have to use jQuery to listen for events, as the client input is a select2 component?
const clientSelectDropdown = document.getElementById("changeClientSelect"); // Define client selector
// // If the client selector is disabled, we must be on a client-specific page instead. Trigger the lists to update.
if (clientSelectDropdown.disabled) {
let client_id = $(clientSelectDropdown).find(':selected').val();
populateLists(client_id);
}
// Listener for client selection. Populate select lists when a client is selected
$(clientSelectDropdown).on('select2:select', function (e) {
let client_id = $(this).find(':selected').val();
// Update the contacts dropdown list
populateLists(client_id);
});
// Populates dropdowns with dynamic content based on the client ID
// Called the client select dropdown is used or if the client select is disabled
function populateLists(client_id) {
populateContactsDropdown(client_id);
populateAssetsDropdown(client_id);
populateLocationsDropdown(client_id);
populateVendorsDropdown(client_id);
}
// Populate client contacts
function populateContactsDropdown(client_id) {
// Send a GET request to ajax.php as ajax.php?get_client_contacts=true&client_id=NUM
jQuery.get(
"ajax.php",
{get_client_contacts: 'true', client_id: client_id},
function(data) {
// If we get a response from ajax.php, parse it as JSON
const response = JSON.parse(data);
// Access the data for contacts (multiple)
const contacts = response.contacts;
// Contacts dropdown
const contactSelectDropdown = document.getElementById("contactSelect");
// Clear dropdown
let i, L = contactSelectDropdown.options.length - 1;
for (i = L; i >= 0; i--) {
contactSelectDropdown.remove(i);
}
contactSelectDropdown[contactSelectDropdown.length] = new Option('- Contact -', '0');
// Populate dropdown
contacts.forEach(contact => {
var appendText = "";
if (contact.contact_primary == "1") {
appendText = " (Primary)";
} else if (contact.contact_technical == "1") {
appendText = " (Technical)";
}
contactSelectDropdown[contactSelectDropdown.length] = new Option(contact.contact_name + appendText, contact.contact_id);
});
}
);
}
// Populate client assets
function populateAssetsDropdown(client_id) {
jQuery.get(
"ajax.php",
{get_client_assets: 'true', client_id: client_id},
function(data) {
// If we get a response from ajax.php, parse it as JSON
const response = JSON.parse(data);
// Access the data for assets (multiple)
const assets = response.assets;
// Assets dropdown
const assetSelectDropdown = document.getElementById("assetSelect");
// Clear dropdown
let i, L = assetSelectDropdown.options.length - 1;
for (i = L; i >= 0; i--) {
assetSelectDropdown.remove(i);
}
assetSelectDropdown[assetSelectDropdown.length] = new Option('- Asset -', '0');
// Populate dropdown with asset name (and contact, if set)
assets.forEach(asset => {
let displayText = asset.asset_name;
if (asset.contact_name !== null) {
displayText = asset.asset_name + " - " + asset.contact_name;
}
assetSelectDropdown[assetSelectDropdown.length] = new Option(displayText, asset.asset_id);
});
}
);
}
// Populate client locations
function populateLocationsDropdown(client_id) {
jQuery.get(
"ajax.php",
{get_client_locations: 'true', client_id: client_id},
function(data) {
// If we get a response from ajax.php, parse it as JSON
const response = JSON.parse(data);
// Access the data for locations (multiple)
const locations = response.locations;
// Locations dropdown
const locationSelectDropdown = document.getElementById("locationSelect");
// Clear dropdown
let i, L = locationSelectDropdown.options.length - 1;
for (i = L; i >= 0; i--) {
locationSelectDropdown.remove(i);
}
locationSelectDropdown[locationSelectDropdown.length] = new Option('- Location -', '0');
// Populate dropdown
locations.forEach(location => {
locationSelectDropdown[locationSelectDropdown.length] = new Option(location.location_name, location.location_id);
});
}
);
}
// Populate client vendors
function populateVendorsDropdown(client_id) {
jQuery.get(
"ajax.php",
{get_client_vendors: 'true', client_id: client_id},
function(data) {
// If we get a response from ajax.php, parse it as JSON
const response = JSON.parse(data);
// Access the data for locations (multiple)
const vendors = response.vendors;
// Locations dropdown
const vendorSelectDropdown = document.getElementById("vendorSelect");
// Clear dropdown
let i, L = vendorSelectDropdown.options.length - 1;
for (i = L; i >= 0; i--) {
vendorSelectDropdown.remove(i);
}
vendorSelectDropdown[vendorSelectDropdown.length] = new Option('- Vendor -', '0');
// Populate dropdown
vendors.forEach(vendor => {
vendorSelectDropdown[vendorSelectDropdown.length] = new Option(vendor.vendor_name, vendor.vendor_id);
});
}
);
}

126
agent/js/tickets_kanban.js Normal file
View File

@@ -0,0 +1,126 @@
$(document).ready(function () {
console.log('CONFIG_TICKET_MOVING_COLUMNS:', CONFIG_TICKET_MOVING_COLUMNS);
console.log('CONFIG_TICKET_ORDERING:', CONFIG_TICKET_ORDERING);
// -------------------------------
// Drag: Kanban Columns (Statuses)
// -------------------------------
new Sortable(document.querySelector('#kanban-board'), {
animation: 150,
handle: '.panel-title',
draggable: '.kanban-column',
onEnd: function () {
const columnPositions = Array.from(document.querySelectorAll('#kanban-board .kanban-column')).map((col, index) => ({
status_id: $(col).data('status-id'),
status_kanban: index
}));
if (CONFIG_TICKET_MOVING_COLUMNS === 1) {
$.post('ajax.php', {
update_kanban_status_position: true,
positions: columnPositions
}).done(() => {
console.log('Ticket status kanban orders updated.');
}).fail((xhr) => {
console.error('Error updating status order:', xhr.responseText);
});
}
}
});
// -------------------------------
// Drag: Tasks within Columns
// -------------------------------
document.querySelectorAll('.kanban-status').forEach(statusCol => {
new Sortable(statusCol, {
group: 'tickets',
animation: 150,
handle: isTouchDevice() ? '.drag-handle-class' : undefined,
onStart: () => hidePlaceholders(),
onEnd: function (evt) {
const target = evt.to;
const movedEl = evt.item;
// Disallow reordering in same column if config says so
if (CONFIG_TICKET_ORDERING === 0 && evt.from === evt.to) {
evt.from.insertBefore(movedEl, evt.from.children[evt.oldIndex]);
showPlaceholders();
return;
}
const columnId = $(target).data('status-id');
const positions = Array.from(target.querySelectorAll('.task')).map((card, index) => {
const ticketId = $(card).data('ticket-id');
const oldStatus = ticketId === $(movedEl).data('ticket-id')
? $(movedEl).data('ticket-status-id')
: false;
$(card).data('ticket-status-id', columnId); // update DOM
return {
ticket_id: ticketId,
ticket_order: index,
ticket_oldStatus: oldStatus,
ticket_status: columnId
};
});
$.post('ajax.php', {
update_kanban_ticket: true,
positions: positions
}).done(() => {
console.log('Updated kanban ticket positions.');
}).fail((xhr) => {
console.error('Error updating ticket positions:', xhr.responseText);
});
// Refresh placeholders after update
showPlaceholders();
}
});
});
// -------------------------------
// 📱 Touch Support: Show drag handle on mobile
// -------------------------------
if (isTouchDevice()) {
$('.drag-handle-class').css('display', 'inline');
}
// -------------------------------
// Placeholder Management
// -------------------------------
function showPlaceholders() {
document.querySelectorAll('.kanban-status').forEach(status => {
const placeholderClass = 'empty-placeholder';
// Remove existing placeholder
const existing = status.querySelector(`.${placeholderClass}`);
if (existing) existing.remove();
// Only show if there are no tasks
if (status.querySelectorAll('.task').length === 0) {
const placeholder = document.createElement('div');
placeholder.className = `${placeholderClass} text-muted text-center p-2`;
placeholder.innerText = 'Drop ticket here';
placeholder.style.pointerEvents = 'none';
status.appendChild(placeholder);
}
});
}
function hidePlaceholders() {
document.querySelectorAll('.empty-placeholder').forEach(el => el.remove());
}
// Run once on load
showPlaceholders();
// -------------------------------
// Utility: Detect touch device
// -------------------------------
function isTouchDevice() {
return 'ontouchstart' in window || navigator.maxTouchPoints > 0;
}
});

410
agent/locations.php Normal file
View File

@@ -0,0 +1,410 @@
<?php
// Default Column Sortby Filter
$sort = "location_name";
$order = "ASC";
// If client_id is in URI then show client Side Bar and client header
if (isset($_GET['client_id'])) {
require_once "includes/inc_all_client.php";
$client_query = "AND location_client_id = $client_id";
$client_url = "client_id=$client_id&";
// Overide Filter Header Archived
if (isset($_GET['archived']) && $_GET['archived'] == 1) {
$archived = 1;
$archive_query = "location_archived_at IS NOT NULL";
} else {
$archived = 0;
$archive_query = "location_archived_at IS NULL";
}
} else {
require_once "includes/inc_client_overview_all.php";
$client_query = '';
$client_url = '';
}
if (!$client_url) {
// Client Filter
if (isset($_GET['client']) & !empty($_GET['client'])) {
$client_query = 'AND (location_client_id = ' . intval($_GET['client']) . ')';
$client = intval($_GET['client']);
} else {
// Default - any
$client_query = '';
$client = '';
}
// Overide Filter Header Archived
if (isset($_GET['archived']) && $_GET['archived'] == 1) {
$archived = 1;
$archive_query = "(client_archived_at IS NOT NULL OR location_archived_at IS NOT NULL)";
} else {
$archived = 0;
$archive_query = "(client_archived_at IS NULL AND location_archived_at IS NULL)";
}
}
// Tags Filter
if (isset($_GET['tags']) && is_array($_GET['tags']) && !empty($_GET['tags'])) {
// Sanitize each element of the tags array
$sanitizedTags = array_map('intval', $_GET['tags']);
// Convert the sanitized tags into a comma-separated string
$tag_filter = implode(",", $sanitizedTags);
$tag_query = "AND tags.tag_id IN ($tag_filter)";
} else {
$tag_filter = 0;
$tag_query = '';
}
$sql = mysqli_query(
$mysqli,
"SELECT SQL_CALC_FOUND_ROWS locations.*, clients.*, GROUP_CONCAT(tag_name) FROM locations
LEFT JOIN clients ON client_id = location_client_id
LEFT JOIN location_tags ON location_tags.location_id = locations.location_id
LEFT JOIN tags ON tags.tag_id = location_tags.tag_id
WHERE $archive_query
$tag_query
AND (location_name LIKE '%$q%' OR location_description LIKE '%$q%' OR location_address LIKE '%$q%' OR location_city LIKE '%$q%' OR location_state LIKE '%$q%' OR location_zip LIKE '%$q%' OR location_country LIKE '%$q%' OR location_phone LIKE '%$phone_query%' OR tag_name LIKE '%$q%' OR client_name LIKE '%$q%')
$access_permission_query
$client_query
GROUP BY location_id
ORDER BY location_primary DESC, $sort $order LIMIT $record_from, $record_to"
);
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?>
<div class="card card-dark">
<div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fa fa-fw fa-map-marker-alt mr-2"></i>Locations</h3>
<div class="card-tools">
<div class="btn-group">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addLocationModal">
<i class="fas fa-plus mr-2"></i>New Location
</button>
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#importLocationModal">
<i class="fa fa-fw fa-upload mr-2"></i>Import
</a>
<?php if ($num_rows[0] > 0) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#exportLocationModal">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
<?php } ?>
</div>
</div>
</div>
</div>
<div class="card-body">
<form autocomplete="off">
<?php if ($client_url) { ?>
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<?php } ?>
<input type="hidden" name="archived" value="<?php echo $archived; ?>">
<div class="row">
<div class="col-md-4">
<div class="input-group mb-3 mb-md-0">
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search Locations">
<div class="input-group-append">
<button class="btn btn-dark"><i class="fa fa-search"></i></button>
</div>
</div>
</div>
<div class="col-md-3">
<div class="input-group mb-3 mb-md-0">
<select onchange="this.form.submit()" class="form-control select2" name="tags[]" data-placeholder="- Select Tags -" multiple>
<?php
$sql_tags_filter = mysqli_query($mysqli, "
SELECT tags.tag_id, tags.tag_name, tag_type
FROM tags
LEFT JOIN location_tags ON location_tags.tag_id = tags.tag_id
LEFT JOIN locations ON location_tags.location_id = locations.location_id
WHERE tag_type = 2
$client_query OR tags.tag_id IN ($tag_filter)
GROUP BY tags.tag_id
HAVING COUNT(location_tags.location_id) > 0 OR tags.tag_id IN ($tag_filter)
");
while ($row = mysqli_fetch_array($sql_tags_filter)) {
$tag_id = intval($row['tag_id']);
$tag_name = nullable_htmlentities($row['tag_name']); ?>
<option value="<?php echo $tag_id ?>" <?php if (isset($_GET['tags']) && is_array($_GET['tags']) && in_array($tag_id, $_GET['tags'])) { echo 'selected'; } ?>> <?php echo $tag_name ?> </option>
<?php } ?>
</select>
</div>
</div>
<?php if ($client_url) { ?>
<div class="col-md-2"></div>
<?php } else { ?>
<div class="col-md-2">
<div class="input-group mb-3 mb-md-0">
<select class="form-control select2" name="client" onchange="this.form.submit()">
<option value="" <?php if ($client == "") { echo "selected"; } ?>>- All Clients -</option>
<?php
$sql_clients_filter = mysqli_query($mysqli, "
SELECT DISTINCT client_id, client_name
FROM clients
JOIN locations ON location_client_id = client_id
WHERE $archive_query
$access_permission_query
ORDER BY client_name ASC
");
while ($row = mysqli_fetch_array($sql_clients_filter)) {
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
?>
<option <?php if ($client == $client_id) { echo "selected"; } ?> value="<?php echo $client_id; ?>"><?php echo $client_name; ?></option>
<?php
}
?>
</select>
</div>
</div>
<?php } ?>
<div class="col-md-3">
<div class="btn-group float-right">
<a href="?<?php echo $client_url; ?>archived=<?php if($archived == 1){ echo 0; } else { echo 1; } ?>"
class="btn btn-<?php if($archived == 1){ echo "primary"; } else { echo "default"; } ?>">
<i class="fa fa-fw fa-archive mr-2"></i>Archived
</a>
<div class="dropdown ml-2" id="bulkActionButton" hidden>
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">
<i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>)
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkAssignTagsModal">
<i class="fas fa-fw fa-tags mr-2"></i>Assign Tags
</a>
<?php if ($archived) { ?>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-info"
type="submit" form="bulkActions" name="bulk_unarchive_locations">
<i class="fas fa-fw fa-redo mr-2"></i>Unarchive
</button>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-danger text-bold"
type="submit" form="bulkActions" name="bulk_delete_locations">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</button>
<?php } else { ?>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-danger confirm-link"
type="submit" form="bulkActions" name="bulk_archive_locations">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</button>
<?php } ?>
</div>
</div>
</div>
</div>
</div>
</form>
<hr>
<form id="bulkActions" action="post.php" method="post" enctype="multipart/form-data">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<div class="table-responsive-sm">
<table class="table table-striped table-borderless table-hover">
<thead class="<?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
<tr>
<td class="bg-light pr-0">
<div class="form-check">
<input class="form-check-input" id="selectAllCheckbox" type="checkbox" onclick="checkAll(this)">
</div>
</td>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=location_name&order=<?php echo $disp; ?>">
Name <?php if ($sort == 'location_name') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=location_address&order=<?php echo $disp; ?>">
Address <?php if ($sort == 'location_address') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=location_phone&order=<?php echo $disp; ?>">
Phone <?php if ($sort == 'location_phone') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=location_hours&order=<?php echo $disp; ?>">
Hours <?php if ($sort == 'location_hours') { echo $order_icon; } ?>
</a>
</th>
<?php if (!$client_url) { ?>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=client_name&order=<?php echo $disp; ?>">
Client <?php if ($sort == 'client_name') { echo $order_icon; } ?>
</a>
</th>
<?php } ?>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql)) {
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
$location_id = intval($row['location_id']);
$location_name = nullable_htmlentities($row['location_name']);
$location_description = nullable_htmlentities($row['location_description']);
$location_country = nullable_htmlentities($row['location_country']);
$location_address = nullable_htmlentities($row['location_address']);
$location_city = nullable_htmlentities($row['location_city']);
$location_state = nullable_htmlentities($row['location_state']);
$location_zip = nullable_htmlentities($row['location_zip']);
$location_phone_country_code = nullable_htmlentities($row['location_phone_country_code']);
$location_phone = nullable_htmlentities(formatPhoneNumber($row['location_phone'], $location_phone_country_code));
if (empty($location_phone)) {
$location_phone_display = "-";
} else {
$location_phone_display = $location_phone;
}
$location_fax_country_code = nullable_htmlentities($row['location_fax_country_code']);
$location_fax = nullable_htmlentities(formatPhoneNumber($row['location_fax'], $location_fax_country_code));
if ($location_fax) {
$location_fax_display = "<div class='text-secondary'>Fax: $location_fax</div>";
} else {
$location_fax_display = '';
}
$location_hours = nullable_htmlentities($row['location_hours']);
if (empty($location_hours)) {
$location_hours_display = "-";
} else {
$location_hours_display = $location_hours;
}
$location_photo = nullable_htmlentities($row['location_photo']);
$location_notes = nullable_htmlentities($row['location_notes']);
$location_created_at = nullable_htmlentities($row['location_created_at']);
$location_archived_at = nullable_htmlentities($row['location_archived_at']);
$location_contact_id = intval($row['location_contact_id']);
$location_primary = intval($row['location_primary']);
if ( $location_primary == 1 ) {
$location_primary_display = "<small class='text-success'><i class='fa fa-fw fa-check'></i> Primary</small>";
} else {
$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='locations.php?$client_url tags[]=$location_tag_id'><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 class="pr-0 bg-light">
<div class="form-check">
<input class="form-check-input bulk-select" type="checkbox" name="location_ids[]" value="<?php echo $location_id ?>">
</div>
</td>
<td>
<a class="text-dark ajax-modal" href="#" data-modal-url="modals/location/location_edit.php?id=<?= $location_id ?>">
<div class="media">
<i class="fa fa-fw fa-2x fa-map-marker-alt mr-3"></i>
<div class="media-body">
<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>
</td>
<td><a href="//maps.<?php echo $session_map_source; ?>.com?q=<?php echo "$location_address $location_zip"; ?>" target="_blank"><?php echo $location_address; ?><br><?php echo "$location_city $location_state $location_zip<br><small>$location_country</small>"; ?></a></td>
<td>
<?php echo $location_phone_display; ?>
<?php echo $location_fax_display; ?>
</td>
<td><?php echo $location_hours_display; ?></td>
<?php if (!$client_url) { ?>
<td><a href="locations.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
<?php } ?>
<td>
<div class="dropdown dropleft text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i>
</button>
<div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/location/location_edit.php?id=<?= $location_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit
</a>
<?php if ($session_user_role == 3 && $location_primary == 0) { ?>
<?php if ($location_archived_at) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-info confirm-link" href="post.php?unarchive_location=<?php echo $location_id; ?>">
<i class="fas fa-fw fa-redo mr-2"></i>Unarchive
</a>
<?php if ($config_destructive_deletes_enable) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_location=<?php echo $location_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</a>
<?php } ?>
<?php } else { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_location=<?php echo $location_id; ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</a>
<?php } ?>
<?php } ?>
</div>
</div>
</td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
<?php require_once "modals/location/location_bulk_assign_tags.php"; ?>
</form>
<?php require_once "../includes/filter_footer.php";
?>
</div>
</div>
<script src="../js/bulk_actions.js"></script>
<?php
require_once "modals/location/location_add.php";
require_once "modals/location/location_import.php";
require_once "modals/location/location_export.php";
require_once "../includes/footer.php";

159
agent/mfa_enforcement.php Normal file
View File

@@ -0,0 +1,159 @@
<?php
require_once "../config.php";
require_once "../functions.php";
require_once "../includes/check_login.php";
require_once '../plugins/totp/totp.php'; //TOTP MFA Lib
// Get Company Logo
$sql = mysqli_query($mysqli, "SELECT company_logo FROM companies");
$row = mysqli_fetch_array($sql);
$company_logo = nullable_htmlentities($row['company_logo']);
// Only generate the token once and store it in session:
if (empty($_SESSION['mfa_token'])) {
$token = key32gen();
$_SESSION['mfa_token'] = $token;
}
$token = $_SESSION['mfa_token'];
// Generate QR Code
$data = "otpauth://totp/ITFlow:$session_email?secret=$token";
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="robots" content="noindex">
<title>MFA Enforcement | <?php echo $session_company_name; ?></title>
<!--
Favicon
If Fav Icon exists else use the default one
-->
<?php if(file_exists('../uploads/favicon.ico')) { ?>
<link rel="icon" type="image/x-icon" href="/uploads/favicon.ico">
<?php } ?>
<!-- Font Awesome Icons -->
<link rel="stylesheet" href="../plugins/fontawesome-free/css/all.min.css">
<!-- Theme style -->
<link rel="stylesheet" href="../plugins/adminlte/css/adminlte.min.css">
<link href="../plugins/toastr/toastr.min.css" rel="stylesheet">
<!-- jQuery -->
<script src="../plugins/jquery/jquery.min.js"></script>
<script src="../plugins/toastr/toastr.min.js"></script>
</head>
<body class="hold-transition login-page">
<?php require_once "../includes/inc_alert_feedback.php"; ?>
<div class="login-box">
<div class="login-logo">
<?php if (!empty($company_logo)) { ?>
<img alt="<?= nullable_htmlentities($company_name)?> logo" height="110" width="380" class="img-fluid" src="<?php echo "../uploads/settings/$company_logo"; ?>">
<?php } else { ?>
<span class="text-primary text-bold"><i class="fas fa-paper-plane mr-2"></i>IT</span>Flow
<?php } ?>
</div>
<!-- /.login-logo -->
<div class="card">
<div class="card-body login-card-body text-center">
<p class="login-box-msg">Multi-Factor Authentication Enforced</p>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<img src='../plugins/barcode/barcode.php?f=png&s=qr&d=<?php echo $data; ?>' data-toggle="tooltip" title="Scan QR code into your MFA App">
<p>
<small data-toggle="tooltip" title="Can't Scan? Copy and paste this code into your app"><?php echo $token; ?></small>
<button type="button" class='btn btn-sm clipboardjs' data-clipboard-text='<?php echo $token; ?>'><i class='far fa-copy text-secondary'></i></button>
</p>
<div class="input-group mb-3">
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*" minlength="6" maxlength="6" name="verify_code" placeholder="Enter 6 digit code to verify MFA" required>
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-lock"></span>
</div>
</div>
</div>
<button type="submit" name="enable_mfa" class="btn btn-primary btn-block mb-3"><i class="fa fa-check mr-2"></i>Enable MFA</button>
</form>
</div>
<!-- /.login-card-body -->
</div>
</div>
<!-- /.login-box -->
<!-- REQUIRED SCRIPTS -->
<!-- Bootstrap 4 -->
<script src="../plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- Custom js-->
<script src="../plugins/clipboardjs/clipboard.min.js"></script>
<script>
// Slide alert up after 4 secs
$("#alert").fadeTo(5000, 500).slideUp(500, function(){
$("#alert").slideUp(500);
});
// ClipboardJS
// Tooltip
$('button').tooltip({
trigger: 'click',
placement: 'bottom'
});
function setTooltip(btn, message) {
$(btn).tooltip('hide')
.attr('data-original-title', message)
.tooltip('show');
}
function hideTooltip(btn) {
setTimeout(function() {
$(btn).tooltip('hide');
}, 1000);
}
// Clipboard
var clipboard = new ClipboardJS('.clipboardjs');
clipboard.on('success', function(e) {
setTooltip(e.trigger, 'Copied!');
hideTooltip(e.trigger);
});
clipboard.on('error', function(e) {
setTooltip(e.trigger, 'Failed!');
hideTooltip(e.trigger);
});
// Enable Popovers
$(function () {
$('[data-toggle="popover"]').popover()
});
</script>
</body>
</html>

View File

@@ -0,0 +1,63 @@
<div class="modal" id="addAccountModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-piggy-bank mr-2"></i>New Account</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<div class="modal-body">
<div class="form-group">
<label>Account Name <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-piggy-bank"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Account name" maxlength="200" required autofocus>
</div>
</div>
<div class="form-group">
<label>Opening Balance <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-dollar-sign"></i></span>
</div>
<input type="text" class="form-control" inputmode="numeric" pattern="-?[0-9]*\.?[0-9]{0,2}" name="opening_balance" placeholder="0.00" required>
</div>
</div>
<div class="form-group">
<label>Currency <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-money-bill"></i></span>
</div>
<select class="form-control select2" name="currency_code" required>
<option value="">- Currency -</option>
<?php foreach ($currencies_array as $currency_code => $currency_name) { ?>
<option <?php if ($session_company_currency == $currency_code) { echo "selected"; } ?> value="<?php echo $currency_code; ?>"><?php echo "$currency_code - $currency_name"; ?></option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group">
<label>Notes</label>
<textarea class="form-control" rows="5" placeholder="Enter some notes" name="notes"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="add_account" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,51 @@
<?php
require_once '../../../includes/modal_header.php';
$account_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_id = $account_id LIMIT 1");
$row = mysqli_fetch_array($sql);
$account_name = nullable_htmlentities($row['account_name']);
$account_notes = nullable_htmlentities($row['account_notes']);
// Generate the HTML form content using output buffering.
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-piggy-bank mr-2"></i>Editing account: <strong><?php echo $account_name; ?></strong></h5>
<button type="button" class="close text-light" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="account_id" value="<?php echo $account_id; ?>">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<div class="modal-body">
<div class="form-group">
<label>Account Name <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-piggy-bank"></i></span>
</div>
<input type="text" class="form-control" name="name" maxlength="200" value="<?php echo $account_name; ?>" required>
</div>
</div>
<div class="form-group">
<label>Notes</label>
<textarea class="form-control" rows="5" placeholder="Enter some notes" name="notes"><?php echo $account_notes; ?></textarea>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="edit_account" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</form>
<?php
require_once '../../../includes/modal_footer.php';

View File

@@ -0,0 +1,455 @@
<div class="modal" id="addAssetModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-desktop mr-2"></i>New <?php if (!empty($_GET['type'])) { echo ucwords(strip_tags($_GET['type'])); }else{ echo "Asset"; } ?></h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<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="modal-body ui-front">
<ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-asset-details">Details</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-asset-network">Network</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-asset-assignment">Assignment</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-asset-purchase">Purchase</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-asset-login">Login</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-asset-notes">Notes</a>
</li>
</ul>
<hr>
<div class="tab-content">
<div class="tab-pane fade show active" id="pills-asset-details">
<?php if ($client_url) { ?>
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<?php } else { ?>
<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-user"></i></span>
</div>
<select class="form-control select2" name="client_id" required>
<option value="">- Select Client -</option>
<?php
$sql = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE client_archived_at IS NULL $access_permission_query ORDER BY client_name ASC");
while ($row = mysqli_fetch_array($sql)) {
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']); ?>
<option <?php if ($client_id == isset($_GET['client'])) { echo "selected"; } ?> value="<?php echo $client_id; ?>"><?php echo $client_name; ?></option>
<?php } ?>
</select>
</div>
</div>
<?php } ?>
<div class="form-group">
<label>Name <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-tag"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Asset name or asset tag" maxlength="200" required autofocus>
</div>
</div>
<div class="form-group">
<label>Description</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
</div>
<input type="text" class="form-control" name="description" placeholder="Description of the asset" maxlength="255">
</div>
</div>
<div class="form-group">
<label>Type <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-tags"></i></span>
</div>
<select class="form-control select2" name="type" required>
<option value="">- Select Type -</option>
<?php foreach($asset_types_array as $asset_type => $asset_icon) { ?>
<option><?php echo $asset_type; ?></option>
<?php } ?>
</select>
</div>
</div>
<?php //Do not display Make Model or Serial if Virtual is selected
if ($_GET['type'] !== 'virtual') { ?>
<div class="form-group">
<label>Make</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
</div>
<input type="text" class="form-control" name="make" placeholder="Manufacturer" maxlength="200">
</div>
</div>
<div class="form-group">
<label>Model</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
</div>
<input type="text" class="form-control" name="model" placeholder="Model Number" maxlength="200">
</div>
</div>
<div class="form-group">
<label>Serial Number</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span>
</div>
<input type="text" class="form-control" name="serial" placeholder="Serial number" maxlength="200">
</div>
</div>
<?php } ?>
<?php if ($_GET['type'] !== 'network' && $_GET['type'] !== 'other') { ?>
<div class="form-group">
<label>Operating System</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fab fa-fw fa-windows"></i></span>
</div>
<input type="text" class="form-control" name="os" id="os" placeholder="ex Windows 10 Pro" maxlength="200">
</div>
</div>
<?php } ?>
</div>
<div class="tab-pane fade" id="pills-asset-network">
<?php if ($client_url) { ?>
<div class="form-group">
<label>Network</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-network-wired"></i></span>
</div>
<select class="form-control select2" name="network">
<option value="">- Select Network -</option>
<?php
$sql = mysqli_query($mysqli, "SELECT * FROM networks WHERE network_archived_at IS NULL AND network_client_id = $client_id ORDER BY network_name ASC");
while ($row = mysqli_fetch_array($sql)) {
$network_id = intval($row['network_id']);
$network_name = nullable_htmlentities($row['network_name']);
$network = nullable_htmlentities($row['network']);
?>
<option value="<?php echo $network_id; ?>"><?php echo $network_name; ?> - <?php echo $network; ?></option>
<?php } ?>
</select>
</div>
</div>
<?php } ?>
<div class="form-group">
<label>IP Address or DHCP</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
</div>
<input type="text" class="form-control" name="ip" placeholder="192.168.10.250" data-inputmask="'alias': 'ip'" data-mask>
<div class="input-group-append">
<div class="input-group-text">
<input type="checkbox" name="dhcp" value="1">
</div>
</div>
</div>
</div>
<div class="form-group">
<label>NAT IP Address</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-random"></i></span>
</div>
<input type="text" class="form-control" name="nat_ip" placeholder="10.52.4.55" data-inputmask="'alias': 'ip'" maxlength="200" data-mask>
</div>
</div>
<div class="form-group">
<label>IPv6 Address</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
</div>
<input type="text" class="form-control" name="ipv6" placeholder="ex. 2001:0db8:0000:0000:0000:ff00:0042:8329" maxlength="200">
</div>
</div>
<div class="form-group">
<label>MAC Address</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
</div>
<input type="text" class="form-control" name="mac" placeholder="MAC Address" data-inputmask="'alias': 'mac'" maxlength="200" data-mask>
</div>
</div>
<div class="form-group">
<label>URI</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span>
</div>
<input type="text" class="form-control" name="uri" placeholder="URI http:// ftp:// ssh: etc" maxlength="500">
</div>
</div>
<div class="form-group">
<label>URI 2</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span>
</div>
<input type="text" class="form-control" name="uri_2" placeholder="URI http:// ftp:// ssh: etc" maxlength="500">
</div>
</div>
<div class="form-group">
<label>Client URI</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span>
</div>
<input type="text" class="form-control" name="uri_client" placeholder="URI http:// ftp:// ssh: etc -- viewable in Client Portal" maxlength="500">
</div>
</div>
</div>
<div class="tab-pane fade" id="pills-asset-assignment">
<div class="form-group">
<label>Physical Location</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-map-marker-alt"></i></span>
</div>
<input type="text" class="form-control" name="physical_location" placeholder="Physical location eg. Floor 2, Closet B" maxlength="200">
</div>
</div>
<?php if ($client_url) { ?>
<div class="form-group">
<label>Location</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-map-marker-alt"></i></span>
</div>
<select class="form-control select2" name="location">
<option value="">- Select Location -</option>
<?php
$sql = mysqli_query($mysqli, "SELECT * FROM locations WHERE location_archived_at IS NULL AND location_client_id = $client_id ORDER BY location_name ASC");
while ($row = mysqli_fetch_array($sql)) {
$location_id = intval($row['location_id']);
$location_name = nullable_htmlentities($row['location_name']);
?>
<option value="<?php echo $location_id; ?>"><?php echo $location_name; ?></option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group">
<label>Assign To</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<select class="form-control select2" name="contact">
<option value="">- Select Contact -</option>
<?php
$sql = mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_archived_at IS NULL AND contact_client_id = $client_id ORDER BY contact_name ASC");
while ($row = mysqli_fetch_array($sql)) {
$contact_id = intval($row['contact_id']);
$contact_name = nullable_htmlentities($row['contact_name']);
?>
<option
<?php if (isset($_GET['contact_id']) && $contact_id == intval($_GET['contact_id'])) {
echo "selected"; }
?>
value="<?php echo $contact_id; ?>"><?php echo $contact_name; ?>
</option>
<?php } ?>
</select>
</div>
</div>
<?php } ?>
<div class="form-group">
<label>Status</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-info"></i></span>
</div>
<select class="form-control select2" name="status">
<option value="">- Select Status -</option>
<?php foreach($asset_status_array as $asset_status) { ?>
<option><?php echo $asset_status; ?></option>
<?php } ?>
</select>
</div>
</div>
</div>
<div class="tab-pane fade" id="pills-asset-purchase">
<?php if ($client_url) { ?>
<div class="form-group">
<label>Vendor</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-building"></i></span>
</div>
<select class="form-control select2" name="vendor">
<option value="">- Select Vendor -</option>
<?php
$sql = mysqli_query($mysqli, "SELECT * FROM vendors WHERE vendor_archived_at IS NULL AND vendor_client_id = $client_id ORDER BY vendor_name ASC");
while ($row = mysqli_fetch_array($sql)) {
$vendor_id = intval($row['vendor_id']);
$vendor_name = nullable_htmlentities($row['vendor_name']);
?>
<option value="<?php echo $vendor_id; ?>"><?php echo $vendor_name; ?></option>
<?php } ?>
</select>
</div>
</div>
<?php } ?>
<?php if ($_GET['type'] !== 'virtual') { ?>
<div class="form-group">
<label>Purchase Reference</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-shopping-cart"></i></span>
</div>
<input type="text" class="form-control" name="purchase_reference" placeholder="eg. Invoice, PO Number">
</div>
</div>
<div class="form-group">
<label>Purchase Date</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="date" class="form-control" name="purchase_date" max="2999-12-31">
</div>
</div>
<?php } ?>
<div class="form-group">
<label>Install Date</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar-check"></i></span>
</div>
<input type="date" class="form-control" name="install_date" max="2999-12-31">
</div>
</div>
<?php if ($_GET['type'] !== 'virtual') { ?>
<div class="form-group">
<label>Warranty Expire</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar-times"></i></span>
</div>
<input type="date" class="form-control" name="warranty_expire" max="2999-12-31">
</div>
</div>
<?php } ?>
</div>
<div class="tab-pane fade" id="pills-asset-login">
<div class="form-group">
<label>Username</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<input type="text" class="form-control" name="username" placeholder="Username">
</div>
</div>
<div class="form-group">
<label>Password</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span>
</div>
<input type="text" class="form-control" name="password" placeholder="Password" autocomplete="off">
</div>
</div>
</div>
<div class="tab-pane fade" id="pills-asset-notes">
<div class="form-group">
<label>Upload Photo</label>
<input type="file" class="form-control-file" name="file" accept="image/*">
</div>
<div class="form-group">
<textarea class="form-control" rows="8" placeholder="Enter some notes" name="notes"></textarea>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="add_asset" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,134 @@
<div class="modal" id="bulkAddTicketModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-life-ring mr-2"></i>Creating Tickets for Assets</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label>Subject <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-tag"></i></span>
</div>
<input type="text" class="form-control" name="bulk_subject" placeholder="Asset Name will be prepended to Subject" maxlength="200">
</div>
</div>
<div class="form-group">
<textarea class="form-control tinymceTicket<?php if($config_ai_enable) { echo "AI"; } ?>" id="textInput" name="bulk_details"></textarea>
</div>
<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="bulk_priority">
<option>Low</option>
<option>Medium</option>
<option>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="bulk_category">
<option value="0">- Not Categorized -</option>
<?php
$sql_categories = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Ticket' AND 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 value="<?php echo $category_id; ?>"><?php echo $category_name; ?></option>
<?php } ?>
</select>
</div>
</div>
</div>
</div>
<div class="form-group">
<label>Assign to</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user-check"></i></span>
</div>
<select class="form-control select2" name="bulk_assigned_to">
<option value="0">Not Assigned</option>
<?php
$sql = mysqli_query(
$mysqli,
"SELECT user_id, user_name FROM users
WHERE user_role_id > 1 AND user_status = 1 AND user_archived_at IS NULL ORDER BY user_name ASC"
);
while ($row = mysqli_fetch_array($sql)) {
$user_id = intval($row['user_id']);
$user_name = nullable_htmlentities($row['user_name']); ?>
<option <?php if ($session_user_id == $user_id) { echo "selected"; } ?> value="<?php echo $user_id; ?>"><?php echo $user_name; ?></option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group">
<label>Project</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-project-diagram"></i></span>
</div>
<select class="form-control select2" name="bulk_project">
<option value="0">- None -</option>
<?php
$sql_projects = mysqli_query($mysqli, "SELECT * FROM projects WHERE project_completed_at IS NULL AND project_archived_at IS NULL ORDER BY project_name ASC");
while ($row = mysqli_fetch_array($sql_projects)) {
$project_id_select = intval($row['project_id']);
$project_name_select = nullable_htmlentities($row['project_name']); ?>
<option value="<?php echo $project_id_select; ?>"><?php echo $project_name_select; ?></option>
<?php } ?>
</select>
</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="bulk_billable" <?php if ($config_ticket_default_billable == 1) { echo "checked"; } ?> value="1" id="billableSwitch">
<label class="custom-control-label" for="billableSwitch">Billable</label>
</div>
</div>
<?php } ?>
</div>
<div class="modal-footer">
<button type="submit" name="bulk_add_asset_ticket" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,44 @@
<div class="modal" id="bulkAssignContactModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-user-check mr-2"></i>Bulk Assign Contact</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label>Assign To</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<select class="form-control select2" name="bulk_contact_id">
<option value="">- Contact -</option>
<?php
$sql = mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_archived_at IS NULL AND contact_client_id = $client_id ORDER BY contact_name ASC");
while ($row = mysqli_fetch_array($sql)) {
$contact_id = intval($row['contact_id']);
$contact_name = nullable_htmlentities($row['contact_name']);
?>
<option value="<?php echo $contact_id; ?>"><?php echo $contact_name; ?></option>
<?php } ?>
</select>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="bulk_assign_asset_contact" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Assign</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,43 @@
<div class="modal" id="bulkAssignLocationModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-map-marker-alt mr-2"></i>Bulk Assign Location</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label>Location</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-map-marker-alt"></i></span>
</div>
<select class="form-control select2" name="bulk_location_id">
<option value="">- Location -</option>
<?php
$sql = mysqli_query($mysqli, "SELECT location_id, location_name FROM locations WHERE location_archived_at IS NULL AND location_client_id = $client_id ORDER BY location_name ASC");
while ($row = mysqli_fetch_array($sql)) {
$location_id = intval($row['location_id']);
$location_name = nullable_htmlentities($row['location_name']);
?>
<option value="<?php echo $location_id; ?>"><?php echo $location_name; ?></option>
<?php } ?>
</select>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="bulk_assign_asset_location" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Assign</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,31 @@
<div class="modal" id="bulkAssignPhysicalLocationModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-map-marker-alt mr-2"></i>Bulk Set Physical Location</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label>Physical Location</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-map-marker-alt"></i></span>
</div>
<input type="text" class="form-control" name="physical_location" placeholder="Physical location eg. Floor 2, Closet B" maxlength="200">
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="bulk_assign_asset_physical_location" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Assign</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,36 @@
<div class="modal" id="bulkEditStatusModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-info mr-2"></i>Bulk Edit Status</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label>Status</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-info"></i></span>
</div>
<select class="form-control select2" name="bulk_status">
<option value="">- Status -</option>
<?php foreach($asset_status_array as $asset_status) { ?>
<option><?php echo $asset_status; ?></option>
<?php } ?>
</select>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="bulk_edit_asset_status" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Set</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,56 @@
<?php
if ($client_url) {
$client_select_query = "AND client_id != $client_id";
} else {
$client_select_query = '';
}
?>
<div class="modal" id="bulkTransferAssetClientModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-exchange mr-2"></i>Transferring Asset(s)</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label>New 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="bulk_client_id">
<option value="">- Select Client -</option>
<?php
$clients_sql = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE client_archived_at IS NULL $client_select_query");
while ($row = mysqli_fetch_array($clients_sql)) {
$client_id_select = intval($row["client_id"]);
$client_name_select = nullable_htmlentities($row["client_name"]);
?>
<option value='<?php echo $client_id_select; ?>'><?php echo $client_name_select; ?></option>
<?php
}
?>
</select>
</div>
</div>
<div class="alert alert-dark" role="alert">
<i>The current asset will be archived and content copied to a new asset.</i>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="bulk_transfer_client_asset" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Transfer</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,446 @@
<?php
require_once '../../../includes/modal_header.php';
$asset_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM assets
LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1
WHERE asset_id = $asset_id LIMIT 1"
);
$row = mysqli_fetch_array($sql);
$client_id = intval($row['asset_client_id']);
$asset_id = intval($row['asset_id']);
$asset_type = nullable_htmlentities($row['asset_type']);
$asset_name = nullable_htmlentities($row['asset_name']);
$asset_description = nullable_htmlentities($row['asset_description']);
$asset_make = nullable_htmlentities($row['asset_make']);
$asset_model = nullable_htmlentities($row['asset_model']);
$asset_serial = nullable_htmlentities($row['asset_serial']);
$asset_os = nullable_htmlentities($row['asset_os']);
$asset_ip = nullable_htmlentities($row['interface_ip']);
$asset_ipv6 = nullable_htmlentities($row['interface_ipv6']);
$asset_nat_ip = nullable_htmlentities($row['interface_nat_ip']);
$asset_mac = nullable_htmlentities($row['interface_mac']);
$asset_uri = nullable_htmlentities($row['asset_uri']);
$asset_uri_2 = nullable_htmlentities($row['asset_uri_2']);
$asset_status = nullable_htmlentities($row['asset_status']);
$asset_purchase_date = nullable_htmlentities($row['asset_purchase_date']);
$asset_warranty_expire = nullable_htmlentities($row['asset_warranty_expire']);
$asset_install_date = nullable_htmlentities($row['asset_install_date']);
$asset_photo = nullable_htmlentities($row['asset_photo']);
$asset_physical_location = nullable_htmlentities($row['asset_physical_location']);
$asset_notes = nullable_htmlentities($row['asset_notes']);
$asset_created_at = nullable_htmlentities($row['asset_created_at']);
$asset_archived_at = nullable_htmlentities($row['asset_archived_at']);
$asset_vendor_id = intval($row['asset_vendor_id']);
$asset_location_id = intval($row['asset_location_id']);
$asset_contact_id = intval($row['asset_contact_id']);
$asset_network_id = intval($row['interface_network_id']);
$device_icon = getAssetIcon($asset_type);
// Generate the HTML form content using output buffering.
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class='fa fa-fw fa-<?php echo $device_icon; ?> mr-2'></i>Copying asset: <strong><?php echo $asset_name; ?></strong></h5>
<button type="button" class="close text-light" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<div class="modal-body">
<ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pillsDetailsCopy<?php echo $asset_id; ?>">Details</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pillsNetworkCopy<?php echo $asset_id; ?>">Network</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pillsAssignmentCopy<?php echo $asset_id; ?>">Assignment</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pillsPurchaseCopy<?php echo $asset_id; ?>">Purchase</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pillsLoginCopy<?php echo $asset_id; ?>">Login</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pillsNotesCopy<?php echo $asset_id; ?>">Notes</a>
</li>
</ul>
<hr>
<div class="tab-content">
<div class="tab-pane fade show active" id="pillsDetailsCopy<?php echo $asset_id; ?>">
<div class="form-group">
<label>Name <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-tag"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Name the asset" value="<?php echo $asset_name; ?>" required>
</div>
</div>
<div class="form-group">
<label>Description</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
</div>
<input type="text" class="form-control" name="description" placeholder="Description of the asset" value="<?php echo $asset_description; ?>">
</div>
</div>
<div class="form-group">
<label>Type <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-tags"></i></span>
</div>
<select class="form-control select2" name="type" required>
<?php foreach($asset_types_array as $asset_type_select => $asset_icon_select) { ?>
<option <?php if ($asset_type_select == $asset_type) { echo "selected"; } ?>><?php echo $asset_type_select; ?></option>
<?php } ?>
</select>
</div>
</div>
<?php //Do not display Make Model or Serial if Virtual is selected
if ($asset_type !== 'virtual') { ?>
<div class="form-group">
<label>Make </label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
</div>
<input type="text" class="form-control" name="make" placeholder="Manufacturer" value="<?php echo $asset_make; ?>">
</div>
</div>
<div class="form-group">
<label>Model</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
</div>
<input type="text" class="form-control" name="model" placeholder="Model Number" value="<?php echo $asset_model; ?>">
</div>
</div>
<div class="form-group">
<label>Serial Number</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span>
</div>
<input type="text" class="form-control" name="serial" placeholder="Serial number">
</div>
</div>
<?php } ?>
<?php if ($asset_type !== 'Phone' && $asset_type !== 'Mobile Phone' && $asset_type !== 'Tablet' && $asset_type !== 'Access Point' && $asset_type !== 'Printer' && $asset_type !== 'Camera' && $asset_type !== 'TV' && $asset_type !== 'Other') { ?>
<div class="form-group">
<label>Operating System</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fab fa-fw fa-windows"></i></span>
</div>
<input type="text" class="form-control" name="os" placeholder="ex Windows 10 Pro" value="<?php echo $asset_os; ?>">
</div>
</div>
<?php } ?>
</div>
<div class="tab-pane fade" id="pillsNetworkCopy<?php echo $asset_id; ?>">
<div class="form-group">
<label>Network</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-network-wired"></i></span>
</div>
<select class="form-control select2" name="network">
<option value="">- Select Network -</option>
<?php
$sql_networks = mysqli_query($mysqli, "SELECT * FROM networks WHERE network_archived_at IS NULL AND network_client_id = $client_id ORDER BY network_name ASC");
while ($row = mysqli_fetch_array($sql_networks)) {
$network_id_select = intval($row['network_id']);
$network_name_select = nullable_htmlentities($row['network_name']);
$network_select = nullable_htmlentities($row['network']);
?>
<option <?php if ($asset_network_id == $network_id_select) { echo "selected"; } ?> value="<?php echo $network_id_select; ?>"><?php echo $network_name_select; ?> - <?php echo $network_select; ?></option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group">
<label>IP Address or DHCP</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
</div>
<input type="text" class="form-control" name="ip" placeholder="192.168.10.250" data-inputmask="'alias': 'ip'" data-mask>
<div class="input-group-append">
<div class="input-group-text">
<input type="checkbox" name="dhcp" value="1" <?php if($asset_ip == 'DHCP'){ echo "checked"; } ?>>
</div>
</div>
</div>
</div>
<div class="form-group">
<label>NAT IP</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-random"></i></span>
</div>
<input type="text" class="form-control" name="nat_ip" placeholder="10.52.4.55" data-inputmask="'alias': 'ip'" data-mask>
</div>
</div>
<div class="form-group">
<label>IPv6 Address</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
</div>
<input type="text" class="form-control" name="ipv6" value="<?php echo $asset_ipv6; ?>" placeholder="ex. 2001:0db8:0000:0000:0000:ff00:0042:8329">
</div>
</div>
<div class="form-group">
<label>MAC Address</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
</div>
<input type="text" class="form-control" name="mac" placeholder="MAC Address" data-inputmask="'alias': 'mac'" data-mask>
</div>
</div>
<div class="form-group">
<label>URI</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span>
</div>
<input type="text" class="form-control" name="uri" placeholder="URI http:// ftp:// ssh: etc">
</div>
</div>
<div class="form-group">
<label>URI 2</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span>
</div>
<input type="text" class="form-control" name="uri_2" placeholder="URI http:// ftp:// ssh: etc">
</div>
</div>
</div>
<div class="tab-pane fade" id="pillsAssignmentCopy<?php echo $asset_id; ?>">
<div class="form-group">
<label>Physical Location</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-map-marker-alt"></i></span>
</div>
<input type="text" class="form-control" name="physical_location" placeholder="Physical location eg. Floor 2, Closet B">
</div>
</div>
<div class="form-group">
<label>Location</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-map-marker-alt"></i></span>
</div>
<select class="form-control select2" name="location">
<option value="">- Select Location -</option>
<?php
$sql_locations = mysqli_query($mysqli, "SELECT * FROM locations WHERE location_archived_at IS NULL AND location_client_id = $client_id ORDER BY location_name ASC");
while ($row = mysqli_fetch_array($sql_locations)) {
$location_id_select = intval($row['location_id']);
$location_name_select = nullable_htmlentities($row['location_name']);
?>
<option <?php if ($asset_location_id == $location_id_select) { echo "selected"; } ?> value="<?php echo $location_id_select; ?>"><?php echo $location_name_select; ?></option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group">
<label>Assign To</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<select class="form-control select2" name="contact">
<option value="">- Select Contact -</option>
<?php
$sql_contacts = mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_archived_at IS NULL AND contact_client_id = $client_id ORDER BY contact_name ASC");
while ($row = mysqli_fetch_array($sql_contacts)) {
$contact_id_select = intval($row['contact_id']);
$contact_name_select = nullable_htmlentities($row['contact_name']);
?>
<option value="<?php echo $contact_id_select; ?>"><?php echo $contact_name_select; ?></option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group">
<label>Status</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-info"></i></span>
</div>
<select class="form-control select2" name="status">
<?php foreach($asset_status_array as $asset_status_select) { ?>
<option <?php if ($asset_status_select == $asset_status) { echo "selected"; } ?>><?php echo $asset_status_select; ?></option>
<?php } ?>
</select>
</div>
</div>
</div>
<div class="tab-pane fade" id="pillsPurchaseCopy<?php echo $asset_id; ?>">
<div class="form-group">
<label>Vendor</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-building"></i></span>
</div>
<select class="form-control select2" name="vendor">
<option value="">- Select Vendor -</option>
<?php
$sql_vendors = mysqli_query($mysqli, "SELECT * FROM vendors WHERE vendor_archived_at IS NULL AND vendor_client_id = $client_id ORDER BY vendor_name ASC");
while ($row = mysqli_fetch_array($sql_vendors)) {
$vendor_id_select = intval($row['vendor_id']);
$vendor_name_select = nullable_htmlentities($row['vendor_name']);
?>
<option <?php if ($asset_vendor_id == $vendor_id_select) { echo "selected"; } ?> value="<?php echo $vendor_id_select; ?>"><?php echo $vendor_name_select; ?></option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group">
<label>Install Date</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar-check"></i></span>
</div>
<input type="date" class="form-control" name="install_date" max="2999-12-31" value="<?php echo $asset_install_date; ?>">
</div>
</div>
<?php if ($asset_type !== 'Virtual Machine') { ?>
<div class="form-group">
<label>Purchase Reference</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-shopping-cart"></i></span>
</div>
<input type="text" class="form-control" name="purchase_reference" placeholder="eg. Invoice, PO Number" >
</div>
</div>
<div class="form-group">
<label>Purchase Date</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-shopping-cart"></i></span>
</div>
<input type="date" class="form-control" name="purchase_date" max="2999-12-31" value="<?php echo $asset_purchase_date; ?>">
</div>
</div>
<div class="form-group">
<label>Warranty Expire</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar-times"></i></span>
</div>
<input type="date" class="form-control" name="warranty_expire" max="2999-12-31" value="<?php echo $asset_warranty_expire; ?>">
</div>
</div>
<?php } ?>
</div>
<div class="tab-pane fade" id="pillsLoginCopy<?php echo $asset_id; ?>">
<div class="form-group">
<label>Username</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<input type="text" class="form-control" name="username" placeholder="Username">
</div>
</div>
<div class="form-group">
<label>Password</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span>
</div>
<input type="text" class="form-control" name="password" placeholder="Password" autocomplete="off">
</div>
</div>
</div>
<div class="tab-pane fade" id="pillsNotesCopy<?php echo $asset_id; ?>">
<div class="form-group">
<label>Upload Photo</label>
<input type="file" class="form-control-file" name="file">
</div>
<div class="form-group">
<textarea class="form-control" rows="8" placeholder="Enter some notes" name="notes"><?php echo $asset_notes; ?></textarea>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="add_asset" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Copy</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</form>
<?php
require_once '../../../includes/modal_footer.php';

View File

@@ -0,0 +1,865 @@
<?php
require_once '../../../includes/modal_header.php';
$asset_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM assets
LEFT JOIN clients ON client_id = asset_client_id
LEFT JOIN contacts ON asset_contact_id = contact_id
LEFT JOIN locations ON asset_location_id = location_id
LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1
WHERE asset_id = $asset_id
LIMIT 1
");
$row = mysqli_fetch_array($sql);
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
$asset_id = intval($row['asset_id']);
$asset_type = nullable_htmlentities($row['asset_type']);
$asset_name = nullable_htmlentities($row['asset_name']);
$asset_description = nullable_htmlentities($row['asset_description']);
$asset_make = nullable_htmlentities($row['asset_make']);
$asset_model = nullable_htmlentities($row['asset_model']);
$asset_serial = nullable_htmlentities($row['asset_serial']);
$asset_os = nullable_htmlentities($row['asset_os']);
$asset_uri = sanitize_url($row['asset_uri']);
$asset_uri_2 = sanitize_url($row['asset_uri_2']);
$asset_uri_client = sanitize_url($row['asset_uri_client']);
$asset_status = nullable_htmlentities($row['asset_status']);
$asset_purchase_reference = nullable_htmlentities($row['asset_purchase_reference']);
$asset_purchase_date = nullable_htmlentities($row['asset_purchase_date']);
$asset_warranty_expire = nullable_htmlentities($row['asset_warranty_expire']);
$asset_install_date = nullable_htmlentities($row['asset_install_date']);
$asset_photo = nullable_htmlentities($row['asset_photo']);
$asset_physical_location = nullable_htmlentities($row['asset_physical_location']);
$asset_notes = nullable_htmlentities($row['asset_notes']);
$asset_created_at = nullable_htmlentities($row['asset_created_at']);
$asset_vendor_id = intval($row['asset_vendor_id']);
$asset_location_id = intval($row['asset_location_id']);
$asset_contact_id = intval($row['asset_contact_id']);
$asset_ip = nullable_htmlentities($row['interface_ip']);
$asset_ipv6 = nullable_htmlentities($row['interface_ipv6']);
$asset_nat_ip = nullable_htmlentities($row['interface_nat_ip']);
$asset_mac = nullable_htmlentities($row['interface_mac']);
$asset_network_id = intval($row['interface_network_id']);
$device_icon = getAssetIcon($asset_type);
$contact_name = nullable_htmlentities($row['contact_name']);
$contact_email = nullable_htmlentities($row['contact_email']);
$contact_phone = nullable_htmlentities($row['contact_phone']);
$contact_extension = nullable_htmlentities($row['contact_extension']);
$contact_mobile = nullable_htmlentities($row['contact_mobile']);
$contact_archived_at = nullable_htmlentities($row['contact_archived_at']);
if ($contact_archived_at) {
$contact_name_display = "<span class='text-danger' title='Archived'><s>$contact_name</s></span>";
} else {
$contact_name_display = $contact_name;
}
$location_name = nullable_htmlentities($row['location_name']);
if (empty($location_name)) {
$location_name = "-";
}
$location_archived_at = nullable_htmlentities($row['location_archived_at']);
if ($location_archived_at) {
$location_name_display = "<span class='text-danger' title='Archived'><s>$location_name</s></span>";
} else {
$location_name_display = $location_name;
}
// Network Interfaces
$sql_related_interfaces = mysqli_query($mysqli, "
SELECT
ai.interface_id,
ai.interface_name,
ai.interface_description,
ai.interface_type,
ai.interface_mac,
ai.interface_ip,
ai.interface_nat_ip,
ai.interface_ipv6,
ai.interface_primary,
ai.interface_notes,
n.network_name,
n.network_id,
connected_interfaces.interface_id AS connected_interface_id,
connected_interfaces.interface_name AS connected_interface_name,
connected_assets.asset_name AS connected_asset_name,
connected_assets.asset_id AS connected_asset_id,
connected_assets.asset_type AS connected_asset_type
FROM asset_interfaces AS ai
LEFT JOIN networks AS n
ON n.network_id = ai.interface_network_id
LEFT JOIN asset_interface_links AS ail
ON (ail.interface_a_id = ai.interface_id OR ail.interface_b_id = ai.interface_id)
LEFT JOIN asset_interfaces AS connected_interfaces
ON (
(ail.interface_a_id = ai.interface_id AND ail.interface_b_id = connected_interfaces.interface_id)
OR
(ail.interface_b_id = ai.interface_id AND ail.interface_a_id = connected_interfaces.interface_id)
)
LEFT JOIN assets AS connected_assets
ON connected_assets.asset_id = connected_interfaces.interface_asset_id
WHERE
ai.interface_asset_id = $asset_id
AND ai.interface_archived_at IS NULL
ORDER BY ai.interface_name ASC
");
$interface_count = mysqli_num_rows($sql_related_interfaces);
// Related Credentials Query
$sql_related_credentials = mysqli_query($mysqli, "
SELECT
credentials.credential_id AS credential_id,
credentials.credential_name,
credentials.credential_description,
credentials.credential_uri,
credentials.credential_username,
credentials.credential_password,
credentials.credential_otp_secret,
credentials.credential_note,
credentials.credential_important,
credentials.credential_contact_id,
credentials.credential_asset_id
FROM credentials
LEFT JOIN credential_tags ON credential_tags.credential_id = credentials.credential_id
LEFT JOIN tags ON tags.tag_id = credential_tags.tag_id
WHERE credential_asset_id = $asset_id
AND credential_archived_at IS NULL
GROUP BY credentials.credential_id
ORDER BY credential_name DESC
");
$credential_count = mysqli_num_rows($sql_related_credentials);
// Related Tickets Query
$sql_related_tickets = mysqli_query($mysqli, "
SELECT tickets.*, users.*, ticket_statuses.*
FROM tickets
LEFT JOIN users ON ticket_assigned_to = user_id
LEFT JOIN ticket_statuses ON ticket_status_id = ticket_status
LEFT JOIN ticket_assets ON tickets.ticket_id = ticket_assets.ticket_id
WHERE ticket_asset_id = $asset_id OR ticket_assets.asset_id = $asset_id
GROUP BY tickets.ticket_id
ORDER BY ticket_number DESC
");
$ticket_count = mysqli_num_rows($sql_related_tickets);
// Related Recurring Tickets Query
$sql_related_recurring_tickets = mysqli_query($mysqli, "SELECT * FROM recurring_tickets
LEFT JOIN recurring_ticket_assets ON recurring_tickets.recurring_ticket_id = recurring_ticket_assets.recurring_ticket_id
WHERE recurring_ticket_asset_id = $asset_id OR recurring_ticket_assets.asset_id = $asset_id
GROUP BY recurring_tickets.recurring_ticket_id
ORDER BY recurring_ticket_next_run DESC"
);
$recurring_ticket_count = mysqli_num_rows($sql_related_recurring_tickets);
// Related Documents
$sql_related_documents = mysqli_query($mysqli, "SELECT * FROM asset_documents
LEFT JOIN documents ON asset_documents.document_id = documents.document_id
LEFT JOIN users ON user_id = document_created_by
WHERE asset_documents.asset_id = $asset_id
AND document_archived_at IS NULL
ORDER BY document_name DESC"
);
$document_count = mysqli_num_rows($sql_related_documents);
// Related Files
$sql_related_files = mysqli_query($mysqli, "SELECT * FROM asset_files
LEFT JOIN files ON asset_files.file_id = files.file_id
WHERE asset_files.asset_id = $asset_id
AND file_archived_at IS NULL
ORDER BY file_name DESC"
);
$file_count = mysqli_num_rows($sql_related_files);
// Related Software Query
$sql_related_software = mysqli_query(
$mysqli,
"SELECT * FROM software_assets
LEFT JOIN software ON software_assets.software_id = software.software_id
WHERE software_assets.asset_id = $asset_id
AND software_archived_at IS NULL
ORDER BY software_name DESC"
);
$software_count = mysqli_num_rows($sql_related_software);
if (isset($_GET['client_id'])) {
$client_url = "client_id=$client_id&";
} else {
$client_url = '';
}
// Generate the HTML form content using output buffering.
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-<?php echo $device_icon; ?> mr-2"></i><strong><?php echo $asset_name; ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-asset-details<?php echo $asset_id; ?>"><i class="fas fa-fw fa-<?php echo $device_icon; ?> fa-2x"></i><br>Details</a>
</li>
<?php if ($interface_count) { ?>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-asset-interfaces<?php echo $asset_id; ?>"><i class="fas fa-fw fa-ethernet fa-2x"></i><br>Interfaces (<?php echo $interface_count; ?>)</a>
</li>
<?php } ?>
<?php if ($credential_count) { ?>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-asset-credentials<?php echo $asset_id; ?>"><i class="fas fa-fw fa-key fa-2x"></i><br>Credentials (<?php echo $credential_count; ?>)</a>
</li>
<?php } ?>
<?php if ($ticket_count) { ?>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-asset-tickets<?php echo $asset_id; ?>"><i class="fas fa-fw fa-life-ring fa-2x"></i><br>Tickets (<?php echo $ticket_count; ?>)</a>
</li>
<?php } ?>
<?php if ($recurring_ticket_count) { ?>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-asset-recurring-tickets<?php echo $asset_id; ?>"><i class="fas fa-fw fa-redo-alt fa-2x"></i><br>Recurring Tickets (<?php echo $recurring_ticket_count; ?>)</a>
</li>
<?php } ?>
<?php if ($software_count) { ?>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-asset-licenses<?php echo $asset_id; ?>"><i class="fas fa-fw fa-cube fa-2x"></i><br>Licenses (<?php echo $software_count; ?>)</a>
</li>
<?php } ?>
<?php if ($document_count) { ?>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-asset-documents<?php echo $asset_id; ?>"><i class="fas fa-fw fa-file-alt fa-2x"></i><br>Documents (<?php echo $document_count; ?>)</a>
</li>
<?php } ?>
<?php if ($file_count) { ?>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-asset-files<?php echo $asset_id; ?>"><i class="fas fa-fw fa-briefcase fa-2x"></i><br>Files (<?php echo $file_count; ?>)</a>
</li>
<?php } ?>
</ul>
<hr>
<div class="tab-content">
<div class="tab-pane fade show active" id="pills-asset-details<?php echo $asset_id; ?>">
<div class="card">
<div class="card-header">
<h3 class="text-bold"><i class="fa fa-fw text-secondary fa-<?php echo $device_icon; ?> mr-3"></i><?php echo $asset_name; ?></h3>
<?php if ($asset_photo) { ?>
<img class="img-fluid img-circle p-3" alt="asset_photo" src="<?php echo "../uploads/clients/$client_id/$asset_photo"; ?>">
<?php } ?>
<?php if ($asset_description) { ?>
<div class="text-secondary"><?php echo $asset_description; ?></div>
<?php } ?>
</div>
<div class="card-body">
<?php if ($asset_type) { ?>
<div><i class="fa fa-fw fa-tag text-secondary mr-2"></i><?php echo $asset_type; ?></div>
<?php }
if ($asset_make) { ?>
<div class="mt-2"><i class="fa fa-fw fa-circle text-secondary mr-2"></i><?php echo "$asset_make $asset_model"; ?></div>
<?php }
if ($asset_os) { ?>
<div class="mt-2"><i class="fab fa-fw fa-windows text-secondary mr-2"></i><?php echo "$asset_os"; ?></div>
<?php }
if ($asset_serial) { ?>
<div class="mt-2"><i class="fa fa-fw fa-barcode text-secondary mr-2"></i><?php echo $asset_serial; ?></div>
<?php }
if ($asset_purchase_date) { ?>
<div class="mt-2"><i class="fa fa-fw fa-shopping-cart text-secondary mr-2"></i><?php echo date('Y-m-d', strtotime($asset_purchase_date)); ?></div>
<?php }
if ($asset_install_date) { ?>
<div class="mt-2"><i class="fa fa-fw fa-calendar-check text-secondary mr-2"></i><?php echo date('Y-m-d', strtotime($asset_install_date)); ?></div>
<?php }
if ($asset_warranty_expire) { ?>
<div class="mt-2"><i class="fa fa-fw fa-exclamation-triangle text-secondary mr-2"></i><?php echo date('Y-m-d', strtotime($asset_warranty_expire)); ?></div>
<?php } ?>
</div>
</div>
<div class="card card-dark">
<div class="card-header">
<h5 class="card-title">Primary Network Interface</h5>
</div>
<div class="card-body">
<?php if ($asset_ip) { ?>
<div><i class="fa fa-fw fa-globe text-secondary mr-2"></i><?php echo $asset_ip; ?></div>
<?php } ?>
<?php if ($asset_nat_ip) { ?>
<div class="mt-2"><i class="fa fa-fw fa-random text-secondary mr-2"></i><?php echo $asset_nat_ip; ?></div>
<?php }
if ($asset_mac) { ?>
<div class="mt-2"><i class="fa fa-fw fa-ethernet text-secondary mr-2"></i><?php echo $asset_mac; ?></div>
<?php }
if ($asset_uri) { ?>
<div class="mt-2"><i class="fa fa-fw fa-link text-secondary mr-2"></i><a href="<?php echo $asset_uri; ?>" target="_blank" title="<?php echo $asset_uri; ?>"><?php echo truncate($asset_uri, 20); ?></a></div>
<?php }
if ($asset_uri_2) { ?>
<div class="mt-2"><i class="fa fa-fw fa-link text-secondary mr-2"></i><a href="<?php echo $asset_uri_2; ?>" target="_blank" title="<?php echo $asset_uri_2; ?>"><?php echo truncate($asset_uri_2, 20); ?></a></div>
<?php } ?>
<?php
if ($asset_uri_client) { ?>
<div class="mt-2"><i class="fa fa-fw fa-link text-secondary mr-2"></i>Client URI: <a href="<?= $asset_uri_client ?>" target="_blank" title="<?= $asset_uri_client ?>"><?= truncate($asset_uri_client, 20); ?></a></div>
<?php } ?>
</div>
</div>
<div class="card card-dark">
<div class="card-header">
<h5 class="card-title">Assignment</h5>
</div>
<div class="card-body">
<?php if ($location_name) { ?>
<div><i class="fa fa-fw fa-map-marker-alt text-secondary mr-2"></i><?php echo $location_name_display; ?></div>
<?php }
if ($contact_name) { ?>
<div class="mt-2"><i class="fa fa-fw fa-user text-secondary mr-2"></i><?php echo $contact_name_display; ?></div>
<?php }
if ($contact_email) { ?>
<div class="mt-2"><i class="fa fa-fw fa-envelope text-secondary mr-2"></i><a href='mailto:<?php echo $contact_email; ?>'><?php echo $contact_email; ?></a><button class='btn btn-sm clipboardjs' data-clipboard-text='<?php echo $contact_email; ?>'><i class='far fa-copy text-secondary'></i></button></div>
<?php }
if ($contact_phone) { ?>
<div class="mt-2"><i class="fa fa-fw fa-phone text-secondary mr-2"></i><?php echo formatPhoneNumber($contact_phone); echo " $contact_extension"; ?></div>
<?php }
if ($contact_mobile) { ?>
<div class="mt-2"><i class="fa fa-fw fa-mobile-alt text-secondary mr-2"></i><?php echo formatPhoneNumber($contact_mobile); ?></div>
<?php } ?>
</div>
</div>
<div class="card card-dark mb-3">
<div class="card-header">
<h5 class="card-title">Additional Notes</h5>
</div>
<textarea class="form-control" rows=6 id="assetNotes" placeholder="Enter quick notes here" onblur="updateAssetNotes(<?php echo $asset_id ?>)"><?php echo $asset_notes ?></textarea>
</div>
</div>
<script>
function updateAssetNotes(asset_id) {
var notes = document.getElementById("assetNotes").value;
// Send a POST request to ajax.php as ajax.php with data contact_set_notes=true, contact_id=NUM, notes=NOTES
jQuery.post(
"../ajax.php",
{
asset_set_notes: 'TRUE',
asset_id: asset_id,
notes: notes
}
)
}
</script>
<?php if ($interface_count) { ?>
<div class="tab-pane fade" id="pills-asset-interfaces<?php echo $asset_id; ?>">
<div class="table-responsive-sm">
<table class="table table-striped table-borderless table-hover table-sm">
<thead class="<?php if ($interface_count == 0) { echo "d-none"; } ?>">
<tr>
<th>Name / Port</th>
<th>Type</th>
<th>MAC</th>
<th>IP</th>
<th>Network</th>
<th>Connected To</th>
</tr>
</thead>
<tbody>
<?php while ($row = mysqli_fetch_array($sql_related_interfaces)) { ?>
<?php
$interface_id = intval($row['interface_id']);
$interface_name = nullable_htmlentities($row['interface_name']);
$interface_description = nullable_htmlentities($row['interface_description']);
$interface_type = nullable_htmlentities($row['interface_type']);
$interface_mac = nullable_htmlentities($row['interface_mac']);
$interface_ip = nullable_htmlentities($row['interface_ip']);
$interface_nat_ip = nullable_htmlentities($row['interface_nat_ip']);
$interface_ipv6 = nullable_htmlentities($row['interface_ipv6']);
$interface_primary = intval($row['interface_primary']);
$network_id = intval($row['network_id']);
$network_name = nullable_htmlentities($row['network_name']);
$interface_notes = nullable_htmlentities($row['interface_notes']);
// Prepare display text
$interface_mac_display = $interface_mac ?: '-';
$interface_ip_display = $interface_ip ?: '-';
$interface_type_display = $interface_type ?: '-';
$network_name_display = $network_name
? "<i class='fas fa-fw fa-network-wired mr-1'></i>$network_name"
: '-';
// Connected interface details
$connected_asset_id = intval($row['connected_asset_id']);
$connected_asset_name = nullable_htmlentities($row['connected_asset_name']);
$connected_asset_type = nullable_htmlentities($row['connected_asset_type']);
$connected_asset_icon = getAssetIcon($connected_asset_type);
$connected_interface_name = nullable_htmlentities($row['connected_interface_name']);
// Show either "-" or "AssetName - Port"
if ($connected_asset_name) {
$connected_to_display = "<a class='ajax-modal' href='#' data-modal-size='lg'
data-modal-url='modals/asset/asset_details.php?id=$connected_asset_id'>
<strong><i class='fa fa-fw fa-$connected_asset_icon mr-1'></i>$connected_asset_name</strong> - $connected_interface_name
</a>
";
} else {
$connected_to_display = "-";
}
?>
<tr>
<td>
<i class="fa fa-fw fa-ethernet text-secondary mr-1"></i>
<?php echo $interface_name; ?> <?php if($interface_primary) { echo "<small class='text-primary'>(Primary)</small>"; } ?>
</td>
<td><?php echo $interface_type_display; ?></td>
<td><?php echo $interface_mac_display; ?></td>
<td><?php echo $interface_ip_display; ?></td>
<td><?php echo $network_name_display; ?></td>
<td><?php echo $connected_to_display; ?></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
<?php } ?>
<?php if ($credential_count) { ?>
<div class="tab-pane fade" id="pills-asset-credentials<?php echo $asset_id; ?>">
<div class="table-responsive-sm-sm">
<table class="table table-sm table-striped table-borderless table-hover">
<thead>
<tr>
<th>Name</th>
<th>Username</th>
<th>Password</th>
<th>OTP</th>
<th>URI</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_related_credentials)) {
$credential_id = intval($row['credential_id']);
$credential_name = nullable_htmlentities($row['credential_name']);
$credential_description = nullable_htmlentities($row['credential_description']);
$credential_uri = nullable_htmlentities($row['credential_uri']);
if (empty($credential_uri)) {
$credential_uri_display = "-";
} else {
$credential_uri_display = "$credential_uri";
}
$credential_username = nullable_htmlentities(decryptCredentialEntry($row['credential_username']));
if (empty($credential_username)) {
$credential_username_display = "-";
} else {
$credential_username_display = "$credential_username <button type='button' class='btn btn-sm clipboardjs' data-clipboard-text='$credential_username'><i class='far fa-copy text-secondary'></i></button>";
}
$credential_password = nullable_htmlentities(decryptCredentialEntry($row['credential_password']));
$credential_otp_secret = nullable_htmlentities($row['credential_otp_secret']);
$credential_id_with_secret = '"' . $row['credential_id'] . '","' . $row['credential_otp_secret'] . '"';
if (empty($credential_otp_secret)) {
$otp_display = "-";
} else {
$otp_display = "<span onmouseenter='showOTPViaCredentialID($credential_id)'><i class='far fa-clock'></i> <span id='otp_$credential_id'><i>Hover..</i></span></span>";
}
$credential_note = nullable_htmlentities($row['credential_note']);
$credential_important = intval($row['credential_important']);
$credential_contact_id = intval($row['credential_contact_id']);
$credential_asset_id = intval($row['credential_asset_id']);
// Tags
$credential_tag_name_display_array = array();
$credential_tag_id_array = array();
$sql_credential_tags = mysqli_query($mysqli, "SELECT * FROM credential_tags LEFT JOIN tags ON credential_tags.tag_id = tags.tag_id WHERE credential_id = $credential_id ORDER BY tag_name ASC");
while ($row = mysqli_fetch_array($sql_credential_tags)) {
$credential_tag_id = intval($row['tag_id']);
$credential_tag_name = nullable_htmlentities($row['tag_name']);
$credential_tag_color = nullable_htmlentities($row['tag_color']);
if (empty($credential_tag_color)) {
$credential_tag_color = "dark";
}
$credential_tag_icon = nullable_htmlentities($row['tag_icon']);
if (empty($credential_tag_icon)) {
$credential_tag_icon = "tag";
}
$credential_tag_id_array[] = $credential_tag_id;
$credential_tag_name_display_array[] = "<a href='credentials.php?client_id=$client_id&tags[]=$credential_tag_id'><span class='badge text-light p-1 mr-1' style='background-color: $credential_tag_color;'><i class='fa fa-fw fa-$credential_tag_icon mr-2'></i>$credential_tag_name</span></a>";
}
$credential_tags_display = implode('', $credential_tag_name_display_array);
?>
<tr>
<td>
<i class="fa fa-fw fa-key text-secondary"></i>
<?php echo $credential_name; ?>
</td>
<td><?php echo $credential_username_display; ?></td>
<td>
<button class="btn p-0" type="button" data-toggle="popover" data-trigger="focus" data-placement="top" data-content="<?php echo $credential_password; ?>"><i class="fas fa-2x fa-ellipsis-h text-secondary"></i><i class="fas fa-2x fa-ellipsis-h text-secondary"></i></button>
<button type='button' class='btn btn-sm clipboardjs' data-clipboard-text='<?php echo $credential_password; ?>'><i class='far fa-copy text-secondary'></i></button>
</td>
<td><?php echo $otp_display; ?></td>
<td><?php echo $credential_uri_display; ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
</div>
<!-- Include script to get TOTP code via the credentials ID -->
<script src="../js/credential_show_otp_via_id.js"></script>
<?php } ?>
<?php if ($ticket_count) { ?>
<div class="tab-pane fade" id="pills-asset-tickets<?php echo $asset_id; ?>">
<div class="table-responsive-sm">
<table class="table table-sm table-striped table-borderless table-hover">
<thead class="text-dark">
<tr>
<th>Number</th>
<th>Subject</th>
<th>Priority</th>
<th>Status</th>
<th>Assigned</th>
<th>Last Response</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_related_tickets)) {
$ticket_id = intval($row['ticket_id']);
$ticket_prefix = nullable_htmlentities($row['ticket_prefix']);
$ticket_number = intval($row['ticket_number']);
$ticket_subject = nullable_htmlentities($row['ticket_subject']);
$ticket_priority = nullable_htmlentities($row['ticket_priority']);
$ticket_status_id = intval($row['ticket_status_id']);
$ticket_status_name = nullable_htmlentities($row['ticket_status_name']);
$ticket_status_color = nullable_htmlentities($row['ticket_status_color']);
$ticket_created_at = nullable_htmlentities($row['ticket_created_at']);
$ticket_updated_at = nullable_htmlentities($row['ticket_updated_at']);
if (empty($ticket_updated_at)) {
if ($ticket_status_name == "Closed") {
$ticket_updated_at_display = "<p>Never</p>";
} else {
$ticket_updated_at_display = "<p class='text-danger'>Never</p>";
}
} else {
$ticket_updated_at_display = $ticket_updated_at;
}
$ticket_closed_at = nullable_htmlentities($row['ticket_closed_at']);
if ($ticket_priority == "High") {
$ticket_priority_display = "<span class='p-2 badge badge-danger'>$ticket_priority</span>";
} elseif ($ticket_priority == "Medium") {
$ticket_priority_display = "<span class='p-2 badge badge-warning'>$ticket_priority</span>";
} elseif ($ticket_priority == "Low") {
$ticket_priority_display = "<span class='p-2 badge badge-info'>$ticket_priority</span>";
} else {
$ticket_priority_display = "-";
}
$ticket_assigned_to = intval($row['ticket_assigned_to']);
if (empty($ticket_assigned_to)) {
if ($ticket_status_id == 5) {
$ticket_assigned_to_display = "<p>Not Assigned</p>";
} else {
$ticket_assigned_to_display = "<p class='text-danger'>Not Assigned</p>";
}
} else {
$ticket_assigned_to_display = nullable_htmlentities($row['user_name']);
}
?>
<tr>
<td>
<a href="ticket.php?client_id=<?php echo $client_id; ?>&ticket_id=<?php echo $ticket_id; ?>">
<?php echo "$ticket_prefix$ticket_number"; ?>
</a>
</td>
<td><a href="ticket.php?client_id=<?php echo $client_id; ?>&ticket_id=<?php echo $ticket_id; ?>"><?php echo $ticket_subject; ?></a></td>
<td><?php echo $ticket_priority_display; ?></td>
<td>
<span class='badge badge-pill text-light p-2' style="background-color: <?php echo $ticket_status_color; ?>"><?php echo $ticket_status_name; ?></span>
</td>
<td><?php echo $ticket_assigned_to_display; ?></td>
<td><?php echo $ticket_updated_at_display; ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
</div>
<?php } ?>
<?php if ($recurring_ticket_count) { ?>
<div class="tab-pane fade" id="pills-asset-recurring-tickets<?php echo $asset_id; ?>">
<div class="table-responsive-sm">
<table class="table table-sm table-striped table-borderless table-hover">
<thead class="text-dark">
<tr>
<th>Subject</th>
<th>Priority</th>
<th>Frequency</th>
<th>Next Run</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_related_recurring_tickets)) {
$recurring_ticket_id = intval($row['recurring_ticket_id']);
$recurring_ticket_subject = nullable_htmlentities($row['recurring_ticket_subject']);
$recurring_ticket_priority = nullable_htmlentities($row['recurring_ticket_priority']);
$recurring_ticket_frequency = nullable_htmlentities($row['recurring_ticket_frequency']);
$recurring_ticket_next_run = nullable_htmlentities($row['recurring_ticket_next_run']);
?>
<tr>
<td class="text-bold"><?php echo $recurring_ticket_subject ?></td>
<td><?php echo $recurring_ticket_priority ?></td>
<td><?php echo $recurring_ticket_frequency ?></td>
<td><?php echo $recurring_ticket_next_run ?></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
<?php } ?>
<?php if ($software_count) { ?>
<div class="tab-pane fade" id="pills-asset-licenses<?php echo $asset_id; ?>">
<div class="table-responsive-sm">
<table class="table table-striped table-borderless table-hover">
<thead class="text-dark">
<tr>
<th>Software</th>
<th>Type</th>
<th>Key</th>
<th>Seats</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_related_software)) {
$software_id = intval($row['software_id']);
$software_name = nullable_htmlentities($row['software_name']);
$software_version = nullable_htmlentities($row['software_version']);
$software_type = nullable_htmlentities($row['software_type']);
$software_license_type = nullable_htmlentities($row['software_license_type']);
$software_key = nullable_htmlentities($row['software_key']);
$software_seats = nullable_htmlentities($row['software_seats']);
$software_purchase = nullable_htmlentities($row['software_purchase']);
$software_expire = nullable_htmlentities($row['software_expire']);
$software_notes = nullable_htmlentities($row['software_notes']);
$seat_count = 0;
// Asset Licenses
$asset_licenses_sql = mysqli_query($mysqli, "SELECT asset_id FROM software_assets WHERE software_id = $software_id");
$asset_licenses_array = array();
while ($row = mysqli_fetch_array($asset_licenses_sql)) {
$asset_licenses_array[] = intval($row['asset_id']);
$seat_count = $seat_count + 1;
}
$asset_licenses = implode(',', $asset_licenses_array);
// Contact Licenses
$contact_licenses_sql = mysqli_query($mysqli, "SELECT contact_id FROM software_contacts WHERE software_id = $software_id");
$contact_licenses_array = array();
while ($row = mysqli_fetch_array($contact_licenses_sql)) {
$contact_licenses_array[] = intval($row['contact_id']);
$seat_count = $seat_count + 1;
}
$contact_licenses = implode(',', $contact_licenses_array);
?>
<tr>
<td><?php echo "$software_name<br><span class='text-secondary'>$software_version</span>"; ?></td>
<td><?php echo $software_type; ?></td>
<td><?php echo $software_key; ?></td>
<td><?php echo "$seat_count / $software_seats"; ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
</div>
<?php } ?>
<?php if ($document_count) { ?>
<div class="tab-pane fade" id="pills-asset-documents<?php echo $asset_id; ?>">
<div class="table-responsive-sm">
<table class="table table-sm table-striped table-borderless table-hover">
<thead class="text-dark">
<tr>
<th>Document Title</th>
<th>By</th>
<th>Created</th>
<th>Updated</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_related_documents)) {
$document_id = intval($row['document_id']);
$document_name = nullable_htmlentities($row['document_name']);
$document_description = nullable_htmlentities($row['document_description']);
$document_created_by = nullable_htmlentities($row['user_name']);
$document_created_at = nullable_htmlentities($row['document_created_at']);
$document_updated_at = nullable_htmlentities($row['document_updated_at']);
$linked_documents[] = $document_id;
?>
<tr>
<td>
<a class="ajax-modal" href="#"
data-modal-size="lg"
data-modal-url="modals/document/document_view.php?id=<?= $document_id ?>">
<?php echo $document_name; ?>
</a>
<div class="text-secondary"><?php echo $document_description; ?></div>
</td>
<td><?php echo $document_created_by; ?></td>
<td><?php echo $document_created_at; ?></td>
<td><?php echo $document_updated_at; ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
</div>
<?php } ?>
<?php if ($file_count) { ?>
<div class="tab-pane fade" id="pills-asset-files<?php echo $asset_id; ?>">
<div class="table-responsive-sm">
<table class="table table-sm table-striped table-borderless table-hover">
<thead class="text-dark">
<tr>
<th>Name</th>
<th>Type</th>
<th>Uploaded</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($sql_related_files)) {
$file_id = intval($row['file_id']);
$file_name = nullable_htmlentities($row['file_name']);
$file_mime_type = nullable_htmlentities($row['file_mime_type']);
$file_description = nullable_htmlentities($row['file_description']);
$file_reference_name = nullable_htmlentities($row['file_reference_name']);
$file_ext = nullable_htmlentities($row['file_ext']);
if ($file_ext == 'pdf') {
$file_icon = "file-pdf";
} elseif ($file_ext == 'gz' || $file_ext == 'tar' || $file_ext == 'zip' || $file_ext == '7z' || $file_ext == 'rar') {
$file_icon = "file-archive";
} elseif ($file_ext == 'txt' || $file_ext == 'md') {
$file_icon = "file-alt";
} elseif ($file_ext == 'msg') {
$file_icon = "envelope";
} elseif ($file_ext == 'doc' || $file_ext == 'docx' || $file_ext == 'odt') {
$file_icon = "file-word";
} elseif ($file_ext == 'xls' || $file_ext == 'xlsx' || $file_ext == 'ods') {
$file_icon = "file-excel";
} elseif ($file_ext == 'pptx' || $file_ext == 'odp') {
$file_icon = "file-powerpoint";
} elseif ($file_ext == 'mp3' || $file_ext == 'wav' || $file_ext == 'ogg') {
$file_icon = "file-audio";
} elseif ($file_ext == 'mov' || $file_ext == 'mp4' || $file_ext == 'av1') {
$file_icon = "file-video";
} elseif ($file_ext == 'jpg' || $file_ext == 'jpeg' || $file_ext == 'png' || $file_ext == 'gif' || $file_ext == 'webp' || $file_ext == 'bmp' || $file_ext == 'tif') {
$file_icon = "file-image";
} else {
$file_icon = "file";
}
$file_created_at = nullable_htmlentities($row['file_created_at']);
?>
<tr>
<td><a class="text-dark" href="<?php echo "../uploads/clients/$client_id/$file_reference_name"; ?>" target="_blank" ><?php echo "$file_name<br><span class='text-secondary'>$file_description</span>"; ?></a></td>
<td><?php echo $file_mime_type; ?></td>
<td><?php echo $file_created_at; ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
</div>
<?php } ?>
</div>
</div>
<div class="modal-footer">
<a href="asset_details.php?client_id=<?php echo $client_id; ?>&asset_id=<?php echo $asset_id; ?>"
class="btn btn-primary text-bold"><span class="text-white"><i class="fas fa-info-circle mr-2"></i>More Details</span>
</a>
<a href="#" class="btn btn-secondary ajax-modal" data-modal-url="modals/asset/asset_edit.php?id=<?= $asset_id ?>">
<span class="text-white"><i class="fas fa-edit mr-2"></i>Edit</span>
</a>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Close</button>
</div>
<?php
require_once '../../../includes/modal_footer.php';

View File

@@ -0,0 +1,29 @@
<div class="modal" id="assetDocumentsModal<?php echo $asset_id; ?>" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-<?php echo $device_icon; ?> mr-2"></i><?php echo $asset_name; ?> Documents</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<?php
while ($row = mysqli_fetch_array($sql_related_documents)) {
$related_document_id = intval($row['document_id']);
$related_document_name = nullable_htmlentities($row['document_name']);
?>
<p>
<i class="fas fa-fw fa-document text-secondary"></i>
<?php echo $related_document_name; ?> <a href="client_documents.php?q=<?php echo $related_document_name; ?>"><?php echo $related_document_name; ?></a>
</p>
<?php } ?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,496 @@
<?php
require_once '../../../includes/modal_header.php';
$asset_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM assets
LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1
WHERE asset_id = $asset_id LIMIT 1"
);
$row = mysqli_fetch_array($sql);
$client_id = intval($row['asset_client_id']);
$asset_id = intval($row['asset_id']);
$asset_type = nullable_htmlentities($row['asset_type']);
$asset_name = nullable_htmlentities($row['asset_name']);
$asset_description = nullable_htmlentities($row['asset_description']);
$asset_make = nullable_htmlentities($row['asset_make']);
$asset_model = nullable_htmlentities($row['asset_model']);
$asset_serial = nullable_htmlentities($row['asset_serial']);
$asset_os = nullable_htmlentities($row['asset_os']);
$asset_ip = nullable_htmlentities($row['interface_ip']);
$asset_ipv6 = nullable_htmlentities($row['interface_ipv6']);
$asset_nat_ip = nullable_htmlentities($row['interface_nat_ip']);
$asset_mac = nullable_htmlentities($row['interface_mac']);
$asset_uri = nullable_htmlentities($row['asset_uri']);
$asset_uri_2 = nullable_htmlentities($row['asset_uri_2']);
$asset_uri_client = nullable_htmlentities($row['asset_uri_client']);
$asset_status = nullable_htmlentities($row['asset_status']);
$asset_purchase_reference = nullable_htmlentities($row['asset_purchase_reference']);
$asset_purchase_date = nullable_htmlentities($row['asset_purchase_date']);
$asset_warranty_expire = nullable_htmlentities($row['asset_warranty_expire']);
$asset_install_date = nullable_htmlentities($row['asset_install_date']);
$asset_photo = nullable_htmlentities($row['asset_photo']);
$asset_physical_location = nullable_htmlentities($row['asset_physical_location']);
$asset_notes = nullable_htmlentities($row['asset_notes']);
$asset_created_at = nullable_htmlentities($row['asset_created_at']);
$asset_archived_at = nullable_htmlentities($row['asset_archived_at']);
$asset_vendor_id = intval($row['asset_vendor_id']);
$asset_location_id = intval($row['asset_location_id']);
$asset_contact_id = intval($row['asset_contact_id']);
$asset_network_id = intval($row['interface_network_id']);
$device_icon = getAssetIcon($asset_type);
// Asset History Query
$sql_asset_history = mysqli_query($mysqli, "SELECT * FROM asset_history
WHERE asset_history_asset_id = $asset_id
ORDER BY asset_history_id
DESC LIMIT 10"
);
// Generate the HTML form content using output buffering.
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class='fa fa-fw fa-<?php echo $device_icon; ?> mr-2'></i>Editing asset: <strong><?php echo $asset_name; ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<input type="hidden" name="asset_id" value="<?php echo $asset_id; ?>">
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<div class="modal-body">
<ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-details<?php echo $asset_id; ?>">Details</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-network<?php echo $asset_id; ?>">Network</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-assignment<?php echo $asset_id; ?>">Assignment</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-purchase<?php echo $asset_id; ?>">Purchase</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-notes<?php echo $asset_id; ?>">Notes</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-history<?php echo $asset_id; ?>">History</a>
</li>
</ul>
<hr>
<div class="tab-content" <?php if (lookupUserPermission('module_support') <= 1) { echo 'inert'; } ?>>
<div class="tab-pane fade show active" id="pills-details<?php echo $asset_id; ?>">
<div class="form-group">
<label>Name <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-tag"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Name the asset" maxlength="200" value="<?php echo $asset_name; ?>" required>
</div>
</div>
<div class="form-group">
<label>Description</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
</div>
<input type="text" class="form-control" name="description" placeholder="Description of the asset" maxlength="255" value="<?php echo $asset_description; ?>">
</div>
</div>
<div class="form-group">
<label>Type <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-tags"></i></span>
</div>
<select class="form-control select2" name="type" required>
<?php foreach($asset_types_array as $asset_type_select => $asset_icon_select) { ?>
<option <?php if ($asset_type_select == $asset_type) { echo "selected"; } ?>><?php echo $asset_type_select; ?></option>
<?php } ?>
</select>
</div>
</div>
<?php //Do not display Make Model or Serial if Virtual is selected
if ($asset_type !== 'virtual') { ?>
<div class="form-group">
<label>Make </label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
</div>
<input type="text" class="form-control" name="make" placeholder="Manufacturer" maxlength="200" value="<?php echo $asset_make; ?>">
</div>
</div>
<div class="form-group">
<label>Model</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
</div>
<input type="text" class="form-control" name="model" placeholder="Model Number" maxlength="200" value="<?php echo $asset_model; ?>">
</div>
</div>
<div class="form-group">
<label>Serial Number</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span>
</div>
<input type="text" class="form-control" name="serial" placeholder="Serial number" maxlength="200" value="<?php echo $asset_serial; ?>">
</div>
</div>
<?php } ?>
<?php if ($asset_type !== 'Phone' && $asset_type !== 'Mobile Phone' && $asset_type !== 'Tablet' && $asset_type !== 'Access Point' && $asset_type !== 'Printer' && $asset_type !== 'Camera' && $asset_type !== 'TV' && $asset_type !== 'Other') { ?>
<div class="form-group">
<label>Operating System</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fab fa-fw fa-windows"></i></span>
</div>
<input type="text" class="form-control" name="os" placeholder="ex Windows 10 Pro" maxlength="200" value="<?php echo $asset_os; ?>">
</div>
</div>
<?php } ?>
</div>
<div class="tab-pane fade" id="pills-network<?php echo $asset_id; ?>">
<div class="form-group">
<label>Network</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-network-wired"></i></span>
</div>
<select class="form-control select2" name="network">
<option value="">- Select Network -</option>
<?php
$sql_networks = mysqli_query($mysqli, "SELECT * FROM networks WHERE network_id = $asset_network_id OR network_archived_at IS NULL AND network_client_id = $client_id ORDER BY network_name ASC");
while ($row = mysqli_fetch_array($sql_networks)) {
$network_id_select = intval($row['network_id']);
$network_name_select = nullable_htmlentities($row['network_name']);
$network_select = nullable_htmlentities($row['network']);
$network_archived_at = nullable_htmlentities($row['network_archived_at']);
if ($network_archived_at) {
$network_name_select_display = "($network_name_select - $network_select) - ARCHIVED";
} else {
$network_name_select_display = "$network_name_select - $network_select";
}
?>
<option <?php if ($asset_network_id == $network_id_select) { echo "selected"; } ?> value="<?php echo $network_id_select; ?>"><?php echo $network_name_select_display; ?></option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group">
<label>IP Address or DHCP</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
</div>
<input type="text" class="form-control" name="ip" value="<?php echo $asset_ip; ?>" placeholder="192.168.10.250" data-inputmask="'alias': 'ip'" maxlength="200" data-mask>
<div class="input-group-append">
<div class="input-group-text">
<input type="checkbox" name="dhcp" value="1" <?php if($asset_ip == 'DHCP'){ echo "checked"; } ?>>
</div>
</div>
</div>
</div>
<div class="form-group">
<label>NAT IP</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-random"></i></span>
</div>
<input type="text" class="form-control" name="nat_ip" value="<?php echo $asset_nat_ip; ?>" placeholder="10.52.4.55" data-inputmask="'alias': 'ip'" maxlength="200" data-mask>
</div>
</div>
<div class="form-group">
<label>IPv6 Address</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
</div>
<input type="text" class="form-control" name="ipv6" value="<?php echo $asset_ipv6; ?>" placeholder="ex. 2001:0db8:0000:0000:0000:ff00:0042:8329" maxlength="200">
</div>
</div>
<div class="form-group">
<label>MAC Address</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
</div>
<input type="text" class="form-control" name="mac" value="<?php echo $asset_mac; ?>" placeholder="MAC Address" data-inputmask="'alias': 'mac'" maxlength="200" data-mask>
</div>
</div>
<div class="form-group">
<label>URI</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span>
</div>
<input type="text" class="form-control" name="uri" placeholder="URI http:// ftp:// ssh: etc" maxlength="500" value="<?php echo $asset_uri; ?>">
</div>
</div>
<div class="form-group">
<label>URI 2</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span>
</div>
<input type="text" class="form-control" name="uri_2" placeholder="URI http:// ftp:// ssh: etc" maxlength="500" value="<?= $asset_uri_2 ?>">
</div>
</div>
<div class="form-group">
<label>Client URI</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span>
</div>
<input type="text" class="form-control" name="uri_client" placeholder="URI http:// ftp:// ssh: etc -- viewable in Client Portal" maxlength="500" value="<?= $asset_uri_client ?>">
</div>
</div>
</div>
<div class="tab-pane fade" id="pills-assignment<?php echo $asset_id; ?>">
<div class="form-group">
<label>Physical Location</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-map-marker-alt"></i></span>
</div>
<input type="text" class="form-control" name="physical_location" placeholder="Physical location eg. Floor 2, Closet B" maxlength="200" value="<?php echo $asset_physical_location; ?>">
</div>
</div>
<div class="form-group">
<label>Location</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-map-marker-alt"></i></span>
</div>
<select class="form-control select2" name="location">
<option value="">- Select Location -</option>
<?php
$sql_locations = mysqli_query($mysqli, "SELECT * FROM locations WHERE location_id = $asset_location_id OR location_archived_at IS NULL AND location_client_id = $client_id ORDER BY location_name ASC");
while ($row = mysqli_fetch_array($sql_locations)) {
$location_id_select = intval($row['location_id']);
$location_name_select = nullable_htmlentities($row['location_name']);
$location_archived_at = nullable_htmlentities($row['location_archived_at']);
if ($location_archived_at) {
$location_name_select_display = "($location_name_select) - ARCHIVED";
} else {
$location_name_select_display = $location_name_select;
}
?>
<option <?php if ($asset_location_id == $location_id_select) { echo "selected"; } ?> value="<?php echo $location_id_select; ?>"><?php echo $location_name_select_display; ?></option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group">
<label>Assign To</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<select class="form-control select2" name="contact">
<option value="">- Select Contact -</option>
<?php
$sql_contacts = mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_id = $asset_contact_id OR contact_archived_at IS NULL AND contact_client_id = $client_id ORDER BY contact_name ASC");
while ($row = mysqli_fetch_array($sql_contacts)) {
$contact_id_select = intval($row['contact_id']);
$contact_name_select = nullable_htmlentities($row['contact_name']);
$contact_archived_at = nullable_htmlentities($row['contact_archived_at']);
if ($contact_archived_at) {
$contact_name_select_display = "($contact_name_select) - ARCHIVED";
} else {
$contact_name_select_display = $contact_name_select;
}
?>
<option <?php if ($asset_contact_id == $contact_id_select) { echo "selected"; } ?> value="<?php echo $contact_id_select; ?>">
<?php echo $contact_name_select_display; ?>
</option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group">
<label>Status</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-info"></i></span>
</div>
<select class="form-control select2" name="status">
<?php foreach($asset_status_array as $asset_status_select) { ?>
<option <?php if ($asset_status_select == $asset_status) { echo "selected"; } ?>><?php echo $asset_status_select; ?></option>
<?php } ?>
</select>
</div>
</div>
</div>
<div class="tab-pane fade" id="pills-purchase<?php echo $asset_id; ?>">
<div class="form-group">
<label>Vendor</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-building"></i></span>
</div>
<select class="form-control select2" name="vendor">
<option value="">- Select Vendor -</option>
<?php
$sql_vendors = mysqli_query($mysqli, "SELECT * FROM vendors WHERE vendor_id = $asset_vendor_id OR vendor_archived_at IS NULL AND vendor_client_id = $client_id ORDER BY vendor_name ASC");
while ($row = mysqli_fetch_array($sql_vendors)) {
$vendor_id_select = intval($row['vendor_id']);
$vendor_name_select = nullable_htmlentities($row['vendor_name']);
$vendor_archived_at = nullable_htmlentities($row['vendor_archived_at']);
if ($vendor_archived_at) {
$vendor_name_select_display = "($vendor_name_select) - ARCHIVED";
} else {
$vendor_name_select_display = $vendor_name_select;
}
?>
<option <?php if ($asset_vendor_id == $vendor_id_select) { echo "selected"; } ?> value="<?php echo $vendor_id_select; ?>"><?php echo $vendor_name_select_display; ?></option>
<?php } ?>
</select>
</div>
</div>
<?php if ($asset_type !== 'Virtual Machine') { ?>
<div class="form-group">
<label>Purchase Reference</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-shopping-cart"></i></span>
</div>
<input type="text" class="form-control" name="purchase_reference" placeholder="eg. Invoice, PO Number" value="<?php echo $asset_purchase_reference; ?>">
</div>
</div>
<div class="form-group">
<label>Purchase Date</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="date" class="form-control" name="purchase_date" max="2999-12-31" value="<?php echo $asset_purchase_date; ?>">
</div>
</div>
<?php } ?>
<div class="form-group">
<label>Install Date</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar-check"></i></span>
</div>
<input type="date" class="form-control" name="install_date" max="2999-12-31" value="<?php echo $asset_install_date; ?>">
</div>
</div>
<?php if ($asset_type !== 'Virtual Machine') { ?>
<div class="form-group">
<label>Warranty Expire</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar-times"></i></span>
</div>
<input type="date" class="form-control" name="warranty_expire" max="2999-12-31" value="<?php echo $asset_warranty_expire; ?>">
</div>
</div>
<?php } ?>
</div>
<div class="tab-pane fade" id="pills-notes<?php echo $asset_id; ?>">
<div class="mb-3 text-center">
<?php if ($asset_photo) { ?>
<img class="img-fluid" alt="asset_photo" src="<?php echo "../uploads/clients/$client_id/$asset_photo"; ?>">
<?php } ?>
</div>
<div class="form-group">
<label>Upload / Replace Photo</label>
<input type="file" class="form-control-file" name="file" accept="image/*">
</div>
<div class="form-group">
<textarea class="form-control" rows="8" placeholder="Enter some notes" name="notes"><?php echo $asset_notes; ?></textarea>
</div>
<p class="text-muted text-right">Asset ID: <?= $asset_id ?></p>
</div>
<div class="tab-pane fade" id="pills-history<?php echo $asset_id; ?>">
<div class="form-group">
<label>Asset History</label>
<ul>
<?php
while ($row = mysqli_fetch_array($sql_asset_history)) {
$asset_history_description = nullable_htmlentities(($row['asset_history_description']));
$asset_history_created_at = nullable_htmlentities(($row['asset_history_created_at']));
echo "<li><small class='text-secondary'>$asset_history_created_at</small><br>$asset_history_description</li>";
}
?>
</ul>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="edit_asset" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</form>
<?php
require_once '../../../includes/modal_footer.php';

View File

@@ -0,0 +1,26 @@
<div class="modal" id="exportAssetModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Assets to CSV</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<?php if ($client_url) { ?>
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<?php } ?>
<div class="modal-body">
</div>
<div class="modal-footer">
<button type="submit" name="export_assets_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,32 @@
<div class="modal" id="importAssetModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-desktop mr-2"></i>Import Assets</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<?php if ($client_url) { ?>
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<?php } ?>
<div class="modal-body">
<p><strong>Format csv file with headings & data:</strong><br>Name, Description, Type, Make, Model, Serial, OS, Purchase Date, Assigned To, Location, Physical Location</p>
<hr>
<div class="form-group my-4">
<input type="file" class="form-control-file" name="file" accept=".csv" required>
</div>
<hr>
<div>Download <a href="post.php?download_assets_csv_template=<?php echo $client_id; ?>">sample csv template</a></div>
<small class="text-muted">Note: Purchase date must be in the format YYYY-MM-DD. Spreadsheet tools may automatically reformat dates.</small>
</div>
<div class="modal-footer">
<button type="submit" name="import_assets_csv" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Import</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,224 @@
<div class="modal" id="addAssetInterfaceModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-ethernet mr-2"></i>New Network Interface</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="asset_id" value="<?php echo $asset_id; ?>">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<div class="modal-body">
<ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-interface-details">Details</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-interface-network">Network</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-interface-notes">Notes</a>
</li>
</ul>
<hr>
<div class="tab-content">
<div class="tab-pane fade show active" id="pills-interface-details">
<!-- Interface Name -->
<div class="form-group">
<label>Interface Name or Port / <span class="text-secondary">Primary</span></label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Interface name or port number" maxlength="200" required>
<div class="input-group-append">
<div class="input-group-text">
<input type="checkbox" name="primary_interface" value="1" title="Mark Interface as primary">
</div>
</div>
</div>
</div>
<!-- Type -->
<div class="form-group">
<label for="network">Type</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-plug"></i></span>
</div>
<select class="form-control select2" name="type">
<option value="">- Select Type -</option>
<?php foreach($interface_types_array as $interface_type) { ?>
<option><?php echo $interface_type; ?></option>
<?php } ?>
</select>
</div>
</div>
<!-- Interface Description -->
<div class="form-group">
<label>Description</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
</div>
<input
type="text"
class="form-control"
name="description"
placeholder="Short Description"
maxlength="200"
>
</div>
</div>
</div>
<div class="tab-pane fade" id="pills-interface-network">
<!-- MAC Address -->
<div class="form-group">
<label>MAC Address</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
</div>
<input type="text" class="form-control" name="mac" placeholder="MAC Address" data-inputmask="'alias': 'mac'" maxlength="200" data-mask>
</div>
</div>
<!-- IP (with optional DHCP checkbox) -->
<div class="form-group">
<label>IP or DHCP</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
</div>
<input type="text" class="form-control" name="ip" placeholder="IP Address" data-inputmask="'alias': 'ip'" maxlength="200" data-mask>
<div class="input-group-append">
<div class="input-group-text">
<input type="checkbox" name="dhcp" value="1" title="Check to mark address as DHCP controlled">
</div>
</div>
</div>
</div>
<!-- NAT IP -->
<div class="form-group">
<label>NAT IP</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
</div>
<input
type="text"
class="form-control"
name="nat_ip"
placeholder="Nat IP"
maxlength="200"
data-inputmask="'alias': 'ip'"
data-mask
>
</div>
</div>
<!-- IPv6 -->
<div class="form-group">
<label>IPv6</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
</div>
<input type="text" class="form-control" name="ipv6" placeholder="IPv6 Address" maxlength="200">
</div>
</div>
<!-- Network -->
<div class="form-group">
<label>Network</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-network-wired"></i></span>
</div>
<select class="form-control select2" name="network">
<option value="">- Select Network -</option>
<?php
$sql_network_select = mysqli_query($mysqli, "SELECT * FROM networks WHERE network_archived_at IS NULL AND network_client_id = $client_id ORDER BY network_name ASC");
while ($row = mysqli_fetch_array($sql_network_select)) {
$network_id = $row['network_id'];
$network_name = nullable_htmlentities($row['network_name']);
$network = nullable_htmlentities($row['network']);
?>
<option value="<?php echo $network_id; ?>">
<?php echo "$network_name - $network"; ?>
</option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group">
<label>Connected to</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-desktop"></i></span>
</div>
<select class="form-control select2" name="connected_to">
<option value="">- NSelect Asset and Interface -</option>
<?php
$sql_interfaces_select = mysqli_query($mysqli, "
SELECT i.interface_id, i.interface_name, a.asset_name
FROM asset_interfaces i
LEFT JOIN assets a ON a.asset_id = i.interface_asset_id
WHERE a.asset_archived_at IS NULL
AND a.asset_client_id = $client_id
AND a.asset_id != $asset_id
AND i.interface_id NOT IN (SELECT interface_a_id FROM asset_interface_links)
AND i.interface_id NOT IN (SELECT interface_b_id FROM asset_interface_links)
ORDER BY a.asset_name ASC, i.interface_name ASC
");
while ($row = mysqli_fetch_array($sql_interfaces_select)) {
$interface_id_select = intval($row['interface_id']);
$interface_name_select = nullable_htmlentities($row['interface_name']);
$asset_name_select = nullable_htmlentities($row['asset_name']);
?>
<option value="<?php echo $interface_id_select; ?>">
<?php echo "$asset_name_select - $interface_name_select"; ?>
</option>
<?php } ?>
</select>
</div>
</div>
</div>
<div class="tab-pane fade" id="pills-interface-notes">
<!-- Notes -->
<div class="form-group">
<textarea class="form-control" rows="8" placeholder="Enter some notes" name="notes"></textarea>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="add_asset_interface" class="btn btn-primary text-bold">
<i class="fas fa-check mr-2"></i>Create
</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Close</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,51 @@
<div class="modal" id="bulkAssignNetworkModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-network-wired mr-2"></i>Bulk Assign Network</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<!-- Network -->
<div class="form-group">
<label>Network</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-network-wired"></i></span>
</div>
<select class="form-control select2" name="bulk_network">
<option value="">- Select a Network -</option>
<?php
$sql_network_select = mysqli_query($mysqli, "
SELECT network_id, network_name, network
FROM networks
WHERE network_archived_at IS NULL
AND network_client_id = $client_id
ORDER BY network_name ASC
");
while ($net_row = mysqli_fetch_array($sql_network_select)) {
$network_id_select = intval($net_row['network_id']);
$network_name_select = nullable_htmlentities($net_row['network_name']);
$network_select = nullable_htmlentities($net_row['network']);
?>
<option value="<?php echo $network_id_select; ?>"><?php echo "$network_name_select - $network_select"; ?></option>
<?php
}
?>
</select>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="bulk_edit_asset_interface_network" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Assign</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,36 @@
<div class="modal" id="bulkSetInterfaceTypeModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-ethernet mr-2"></i>Bulk Set Interface Type</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label>Interface Type</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
</div>
<select class="form-control select2" name="bulk_type">
<option value="">- Select a Type -</option>
<?php foreach($interface_types_array as $interface_type_select) { ?>
<option><?php echo $interface_type_select; ?></option>
<?php } ?>
</select>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="bulk_edit_asset_interface_type" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Set</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,333 @@
<?php
require_once '../../../includes/modal_header.php';
$interface_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM asset_interfaces
LEFT JOIN assets ON asset_id = interface_asset_id
LEFT JOIN clients ON client_id = asset_client_id
WHERE interface_id = $interface_id LIMIT 1"
);
$interface_count = mysqli_num_rows($sql);
$row = mysqli_fetch_array($sql);
$client_id = intval($row['asset_client_id']);
$asset_id = intval($row['interface_asset_id']);
$network_id = intval($row['interface_network_id']);
$asset_name = nullable_htmlentities($row['asset_name']);
$interface_id = intval($row['interface_id']);
$interface_name = nullable_htmlentities($row['interface_name']);
$interface_description = nullable_htmlentities($row['interface_description']);
$interface_type = nullable_htmlentities($row['interface_type']);
$interface_mac = nullable_htmlentities($row['interface_mac']);
$interface_ip = nullable_htmlentities($row['interface_ip']);
$interface_nat_ip = nullable_htmlentities($row['interface_nat_ip']);
$interface_ipv6 = nullable_htmlentities($row['interface_ipv6']);
$interface_primary = intval($row['interface_primary']);
$interface_notes = nullable_htmlentities($row['interface_notes']);
// Determine the linked interface for $interface_id
$linked_interface_id = null;
$sql_link = mysqli_query($mysqli, "
SELECT interface_a_id, interface_b_id
FROM asset_interface_links
WHERE interface_a_id = $interface_id
OR interface_b_id = $interface_id
LIMIT 1
");
if ($link_row = mysqli_fetch_assoc($sql_link)) {
if ($link_row['interface_a_id'] == $interface_id) {
$linked_interface_id = intval($link_row['interface_b_id']);
} else {
$linked_interface_id = intval($link_row['interface_a_id']);
}
}
// Generate the HTML form content using output buffering.
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class='fa fa-fw fa-ethernet mr-2'></i>Editing Interface: <?php echo $asset_name; ?> - <strong><?php echo $interface_name; ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
<input type="hidden" name="interface_id" value="<?php echo $interface_id; ?>">
<div class="modal-body" <?php if (lookupUserPermission('module_support') <= 1) { echo 'inert'; } ?>>
<ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-interface-details<?php echo $interface_id; ?>">Details</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-interface-network<?php echo $interface_id; ?>">Network</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-interface-notes<?php echo $interface_id; ?>">Notes</a>
</li>
</ul>
<hr>
<div class="tab-content">
<div class="tab-pane fade show active" id="pills-interface-details<?php echo $interface_id; ?>">
<!-- Interface Name -->
<div class="form-group">
<label>Interface Name or Port / <span class="text-secondary">Primary</span></label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
</div>
<input
type="text"
class="form-control"
name="name"
placeholder="Interface name or port number"
maxlength="200"
value="<?php echo $interface_name; ?>"
required
>
<div class="input-group-append">
<div class="input-group-text">
<input type="checkbox" name="primary_interface" value="1" <?php if($interface_primary) { echo "checked"; } ?> title="Mark Interface as primary">
</div>
</div>
</div>
</div>
<!-- Interface Description -->
<div class="form-group">
<label>Description</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
</div>
<input
type="text"
class="form-control"
name="description"
placeholder="Short Description"
maxlength="200"
value="<?php echo $interface_description; ?>"
>
</div>
</div>
<!-- Type -->
<div class="form-group">
<label for="network">Type</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-plug"></i></span>
</div>
<select class="form-control select2" name="type">
<option value="">- Select Type -</option>
<?php foreach($interface_types_array as $interface_type_select) { ?>
<option <?php if($interface_type == $interface_type_select) { echo "selected"; } ?>>
<?php echo $interface_type_select; ?>
</option>
<?php } ?>
</select>
</div>
</div>
</div> <!-- End Details -->
<!-- Network Section -->
<div class="tab-pane fade" id="pills-interface-network<?php echo $interface_id; ?>">
<!-- MAC Address -->
<div class="form-group">
<label>MAC Address</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
</div>
<input
type="text"
class="form-control"
name="mac"
placeholder="MAC Address"
maxlength="200"
value="<?php echo $interface_mac; ?>"
data-inputmask="'alias': 'mac'"
data-mask
>
</div>
</div>
<!-- IPv4 or DHCP -->
<div class="form-group">
<label>IPv4 or DHCP</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
</div>
<input
type="text"
class="form-control"
name="ip"
placeholder="IP Address"
maxlength="200"
value="<?php echo $interface_ip; ?>"
data-inputmask="'alias': 'ip'"
data-mask
>
<div class="input-group-append">
<div class="input-group-text">
<input
type="checkbox"
name="dhcp"
value="1"
title="Check to mark address as DHCP controlled"
<?php if ($interface_ip === 'DHCP') echo "checked"; ?>
>
</div>
</div>
</div>
</div>
<!-- NAT IP -->
<div class="form-group">
<label>NAT IP</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
</div>
<input
type="text"
class="form-control"
name="nat_ip"
placeholder="Nat IP"
maxlength="200"
value="<?php echo $interface_nat_ip; ?>"
data-inputmask="'alias': 'ip'"
data-mask
>
</div>
</div>
<!-- IPv6 -->
<div class="form-group">
<label>IPv6</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
</div>
<input
type="text"
class="form-control"
name="ipv6"
placeholder="IPv6 Address"
maxlength="200"
value="<?php echo $interface_ipv6; ?>"
>
</div>
</div>
<!-- Network -->
<div class="form-group">
<label>Network</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-network-wired"></i></span>
</div>
<select class="form-control select2" name="network">
<option value="">- Select Network -</option>
<?php
$sql_network_select = mysqli_query($mysqli, "
SELECT network_id, network_name, network
FROM networks
WHERE network_archived_at IS NULL
AND network_client_id = $client_id
ORDER BY network_name ASC
");
while ($net_row = mysqli_fetch_array($sql_network_select)) {
$network_id_select = intval($net_row['network_id']);
$network_name_select = nullable_htmlentities($net_row['network_name']);
$network_select = nullable_htmlentities($net_row['network']);
$selected = ($network_id == $network_id_select) ? 'selected' : '';
echo "<option value='$network_id_select' $selected>$network_name_select - $network_select</option>";
}
?>
</select>
</div>
</div>
<!-- Connected to (One-to-One) -->
<div class="form-group">
<label>Connected to</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-desktop"></i></span>
</div>
<select class="form-control select2" name="connected_to">
<option value="">- Select Asset and Interface -</option>
<?php
$sql_interfaces_select = mysqli_query($mysqli, "
SELECT i.interface_id, i.interface_name, a.asset_name
FROM asset_interfaces i
LEFT JOIN assets a ON a.asset_id = i.interface_asset_id
WHERE a.asset_archived_at IS NULL
AND a.asset_client_id = $client_id
AND i.interface_id != $interface_id
AND a.asset_id != $asset_id
AND (
(
i.interface_id NOT IN (SELECT interface_a_id FROM asset_interface_links)
AND i.interface_id NOT IN (SELECT interface_b_id FROM asset_interface_links)
)
OR i.interface_id = " . (int)$linked_interface_id . "
)
ORDER BY a.asset_name ASC, i.interface_name ASC
");
while ($row_if = mysqli_fetch_array($sql_interfaces_select)) {
$iface_id_select = intval($row_if['interface_id']);
$iface_name_select = nullable_htmlentities($row_if['interface_name']);
$iface_asset_name_select = nullable_htmlentities($row_if['asset_name']);
$selected = ($linked_interface_id === $iface_id_select) ? 'selected' : '';
echo "<option value='$iface_id_select' $selected>";
echo "$iface_asset_name_select - $iface_name_select";
echo "</option>";
}
?>
</select>
</div>
</div>
</div> <!-- End Network Section -->
<!-- Notes Section -->
<div class="tab-pane fade" id="pills-interface-notes<?php echo $interface_id; ?>">
<!-- Notes -->
<div class="form-group">
<textarea class="form-control" rows="8" placeholder="Enter some notes" name="notes"><?php echo $interface_notes; ?></textarea>
</div>
</div>
<!-- End Notes Section -->
</div>
</div>
<!-- End Footer Section -->
<div class="modal-footer">
<button type="submit" name="edit_asset_interface" class="btn btn-primary text-bold">
<i class="fas fa-check mr-2"></i>Save
</button>
<button type="button" class="btn btn-light" data-dismiss="modal">
<i class="fas fa-times mr-2"></i>Close
</button>
</div>
</form>
<?php
require_once '../../../includes/modal_footer.php';

View File

@@ -0,0 +1,24 @@
<div class="modal" id="exportAssetInterfaceModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Interfaces to CSV</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<input type="hidden" name="asset_id" value="<?php echo $asset_id; ?>">
<div class="modal-body">
</div>
<div class="modal-footer">
<button type="submit" name="export_client_asset_interfaces_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,28 @@
<div class="modal" id="importAssetInterfaceModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-ethernet mr-2"></i>Import Interfaces</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<input type="hidden" name="asset_id" value="<?php echo $asset_id; ?>">
<div class="modal-body">
<p><strong>Format csv file with headings & data:</strong><br>Name, Description, Type, MAC, IP, NAT IP, IPv6, Network</p>
<hr>
<div class="form-group my-4">
<input type="file" class="form-control-file" name="file" accept=".csv" required>
</div>
<hr>
<div>Download <a href="post.php?download_client_asset_interfaces_csv_template=<?php echo $asset_id; ?>">sample csv template</a></div>
</div>
<div class="modal-footer">
<button type="submit" name="import_client_asset_interfaces_csv" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Import</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,107 @@
<div class="modal" id="addMultipleAssetInterfacesModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-ethernet mr-2"></i>Creating Multiple Interfaces: <strong><?php echo $asset_name; ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="asset_id" value="<?php echo $asset_id; ?>">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<div class="modal-body">
<!-- Starting Interface Number -->
<div class="form-group">
<label for="interface_start">Starting Interface Number</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
</div>
<input type="number" id="interface_start" class="form-control" name="interface_start" placeholder="e.g., 1" min="0" required>
</div>
</div>
<!-- Number of Interfaces -->
<div class="form-group">
<label for="interfaces">Number of Interfaces / Ports</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
</div>
<input type="number" id="interfaces" class="form-control" name="interfaces" placeholder="How many interfaces to create?" min="1" required>
</div>
</div>
<!-- Type -->
<div class="form-group">
<label for="network">Type</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-plug"></i></span>
</div>
<select class="form-control select2" name="type">
<option value="">- Select Type -</option>
<?php foreach($interface_types_array as $interface_type) { ?>
<option><?php echo $interface_type; ?></option>
<?php } ?>
</select>
</div>
</div>
<!-- Interface Name -->
<div class="form-group">
<label for="name_prefix">Interface Name / Port Prefix (Optional)</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
</div>
<input type="text" id="name_prefix" class="form-control" name="name_prefix" placeholder="e.g., eth-" maxlength="200">
</div>
</div>
<!-- Network -->
<div class="form-group">
<label for="network">Network Assignment</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-network-wired"></i></span>
</div>
<select id="network" class="form-control select2" name="network">
<option value="">- Select Network -</option>
<?php
$sql_network_select = mysqli_query($mysqli, "SELECT network_id, network_name, network FROM networks WHERE network_archived_at IS NULL AND network_client_id = $client_id ORDER BY network_name ASC");
while ($row = mysqli_fetch_array($sql_network_select)) {
$network_id = $row['network_id'];
$network_name = nullable_htmlentities($row['network_name']);
$network = nullable_htmlentities($row['network']);
?>
<option value="<?php echo $network_id; ?>">
<?php echo "$network_name - $network"; ?>
</option>
<?php } ?>
</select>
</div>
<small class="form-text text-muted">Choose the network for these interfaces or leave as None.</small>
</div>
<!-- Notes -->
<div class="form-group">
<label for="notes">Additional Notes</label>
<textarea id="notes" class="form-control" rows="5" placeholder="Enter any additional details or notes" name="notes"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="add_asset_multiple_interfaces" class="btn btn-primary text-bold">
<i class="fas fa-check mr-2"></i>Create Interfaces
</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,69 @@
<?php
require_once '../../../includes/modal_header.php';
$asset_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM assets
WHERE asset_id = $asset_id
LIMIT 1
");
$row = mysqli_fetch_array($sql);
$asset_name = nullable_htmlentities($row['asset_name']);
$client_id = intval($row['asset_client_id']);
// Generate the HTML form content using output buffering.
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-key mr-2"></i>Link Credential to <strong><?php echo $asset_name; ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="asset_id" value="<?php echo $asset_id; ?>">
<div class="modal-body">
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
</div>
<select class="form-control select2" name="credential_id">
<option value="">- Select a Credential -</option>
<?php
$sql_credentials_select = mysqli_query($mysqli, "
SELECT credentials.credential_id, credentials.credential_name
FROM credentials
LEFT JOIN assets ON credentials.credential_asset_id = assets.asset_id
AND credentials.credential_asset_id = $asset_id
WHERE credentials.credential_client_id = $client_id
AND credentials.credential_asset_id = 0
AND credentials.credential_archived_at IS NULL
ORDER BY credentials.credential_name ASC
");
while ($row = mysqli_fetch_array($sql_credentials_select)) {
$credential_id = intval($row['credential_id']);
$credential_name = nullable_htmlentities($row['credential_name']);
?>
<option value="<?php echo $credential_id ?>"><?php echo $credential_name; ?></option>
<?php
}
?>
</select>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="link_asset_to_credential" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Link</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</form>
<?php
require_once '../../../includes/modal_footer.php';
?>

View File

@@ -0,0 +1,70 @@
<?php
require_once '../../../includes/modal_header.php';
$asset_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM assets
WHERE asset_id = $asset_id
LIMIT 1
");
$row = mysqli_fetch_array($sql);
$asset_name = nullable_htmlentities($row['asset_name']);
$client_id = intval($row['asset_client_id']);
// Generate the HTML form content using output buffering.
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-folder mr-2"></i>Link Document to <strong><?php echo $asset_name; ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="asset_id" value="<?php echo $asset_id; ?>">
<div class="modal-body">
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-folder"></i></span>
</div>
<select class="form-control select2" name="document_id">
<option value="">- Select a Document -</option>
<?php
$sql_documents_select = mysqli_query($mysqli, "
SELECT documents.document_id, documents.document_name
FROM documents
LEFT JOIN asset_documents
ON documents.document_id = asset_documents.document_id
AND asset_documents.asset_id = $asset_id
WHERE documents.document_client_id = $client_id
AND documents.document_archived_at IS NULL
AND asset_documents.asset_id IS NULL
ORDER BY documents.document_name ASC
");
while ($row = mysqli_fetch_array($sql_documents_select)) {
$document_id = intval($row['document_id']);
$document_name = nullable_htmlentities($row['document_name']);
?>
<option value="<?php echo $document_id ?>"><?php echo $document_name; ?></option>
<?php
}
?>
</select>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="link_asset_to_document" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Link</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</form>
<?php
require_once '../../../includes/modal_footer.php';
?>

View File

@@ -0,0 +1,73 @@
<?php
require_once '../../../includes/modal_header.php';
$asset_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM assets
WHERE asset_id = $asset_id
LIMIT 1
");
$row = mysqli_fetch_array($sql);
$asset_name = nullable_htmlentities($row['asset_name']);
$client_id = intval($row['asset_client_id']);
// Generate the HTML form content using output buffering.
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-paperclip mr-2"></i>Link File to <strong><?php echo $asset_name; ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="asset_id" value="<?php echo $asset_id; ?>">
<div class="modal-body">
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-paperclip"></i></span>
</div>
<select class="form-control select2" name="file_id">
<option value="">- Select a File -</option>
<?php
$sql_files_select = mysqli_query($mysqli, "
SELECT files.file_id, files.file_name, folders.folder_name
FROM files
LEFT JOIN asset_files
ON files.file_id = asset_files.file_id
AND asset_files.asset_id = $asset_id
LEFT JOIN folders
ON folders.folder_id = files.file_folder_id
WHERE files.file_client_id = $client_id
AND asset_files.asset_id IS NULL
ORDER BY folders.folder_name ASC, files.file_name ASC
");
while ($row = mysqli_fetch_array($sql_files_select)) {
$file_id = intval($row['file_id']);
$file_name = nullable_htmlentities($row['file_name']);
$folder_name = nullable_htmlentities($row['folder_name']);
?>
<option value="<?php echo $file_id ?>"><?php echo "$folder_name/$file_name"; ?></option>
<?php
}
?>
</select>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="link_asset_to_file" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Link</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</form>
<?php
require_once '../../../includes/modal_footer.php';
?>

View File

@@ -0,0 +1,68 @@
<?php
require_once '../../../includes/modal_header.php';
$asset_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM assets
WHERE asset_id = $asset_id
LIMIT 1
");
$row = mysqli_fetch_array($sql);
$asset_name = nullable_htmlentities($row['asset_name']);
$client_id = intval($row['asset_client_id']);
// Generate the HTML form content using output buffering.
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-stream mr-2"></i>Link Service to <strong><?php echo $asset_name; ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="asset_id" value="<?php echo $asset_id; ?>">
<div class="modal-body">
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-stream"></i></span>
</div>
<select class="form-control select2" name="service_id">
<option value="">- Select a Service -</option>
<?php
$sql_services_select = mysqli_query($mysqli, "
SELECT services.service_id, services.service_name
FROM services
LEFT JOIN service_assets
ON services.service_id = service_assets.service_id
AND service_assets.asset_id = $asset_id
WHERE services.service_client_id = $client_id
AND service_assets.asset_id IS NULL
ORDER BY services.service_name ASC
");
while ($row = mysqli_fetch_array($sql_services_select)) {
$service_id = intval($row['service_id']);
$service_name = nullable_htmlentities($row['service_name']);
?>
<option value="<?php echo $service_id ?>"><?php echo $service_name; ?></option>
<?php
}
?>
</select>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="link_service_to_asset" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Link</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</form>
<?php
require_once '../../../includes/modal_footer.php';

View File

@@ -0,0 +1,73 @@
<?php
require_once '../../../includes/modal_header.php';
$asset_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM assets
WHERE asset_id = $asset_id
LIMIT 1
");
$row = mysqli_fetch_array($sql);
$asset_name = nullable_htmlentities($row['asset_name']);
$client_id = intval($row['asset_client_id']);
// Generate the HTML form content using output buffering.
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-cube mr-2"></i>License Software to <strong><?php echo $asset_name; ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="asset_id" value="<?php echo $asset_id; ?>">
<div class="modal-body">
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-cube"></i></span>
</div>
<select class="form-control select2" name="software_id">
<option value="">- Select a Device Software License -</option>
<?php
$sql_software_select = mysqli_query($mysqli, "
SELECT software.software_id, software.software_name
FROM software
LEFT JOIN software_assets
ON software.software_id = software_assets.software_id
AND software_assets.asset_id = $asset_id
WHERE software.software_client_id = $client_id
AND software.software_archived_at IS NULL
AND software.software_license_type = 'Device'
AND software_assets.asset_id IS NULL
ORDER BY software.software_name ASC
");
while ($row = mysqli_fetch_array($sql_software_select)) {
$software_id = intval($row['software_id']);
$software_name = nullable_htmlentities($row['software_name']);
?>
<option value="<?php echo $software_id ?>"><?php echo $software_name; ?></option>
<?php
}
?>
</select>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="link_software_to_asset" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Link</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</form>
<?php
require_once '../../../includes/modal_footer.php';

View File

@@ -0,0 +1,41 @@
<div class="modal" id="addCalendarModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-calendar-plus mr-2"></i>New Calendar</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<div class="modal-body">
<div class="form-group">
<label>Name</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Name your calendar" maxlength="200" required autofocus>
</div>
</div>
<div class="form-group">
<label>Color <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-paint-brush"></i></span>
</div>
<input type="color" class="form-control col-3" name="color" required>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="add_calendar" class="btn btn-primary"><i class="fa fa-check mr-2"></i>Create</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,55 @@
<?php
require_once '../../../includes/modal_header.php';
$calendar_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM calendars WHERE calendar_id = $calendar_id LIMIT 1");
$row = mysqli_fetch_array($sql);
$calendar_name = nullable_htmlentities($row['calendar_name']);
$calendar_color = nullable_htmlentities($row['calendar_color']);
// Generate the HTML form content using output buffering.
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-circle mr-2" style="color:<?php echo $calendar_color; ?>"></i><?php echo $calendar_name; ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="calendar_id" value="<?php echo $calendar_id; ?>">
<div class="modal-body">
<div class="form-group">
<label>Name</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Name your calendar" maxlength="200" value="<?php echo $calendar_name; ?>" required>
</div>
</div>
<div class="form-group">
<label>Color <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-paint-brush"></i></span>
</div>
<input type="color" class="form-control col-3" name="color" value="<?php echo $calendar_color; ?>" required>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="edit_calendar" class="btn btn-primary"><i class="fa fa-check mr-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</form>
<?php
require_once '../../../includes/modal_footer.php';

View File

@@ -0,0 +1,171 @@
<div class="modal" id="addCalendarEventModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-calendar-plus mr-2"></i>New Event</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<div class="modal-body">
<ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-event"><i class="fa fa-fw fa-calendar mr-2"></i>Event</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-details"><i class="fa fa-fw fa-info-circle mr-2"></i>Details</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-attendees"><i class="fa fa-fw fa-users mr-2"></i>Attendees</a>
</li>
</ul>
<hr>
<div class="tab-content">
<div class="tab-pane fade show active" id="pills-event">
<div class="form-group">
<label>Title <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>
<input type="text" class="form-control" name="title" placeholder="Title of the event" maxlength="200" required autofocus>
</div>
</div>
<div class="form-group">
<label>Calendar <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"></i></span>
</div>
<select class="form-control select2" name="calendar" required>
<option value="">- Calendar -</option>
<?php
$sql = mysqli_query($mysqli, "SELECT * FROM calendars ORDER BY calendar_name ASC");
while ($row = mysqli_fetch_array($sql)) {
$calendar_id = intval($row['calendar_id']);
$calendar_name = nullable_htmlentities($row['calendar_name']);
$calendar_color = nullable_htmlentities($row['calendar_color']);
?>
<option <?php if ($config_default_calendar == $calendar_id) { echo "selected"; } ?> data-content="<i class='fa fa-circle mr-2' style='color:<?php echo $calendar_color; ?>;'></i> <?php echo $calendar_name; ?>" value="<?php echo $calendar_id; ?>"><?php echo $calendar_name; ?></option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group">
<label>Start / End <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-check"></i></span>
</div>
<input type="datetime-local" class="form-control" id="event_add_start" name="start" required onblur="updateIncrementEndTime()">
</div>
</div>
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="datetime-local" class="form-control" id="event_add_end" name="end" required>
</div>
</div>
<div class="form-group">
<label>Repeat</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-recycle"></i></span>
</div>
<select class="form-control select2" name="repeat" disabled>
<option value="">Never</option>
<option>Day</option>
<option>Week</option>
<option>Month</option>
<option>Year</option>
</select>
</div>
</div>
</div>
<div class="tab-pane fade" id="pills-details">
<div class="form-group">
<label>Location</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-map-marker-alt"></i></span>
</div>
<input type="text" class="form-control" name="location" placeholder="Location of the event">
</div>
</div>
<div class="form-group">
<textarea class="form-control" rows="8" name="description" placeholder="Enter a description"></textarea>
</div>
</div>
<div class="tab-pane fade" id="pills-attendees">
<?php if (isset($client_id)) { ?>
<input type="hidden" name="client" value="<?php echo $client_id; ?>">
<?php } else{ ?>
<div class="form-group">
<label>Client</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<select class="form-control select2" name="client">
<option value="">- Client -</option>
<?php
$sql = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN contacts ON clients.client_id = contacts.contact_client_id AND contact_primary = 1 ORDER BY client_name ASC");
while ($row = mysqli_fetch_array($sql)) {
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
$contact_email = nullable_htmlentities($row['contact_email']);
?>
<option value="<?php echo $client_id; ?>"><?php echo $client_name; ?></option>
<?php } ?>
</select>
</div>
</div>
<?php } ?>
<?php if (!empty($config_smtp_host)) { ?>
<div class="form-group">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="emailEventCheckbox" name="email_event" value="1" >
<label class="custom-control-label" for="emailEventCheckbox">Email Event</label>
</div>
</div>
<?php } ?>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="add_event" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,194 @@
<?php
require_once '../../../includes/modal_header.php';
$event_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM calendar_events LEFT JOIN calendars ON event_calendar_id = calendar_id WHERE event_id = $event_id LIMIT 1");
$row = mysqli_fetch_array($sql);
$event_title = nullable_htmlentities($row['event_title']);
$event_description = nullable_htmlentities($row['event_description']);
$event_location = nullable_htmlentities($row['event_location']);
$event_start = nullable_htmlentities($row['event_start']);
$event_end = nullable_htmlentities($row['event_end']);
$event_repeat = nullable_htmlentities($row['event_repeat']);
$calendar_id = intval($row['calendar_id']);
$calendar_name = nullable_htmlentities($row['calendar_name']);
$calendar_color = nullable_htmlentities($row['calendar_color']);
$client_id = intval($row['event_client_id']);
// Generate the HTML form content using output buffering.
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-calendar mr-2" style="color:<?php echo $calendar_color; ?>"></i><?php echo $event_title; ?></h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="event_id" value="<?php echo $event_id; ?>">
<div class="modal-body">
<ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-event<?php echo $event_id; ?>"><i class="fa fa-fw fa-calendar mr-2"></i>Event</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-details<?php echo $event_id; ?>"><i class="fa fa-fw fa-info-circle mr-2"></i>Details</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-attendees<?php echo $event_id; ?>"><i class="fa fa-fw fa-users mr-2"></i>Attendees</a>
</li>
</ul>
<hr>
<div class="tab-content">
<div class="tab-pane fade show active" id="pills-event<?php echo $event_id; ?>">
<div class="form-group">
<label>Title <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>
<input type="text" class="form-control" name="title" maxlength="200" value="<?php echo $event_title; ?>" placeholder="Title of the event" required>
</div>
</div>
<div class="form-group">
<label>Calendar <strong class="text-danger">*</strong></label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-calendar"></i></span>
</div>
<select class="form-control select2" name="calendar" required>
<?php
$sql_calendars_select = mysqli_query($mysqli, "SELECT * FROM calendars ORDER BY calendar_name ASC");
while ($row = mysqli_fetch_array($sql_calendars_select)) {
$calendar_id_select = intval($row['calendar_id']);
$calendar_name_select = nullable_htmlentities($row['calendar_name']);
$calendar_color_select = nullable_htmlentities($row['calendar_color']);
?>
<option data-content="<i class='fa fa-circle mr-2' style='color:<?php echo $calendar_color_select; ?>;'></i> <?php echo $calendar_name_select; ?>"<?php if ($calendar_id == $calendar_id_select) { echo "selected"; } ?> value="<?php echo $calendar_id_select; ?>"><?php echo $calendar_name_select; ?></option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group">
<label>Start / End <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-check"></i></span>
</div>
<input type="datetime-local" class="form-control" name="start" value="<?php echo date('Y-m-d\TH:i:s', strtotime($event_start)); ?>" required>
</div>
</div>
<div class="form-group">
<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>
<input type="datetime-local" class="form-control" name="end" value="<?php echo date('Y-m-d\TH:i:s', strtotime($event_end)); ?>"required>
</div>
</div>
<div class="form-group">
<label>Repeat</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-recycle"></i></span>
</div>
<select class="form-control select2" name="repeat" disabled>
<option <?php if (empty($event_repeat)) { echo "selected"; } ?> value="">Never</option>
<option <?php if ($event_repeat == "Day") { echo "selected"; } ?>>Day</option>
<option <?php if ($event_repeat == "Week") { echo "selected"; } ?>>Week</option>
<option <?php if ($event_repeat == "Month") { echo "selected"; } ?>>Month</option>
<option <?php if ($event_repeat == "Year") { echo "selected"; } ?>>Year</option>
</select>
</div>
</div>
</div>
<div class="tab-pane fade" id="pills-details<?php echo $event_id; ?>">
<div class="form-group">
<label>Location</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-map-marker-alt"></i></span>
</div>
<input type="text" class="form-control" name="location" value="<?php echo $event_location; ?>" placeholder="Location of the event">
</div>
</div>
<div class="form-group">
<label>Description</label>
<textarea class="form-control" rows="8" name="description" placeholder="Enter a description"><?php echo $event_description; ?></textarea>
</div>
</div>
<div class="tab-pane fade" id="pills-attendees<?php echo $event_id; ?>">
<?php if (isset($_GET['client_id'])) { ?>
<input type="hidden" name="client" value="<?php echo $client_id; ?>">
<?php } else { ?>
<div class="form-group">
<label>Client</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<select class="form-control select2" name="client">
<option value="">- Client -</option>
<?php
$sql_clients = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN contacts ON clients.client_id = contacts.contact_client_id AND contact_primary = 1 ORDER BY client_name ASC");
while ($row = mysqli_fetch_array($sql_clients)) {
$client_id_select = intval($row['client_id']);
$client_name_select = nullable_htmlentities($row['client_name']);
$contact_email_select = nullable_htmlentities($row['contact_email']);
?>
<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>
<?php } ?>
<?php if (!empty($config_smtp_host)) { ?>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="customControlAutosizing<?php echo $event_id; ?>" name="email_event" value="1" >
<label class="custom-control-label" for="customControlAutosizing<?php echo $event_id; ?>">Email Event</label>
</div>
<?php } ?>
</div>
</div>
</div>
<div class="modal-footer">
<a class="btn btn-default text-danger mr-auto" href="post.php?delete_event=<?php echo $event_id; ?>"><i class="fa fa-calendar-times mr-2"></i>Delete</a>
<button type="submit" name="edit_event" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</form>
<?php
require_once '../../../includes/modal_footer.php';

View File

@@ -0,0 +1,166 @@
<div class="modal" id="addCertificateModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-lock mr-2"></i>New Certificate</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<div class="modal-body">
<ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-details">Details</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-certificate">Certificate</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-notes">Notes</a>
</li>
</ul>
<hr>
<div class="tab-content">
<div class="tab-pane fade show active" id="pills-details">
<?php if ($client_url) { ?>
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<?php } else { ?>
<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-user"></i></span>
</div>
<select class="form-control select2" name="client_id" required>
<option value="">- Select Client -</option>
<?php
$sql = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE client_archived_at IS NULL $access_permission_query ORDER BY client_name ASC");
while ($row = mysqli_fetch_array($sql)) {
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']); ?>
<option <?php if ($client_id == isset($_GET['client'])) { echo "selected"; } ?> value="<?php echo $client_id; ?>"><?php echo $client_name; ?></option>
<?php } ?>
</select>
</div>
</div>
<?php } ?>
<div class="form-group">
<label>Certificate Name <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-lock"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Certificate name" maxlength="200" required autofocus>
</div>
</div>
<div class="form-group">
<label>Description</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
</div>
<input type="text" class="form-control" name="description" placeholder="Short Description">
</div>
</div>
<?php if ($client_url) { ?>
<div class="form-group">
<label>Domain</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span>
</div>
<select class="form-control select2" name="domain_id">
<option value="">- Domain -</option>
<?php
$domains_sql = mysqli_query($mysqli, "SELECT * FROM domains WHERE domain_archived_at IS NULL AND domain_client_id = $client_id ORDER BY domain_name ASC");
while ($domain_row = mysqli_fetch_array($domains_sql)) {
$domain_id = intval($domain_row['domain_id']);
$domain_name = nullable_htmlentities($domain_row['domain_name']);
echo "<option value=\"$domain_id\">$domain_name</option>";
}
?>
</select>
</div>
</div>
<?php } ?>
</div>
<div class="tab-pane fade" id="pills-certificate">
<div class="form-group">
<label>Domain <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-globe"></i>&nbsp;https://</span>
</div>
<input type="text" class="form-control" name="domain" id="domain" placeholder="FQDN" maxlength="200" required>
<div class="input-group-append">
<button type="button" class="btn btn-secondary" onclick="fetchSSL('new')"><i class="fas fa-fw fa-sync-alt"></i></button>
</div>
</div>
</div>
<div class="form-group">
<label>Issued By </label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-building"></i></span>
</div>
<input type="text" class="form-control" name="issued_by" id="issuedBy" placeholder="Issued By" maxlength="200">
</div>
</div>
<div class="form-group">
<label>Expire Date</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar-times"></i></span>
</div>
<input type="date" class="form-control" name="expire" id="expire" max="2999-12-31">
</div>
</div>
<div class="form-group">
<label>Public Key </label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
</div>
<textarea class="form-control" rows="8" name="public_key" id="publicKey" placeholder="-----BEGIN CERTIFICATE-----"></textarea>
</div>
</div>
</div>
<div class="tab-pane fade" id="pills-notes">
<div class="form-group">
<textarea class="form-control" rows="12" placeholder="Enter some notes" name="notes"></textarea>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="add_certificate" class="btn btn-primary text-bold"><i class="fa fa-check"></i> Create</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,197 @@
<?php
require_once '../../../includes/modal_header.php';
$certificate_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM certificates WHERE certificate_id = $certificate_id LIMIT 1");
$row = mysqli_fetch_array($sql);
$certificate_name = nullable_htmlentities($row['certificate_name']);
$certificate_description = nullable_htmlentities($row['certificate_description']);
$certificate_domain = nullable_htmlentities($row['certificate_domain']);
$certificate_domain_id = intval($row['certificate_domain_id']);
$certificate_issued_by = nullable_htmlentities($row['certificate_issued_by']);
$certificate_public_key = nullable_htmlentities($row['certificate_public_key']);
$certificate_notes = nullable_htmlentities($row['certificate_notes']);
$certificate_expire = nullable_htmlentities($row['certificate_expire']);
$certificate_created_at = nullable_htmlentities($row['certificate_created_at']);
$client_id = intval($row['certificate_client_id']);
$history_sql = mysqli_query($mysqli, "SELECT * FROM certificate_history WHERE certificate_history_certificate_id = $certificate_id");
// Generate the HTML form content using output buffering.
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-lock mr-2"></i>Editing certificate: <span class="text-bold"><?php echo $certificate_name; ?></span></h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="certificate_id" value="<?php echo $certificate_id; ?>">
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<div class="modal-body">
<ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pillsEditDetails<?php echo $certificate_id; ?>">Details</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pillsEditCertificate<?php echo $certificate_id; ?>">Certificate</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pillsEditNotes<?php echo $certificate_id; ?>">Notes</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pillsEditHistory<?php echo $certificate_id; ?>">History</a>
</li>
</ul>
<hr>
<div class="tab-content" <?php if (lookupUserPermission('module_support') <= 1) { echo 'inert'; } ?>>
<div class="tab-pane fade show active" id="pillsEditDetails<?php echo $certificate_id; ?>">
<div class="form-group">
<label>Certificate Name <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-lock"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Certificate name" maxlength="200" value="<?php echo $certificate_name; ?>" required>
</div>
</div>
<div class="form-group">
<label>Description</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
</div>
<input type="text" class="form-control" name="description" placeholder="Short Description" value="<?php echo $certificate_description; ?>">
</div>
</div>
<div class="form-group">
<label>Domain</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span>
</div>
<select class="form-control select2" name="domain_id">
<option value="">- Select Domain -</option>
<?php
$domains_sql = mysqli_query($mysqli, "SELECT domain_id, domain_name FROM domains WHERE domain_client_id = $client_id");
while ($row = mysqli_fetch_array($domains_sql)) {
$domain_id = intval($row['domain_id']);
$domain_name = nullable_htmlentities($row['domain_name']);
?>
<option value="<?php echo $domain_id; ?>" <?php if ($certificate_domain_id == $domain_id) { echo "selected"; } ?>><?php echo $domain_name; ?></option>
<?php } ?>
</select>
</div>
</div>
</div>
<div class="tab-pane fade" id="pillsEditCertificate<?php echo $certificate_id; ?>">
<div class="form-group">
<label>Domain <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-globe"></i>&nbsp;https://</span>
</div>
<input type="text" class="form-control" name="domain" id="editCertificateDomain" placeholder="Domain" maxlength="200" value="<?php echo $certificate_domain; ?>" required>
<div class="input-group-append">
<button type="button" class="btn btn-secondary" onclick="fetchSSL('edit')"><i class="fas fa-fw fa-sync-alt"></i></button>
</div>
</div>
</div>
<div class="form-group">
<label>Issued By</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-building"></i></span>
</div>
<input type="text" class="form-control" name="issued_by" id="editCertificateIssuedBy" maxlength="200" placeholder="Issued By" value="<?php echo $certificate_issued_by; ?>">
</div>
</div>
<div class="form-group">
<label>Expire Date</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar-times"></i></span>
</div>
<input type="date" class="form-control" name="expire" id="editCertificateExpire" max="2999-12-31" value="<?php echo $certificate_expire; ?>">
</div>
</div>
<div class="form-group">
<label>Public Key </label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
</div>
<textarea class="form-control" rows="8" name="public_key" id="editCertificatePublicKey"><?php echo $certificate_public_key; ?></textarea>
</div>
</div>
</div>
<div class="tab-pane fade" id="pillsEditNotes<?php echo $certificate_id; ?>">
<div class="form-group">
<textarea class="form-control" name="notes" rows="12" placeholder="Enter some notes"><?php echo $certificate_notes; ?></textarea>
</div>
</div>
<div class="tab-pane fade" id="pillsEditHistory<?php echo $certificate_id; ?>">
<div class="table-responsive">
<table class='table table-sm table-striped border table-hover'>
<thead class='thead-dark'>
<tr>
<th>Date</th>
<th>Field</th>
<th>Before</th>
<th>After</th>
</tr>
</thead>
<tbody>
<?php
while ($row = mysqli_fetch_array($history_sql)) {
$certificate_modified_at = nullable_htmlentities($row['certificate_history_modified_at']);
$certificate_field = nullable_htmlentities($row['certificate_history_column']);
$certificate_before_value = nullable_htmlentities($row['certificate_history_old_value']);
$certificate_after_value = nullable_htmlentities($row['certificate_history_new_value']);
?>
<tr>
<td><?php echo $certificate_modified_at; ?></td>
<td><?php echo $certificate_field; ?></td>
<td><?php echo $certificate_before_value; ?></td>
<td><?php echo $certificate_after_value; ?></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="edit_certificate" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</form>
<?php
require_once '../../../includes/modal_footer.php';

View File

@@ -0,0 +1,24 @@
<div class="modal" id="exportCertificateModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Certificates to CSV</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<?php if ($client_url) { ?>
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<?php } ?>
<div class="modal-body">
</div>
<div class="modal-footer">
<button type="submit" name="export_certificates_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,385 @@
<div class="modal" id="addClientModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content border-dark">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-user-plus mr-2"></i>Creating New <?php if($leads_filter == 0){ echo "Client"; } else { echo "Lead"; } ?></h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<ul class="modal-header nav nav-pills nav-justified">
<li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-details">Details</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-location">Location</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-contact" id="contactNavPill">Contact</a>
</li>
<?php if ($config_module_enable_accounting) { ?>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-billing">Billing</a>
</li>
<?php } ?>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-notes">Notes</a>
</li>
</ul>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<div class="modal-body">
<div class="tab-content">
<div class="tab-pane fade show active" id="pills-details">
<div class="form-group">
<label>Name <strong class="text-danger">*</strong> / <span class="text-secondary">Is Lead</span></label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<input type="text" class="form-control" name="name" placeholder="Name or Company" maxlength="200" required autofocus>
<div class="input-group-append">
<div class="input-group-text">
<input type="checkbox" name="lead" value="1" <?php if($leads_filter == 1){ echo "checked"; } ?>>
</div>
</div>
</div>
</div>
<div class="form-group">
<label>Shortened Name</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-id-badge"></i></span>
</div>
<input type="text" class="form-control" name="abbreviation" placeholder="Shortned name for client - Max chars 6" maxlength="6" oninput="this.value = this.value.toUpperCase()">
</div>
</div>
<div class="form-group">
<label>Industry</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-briefcase"></i></span>
</div>
<input type="text" class="form-control" name="type" placeholder="Company Type" maxlength="200">
</div>
</div>
<div class="form-group">
<label>Referral</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-link"></i></span>
</div>
<select class="form-control select2" data-tags="true" name="referral">
<option value="">- Select Referral -</option>
<?php
$referral_sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Referral' AND category_archived_at IS NULL ORDER BY category_name ASC");
while ($row = mysqli_fetch_array($referral_sql)) {
$referral = nullable_htmlentities($row['category_name']); ?>
<option><?php echo $referral; ?></option>
<?php } ?>
</select>
<div class="input-group-append">
<button class="btn btn-secondary ajax-modal" type="button"
data-modal-url="../admin/modals/category/category_add.php?category=Referral">
<i class="fas fa-fw fa-plus"></i>
</button>
</div>
</div>
</div>
<div class="form-group">
<label>Website</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span>
</div>
<input type="text" class="form-control" name="website" placeholder="ex. google.com" maxlength="200">
</div>
</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="- Select Tags -"multiple>
<?php
$sql_tags_select = mysqli_query($mysqli, "SELECT * FROM tags WHERE tag_type = 1 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 class="input-group-append">
<button class="btn btn-secondary ajax-modal" type="button"
data-modal-url="../admin/modals/tag/tag_add.php?type=1">
<i class="fas fa-fw fa-plus"></i>
</button>
</div>
</div>
</div>
</div>
<div class="tab-pane fade" id="pills-location">
<div class="form-group">
<label>Address</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-map-marker-alt"></i></span>
</div>
<input type="text" class="form-control" name="address" placeholder="Street Address" maxlength="200">
</div>
</div>
<div class="form-group">
<label>City</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-city"></i></span>
</div>
<input type="text" class="form-control" name="city" placeholder="City" maxlength="200">
</div>
</div>
<div class="form-group">
<label>State / Province</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-flag"></i></span>
</div>
<input type="text" class="form-control" name="state" placeholder="State or Province" maxlength="200">
</div>
</div>
<div class="form-group">
<label>Postal Code</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fab fa-fw fa-usps"></i></span>
</div>
<input type="text" class="form-control" name="zip" placeholder="Zip or Postal Code" maxlength="200">
</div>
</div>
<div class="form-group">
<label>Country</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-globe-americas"></i></span>
</div>
<select class="form-control select2" name="country">
<option value="">- Select Country -</option>
<?php foreach($countries_array as $country_name) { ?>
<option <?php if ($session_company_country == $country_name) { echo "selected"; } ?> ><?php echo $country_name; ?></option>
<?php } ?>
</select>
</div>
</div>
<label>Location Phone / <span class="text-secondary">Extension</span></label>
<div class="form-row">
<div class="col-9">
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-phone"></i></span>
</div>
<input type="tel" class="form-control col-2" name="location_phone_country_code" placeholder="+" maxlength="4">
<input type="tel" class="form-control" name="location_phone" placeholder="Phone Number" maxlength="200">
</div>
</div>
</div>
<div class="col-3">
<div class="form-group">
<input type="text" class="form-control" name="location_extension" placeholder="ext." maxlength="200">
</div>
</div>
</div>
<label>Location Fax</label>
<div class="form-row">
<div class="col-9">
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-fax"></i></span>
</div>
<input type="tel" class="form-control col-2" name="location_fax_country_code" placeholder="+" maxlength="4">
<input type="tel" class="form-control" name="location_fax" placeholder="Fax Number">
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane fade" id="pills-contact">
<div class="form-group">
<label>Primary Contact <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-user-check"></i></span>
</div>
<input type="text" class="form-control" id="primaryContact" name="contact" placeholder="Primary Contact Person" maxlength="200" required autofocus>
</div>
</div>
<div class="form-group">
<label>Title</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-id-badge"></i></span>
</div>
<input type="text" class="form-control" name="title" placeholder="Title" maxlength="200">
</div>
</div>
<label>Contact Phone / <span class="text-secondary">Extension</span></label>
<div class="form-row">
<div class="col-9">
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-phone"></i></span>
</div>
<input type="tel" class="form-control col-2" name="contact_phone_country_code" placeholder="+" maxlength="4">
<input type="tel" class="form-control" name="contact_phone" placeholder="Phone Number" maxlength="200">
</div>
</div>
</div>
<div class="col-3">
<div class="form-group">
<input type="text" class="form-control" name="contact_extension" placeholder="ext." maxlength="200">
</div>
</div>
</div>
<label>Mobile</label>
<div class="form-row">
<div class="col-9">
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-mobile-alt"></i></span>
</div>
<input type="tel" class="form-control col-2" name="contact_mobile_country_code" placeholder="+" maxlength="4">
<input type="tel" class="form-control" name="contact_mobile" placeholder="Mobile Phone Number">
</div>
</div>
</div>
</div>
<div class="form-group">
<label>Contact Email</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-envelope"></i></span>
</div>
<input type="email" class="form-control" name="contact_email" placeholder="Contact's Email Address" maxlength="200">
</div>
</div>
</div>
<?php if ($config_module_enable_accounting) { ?>
<div class="tab-pane fade" id="pills-billing">
<div class="form-group">
<label>Hourly Rate</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
</div>
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="rate" placeholder="0.00" value="<?php echo "$config_default_hourly_rate"; ?>">
</div>
</div>
<div class="form-group">
<label>Currency <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-money-bill"></i></span>
</div>
<select class="form-control select2" name="currency_code" required>
<option value="">- Select Currency -</option>
<?php foreach($currencies_array as $currency_code => $currency_name) { ?>
<option <?php if ($session_company_currency == $currency_code) { echo "selected"; } ?> value="<?php echo $currency_code; ?>"><?php echo "$currency_code - $currency_name"; ?></option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group">
<label>Payment Terms</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<select class="form-control select2" name="net_terms">
<?php foreach($net_terms_array as $net_term_value => $net_term_name) { ?>
<option <?php if ($config_default_net_terms == $net_term_value) { echo "selected"; } ?> value="<?php echo $net_term_value; ?>"><?php echo $net_term_name; ?></option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group">
<label>Tax ID</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-balance-scale"></i></span>
</div>
<input type="text" class="form-control" name="tax_id_number" placeholder="Tax ID Number" maxlength="255">
</div>
</div>
</div>
<?php } ?>
<div class="tab-pane fade" id="pills-notes">
<div class="form-group">
<textarea class="form-control" rows="10" name="notes" placeholder="Enter some notes"></textarea>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="add_client" class="btn btn-primary text-bold" onclick="promptPrimaryContact()"><i class="fa fa-check mr-2"></i>Create</button>
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Close</button>
</div>
</form>
</div>
</div>
</div>
<script>
// Checks/prompts that the primary contact field (required) is populated
function promptPrimaryContact() {
let primaryContactField = document.getElementById("primaryContact").value;
if (primaryContactField == null || primaryContactField === "") {
document.getElementById("contactNavPill").click();
}
}
</script>

View File

@@ -0,0 +1,48 @@
<div class="modal" id="bulkAssignTagsModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-tags mr-2"></i>Bulk Assign Tags</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<input type="hidden" name="bulk_remove_tags" value="0">
<div class="form-group form-check">
<input type="checkbox" class="form-check-input" name="bulk_remove_tags" value="1">
<label class="form-check-label text-danger">Remove Existing Tags</label>
</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="bulk_tags[]" data-placeholder="Add some tags" multiple>
<?php
$sql_tags_select = mysqli_query($mysqli, "SELECT * FROM tags WHERE tag_type = 1 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 class="modal-footer">
<button type="submit" name="bulk_assign_client_tags" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Assign</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,31 @@
<div class="modal" id="bulkEditHourlyRateModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-clock mr-2"></i>Bulk Edit Hourly Rate</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label>Hourly Rate</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
</div>
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="bulk_rate" placeholder="0.00">
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="bulk_edit_client_hourly_rate" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Assign</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,31 @@
<div class="modal" id="bulkEditIndustryModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-briefcase mr-2"></i>Bulk Edit Industry</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label>Industry</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-briefcase"></i></span>
</div>
<input type="text" class="form-control" name="bulk_industry" placeholder="Enter an Industry" maxlength="200">
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="bulk_edit_client_industry" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Assign</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,49 @@
<div class="modal" id="bulkEditReferralModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-link mr-2"></i>Bulk Edit Referral</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label>Referral</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-link"></i></span>
</div>
<select class="form-control select2" name="bulk_referral">
<option value="">- Select a Referral -</option>
<?php
$referral_sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Referral' AND category_archived_at IS NULL ORDER BY category_name ASC");
while ($row = mysqli_fetch_array($referral_sql)) {
$referral = nullable_htmlentities($row['category_name']); ?>
<option><?php echo $referral; ?></option>
<?php } ?>
</select>
<div class="input-group-append">
<button class="btn btn-secondary" type="button"
data-toggle="ajax-modal"
data-modal-size="sm"
data-ajax-url="ajax/ajax_category_add.php?category=Referral">
<i class="fas fa-fw fa-plus"></i>
</button>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="bulk_edit_client_referral" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Assign</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,100 @@
<div class="modal" id="bulkSendEmailModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-envelope-open mr-2"></i>Bulk Send Email</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<label>From Email / <span class="text-secondary">Display Name</span></label>
<div class="form-row">
<div class="form-group col-sm-6">
<select type="text" class="form-control select2" name="mail_from">
<option value="<?php echo nullable_htmlentities($config_mail_from_email); ?>">
<?php echo nullable_htmlentities("$config_mail_from_name - $config_mail_from_email"); ?></option>
<option value="<?php echo nullable_htmlentities($config_invoice_from_email); ?>">
<?php echo nullable_htmlentities("$config_invoice_from_name - $config_invoice_from_email"); ?></option>
<option value="<?php echo nullable_htmlentities($config_quote_from_email); ?>">
<?php echo nullable_htmlentities("$config_quote_from_name - $config_quote_from_email"); ?></option>
<option value="<?php echo nullable_htmlentities($config_ticket_from_email); ?>">
<?php echo nullable_htmlentities("$config_ticket_from_name - $config_ticket_from_email"); ?></option>
</select>
</div>
<div class="form-group col-sm-6">
<input type="text" class="form-control" name="mail_from_name" placeholder="From Name" maxlength="255"
value="<?php echo nullable_htmlentities($config_mail_from_name); ?>">
</div>
</div>
<label>Recipients</label>
<div class="form-row">
<div class="col-md-3">
<div class="form-group">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="contactPrimaryCheckbox" name="primary_contacts" value="1">
<label class="custom-control-label" for="contactPrimaryCheckbox">Primary Contacts</label>
</div>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="contactImportantCheckbox" name="important_contacts" value="1">
<label class="custom-control-label" for="contactImportantCheckbox">Important Contacts</label>
</div>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="contactBillingCheckbox" name="billing_contacts" value="1">
<label class="custom-control-label" for="contactBillingCheckbox">Billing Contacts</label>
</div>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="contactTechnicalCheckbox" name="technical_contacts" value="1">
<label class="custom-control-label" for="contactTechnicalCheckbox">Technical Contacts</label>
</div>
</div>
</div>
</div>
<div class="form-group">
<input type="text" class="form-control" name="subject" placeholder="Subject" maxlength="255">
</div>
<div class="form-group">
<textarea class="form-control tinymce" name="body"
placeholder="Type an email in here"></textarea>
</div>
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="datetime-local" class="form-control" name="queued_at">
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="bulk_send_client_email" class="btn btn-primary text-bold"><i class="fas fa-paper-plane mr-2"></i>Send</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,97 @@
<div class="modal" id="addCreditModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content border-dark">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-wallet mr-2"></i>Adding <strong>Credit</strong> (Credit Balance: <?php echo numfmt_format_currency($currency_format, $credit_balance, $client_currency_code); ?>)</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<div class="modal-body">
<div class="form-group">
<label>Expire</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>
<input type="date" class="form-control" name="expire" max="2999-12-31">
</div>
</div>
<div class="form-group">
<label>Type<strong class="text-danger ml-2">*</strong></label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-th-list"></i></span>
</div>
<select class="form-control select2" name="type" required>
<option value="0">- Select Credit Type -</option>
<option value="manual">Manual</option>
<option value="prepaid">Prepaid</option>
<option value="promotion">Promotion</option>
</select>
</div>
</div>
<div class="form-group">
<label>Amount<strong class="text-danger ml-2">*</strong></label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-dollar-sign"></i></span>
</div>
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="amount" placeholder="0.00" required>
</div>
</div>
<div class="form-group">
<label>Note<strong class="text-danger ml-2">*</strong></label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-file-alt"></i></span>
</div>
<input type="text" class="form-control" name="note" placeholder="Enter a note" maxlength="250">
</div>
</div>
<?php if (isset($_GET['client_id'])) { ?>
<input type="hidden" name="client" value="<?php echo $client_id; ?>">
<?php } else { ?>
<div class="form-group">
<label>Client</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<select class="form-control select2" name="client" required>
<option value="0">- Client (Optional) -</option>
<?php
$sql = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients ORDER BY client_name ASC");
while ($row = mysqli_fetch_array($sql)) {
$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>
</div>
<?php } ?>
</div>
<div class="modal-footer">
<button type="submit" name="add_credit" class="btn btn-primary text-bold"><i class="fa fa-fw fa-check mr-2"></i>Add</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,20 @@
<div class="modal" id="deleteClientModal<?php echo $client_id; ?>" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<div class="mb-4" style="text-align: center;">
<i class="far fa-10x fa-times-circle text-danger mb-3 mt-3"></i>
<h2>Are you really, really, really sure?</h2>
<h6 class="mb-4 text-secondary">Do you really want to <b>delete <?php echo $client_name; ?> and ALL associated data</b>? This includes <?php echo $client_name; ?>'s documents, tickets, files, financial data, logs, etc. <br><br>This process cannot be undone.</h6>
<div class="form-group">
<input type="hidden" id="clientName<?php echo $client_id ?>" value="<?php echo $client_name; ?>">
<input class="form-control" type="text" id="clientNameProvided<?php echo $client_id ?>" onkeyup="validateClientNameDelete(<?php echo $client_id ?>)" placeholder="Type '<?php echo $client_name; ?>' to confirm data deletion">
</div>
<button type="button" class="btn btn-outline-secondary btn-lg px-5 mr-4" data-dismiss="modal">Cancel</button>
<a class="btn btn-danger btn-lg px-5 disabled" id="clientDeleteButton<?php echo $client_id ?>" href="post.php?delete_client=<?php echo $client_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">Yes, Delete!</a>
</div>
</div>
</div>
</div>
</div>
<script src="../js/client_delete_confirm.js"></script>

View File

@@ -0,0 +1,185 @@
<div class="modal" id="exportClientPDFModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-file-pdf mr-2"></i>Export PDF</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off" target="_blank">
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<div class="modal-body">
<ul class="list-group">
<div class="row">
<div class="col-sm-6">
<li class="list-group-item">
<div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="contacts" name="export_contacts" value="1" checked>
<label for="contacts" class="custom-control-label">
<i class='fas fa-fw fa-users mr-2'></i>Contacts
</label>
</div>
</li>
<li class="list-group-item">
<div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="locations" name="export_locations" value="1" checked>
<label for="locations" class="custom-control-label">
<i class='fas fa-fw fa-map-marker-alt mr-2'></i>Locations
</label>
</div>
</li>
<li class="list-group-item">
<div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="assets" name="export_assets" value="1" checked>
<label for="assets" class="custom-control-label">
<i class='fas fa-fw fa-desktop mr-2'></i>Assets
</label>
</div>
</li>
<li class="list-group-item">
<div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="software" name="export_software" value="1" checked>
<label for="software" class="custom-control-label">
<i class='fas fa-fw fa-cube mr-2'></i>Software / Licenses
</label>
</div>
</li>
<li class="list-group-item">
<div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="credentials" name="export_credentials" value="1">
<label for="credentials" class="custom-control-label">
<i class='fas fa-fw fa-key mr-2'></i>Credentials
</label>
</div>
</li>
<li class="list-group-item">
<div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="networks" name="export_networks" value="1" checked>
<label for="networks" class="custom-control-label">
<i class='fas fa-fw fa-network-wired mr-2'></i>Networks
</label>
</div>
</li>
<li class="list-group-item">
<div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="certificates" name="export_certificates" value="1" checked>
<label for="certificates" class="custom-control-label">
<i class='fas fa-fw fa-lock mr-2'></i>Certificates
</label>
</div>
</li>
<li class="list-group-item">
<div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="domains" name="export_domains" value="1" checked>
<label for="domains" class="custom-control-label">
<i class='fas fa-fw fa-globe mr-2'></i>Domains
</label>
</div>
</li>
<li class="list-group-item">
<div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="tickets" name="export_tickets" value="1" checked>
<label for="tickets" class="custom-control-label">
<i class='fas fa-fw fa-life-ring mr-2'></i>Tickets
</label>
</div>
</li>
</div>
<div class="col-sm-6">
<li class="list-group-item">
<div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="recurring_tickets" name="export_recurring_tickets" value="1" checked>
<label for="recurring_tickets" class="custom-control-label">
<i class='fas fa-fw fa-clock mr-2'></i>Recurring Tickets
</label>
</div>
</li>
<li class="list-group-item">
<div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="vendors" name="export_vendors" value="1" checked>
<label for="vendors" class="custom-control-label">
<i class='fas fa-fw fa-building mr-2'></i>Vendors
</label>
</div>
</li>
<li class="list-group-item">
<div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="invoices" name="export_invoices" value="1" checked>
<label for="invoices" class="custom-control-label">
<i class='fas fa-fw fa-file-invoice mr-2'></i>Invoices
</label>
</div>
</li>
<li class="list-group-item">
<div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="recurring_invoices" name="export_recurring_invoices" value="1" checked>
<label for="recurring_invoices" class="custom-control-label">
<i class='fas fa-fw fa-sync mr-2'></i>Recurring Invoices
</label>
</div>
</li>
<li class="list-group-item">
<div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="quotes" name="export_quotes" value="1" checked>
<label for="quotes" class="custom-control-label">
<i class='fas fa-fw fa-file mr-2'></i>Quotes
</label>
</div>
</li>
<li class="list-group-item">
<div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="payments" name="export_payments" value="1" checked>
<label for="payments" class="custom-control-label">
<i class='fas fa-fw fa-credit-card mr-2'></i>Payments
</label>
</div>
</li>
<li class="list-group-item">
<div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="trips" name="export_trips" value="1" checked>
<label for="trips" class="custom-control-label">
<i class='fas fa-fw fa-route mr-2'></i>Trips
</label>
</div>
</li>
<li class="list-group-item">
<div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="logs" name="export_logs" value="1" checked>
<label for="logs" class="custom-control-label">
<i class='fas fa-fw fa-eye mr-2'></i>Audit Log
</label>
</div>
</li>
</div>
</div>
</ul>
</div>
<div class="modal-footer">
<button type="submit" name="export_client_pdf" class="btn btn-primary text-bold"><i class="fa fa-fw fa-download mr-2"></i>Export</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div>
</form>
</div>
</div>
</div>

Some files were not shown because too many files have changed in this diff Show More