72 Commits

Author SHA1 Message Date
Johnny
ed8a576ac3 Merge pull request #1223 from itflow-org/develop
25.06 Release
2025-06-20 15:34:32 -04:00
johnnyq
5c6a7acb7d Fix Updated at date in Documents 2025-06-20 15:25:42 -04:00
johnnyq
850db54a3b Bump ITFlow version to 25.6 and updated changelog 2025-06-20 15:10:46 -04:00
johnnyq
985593b7c2 Add Confirm Modal to Accept Decline Quote 2025-06-19 16:39:22 -04:00
johnnyq
857b5d1bfd Remove redundant php open tag 2025-06-19 00:27:33 -04:00
johnnyq
498e86aa7a Refactor Restore ITFlow Backup code in setup to utilize Sys Temp Directory 2025-06-19 00:26:23 -04:00
johnnyq
79d0fd28b0 Fix Backup function 2025-06-19 00:17:52 -04:00
johnnyq
426ca90515 Add Function to cleanup temp backup files if backup times out or error out 2025-06-19 00:13:56 -04:00
johnnyq
e7328f1be5 Use tmp directory to zip and backup itflow instance 2025-06-19 00:06:54 -04:00
johnnyq
baccc8051e Fix Extra spacing before Contact Name in client listing 2025-06-18 23:13:06 -04:00
johnnyq
f1c7690270 Also add contact_id to the compact ticket listing 2025-06-18 22:34:27 -04:00
johnnyq
d700d1530b Add missing contact_id in ticket listing 2025-06-18 22:32:55 -04:00
johnnyq
b60f44eede Allow the Contact to be clickable in ticket compact listing too 2025-06-18 18:06:59 -04:00
johnnyq
54ab788e93 Allow the Contact to be clickable in ticket listing and direct to the client contact details page 2025-06-18 18:05:28 -04:00
johnnyq
ac2dd04959 Moved Has Base Vendor Template Icon to the the end of the Vendors Table listing 2025-06-18 16:56:40 -04:00
johnnyq
9a449c35ac Fix No content in Edit Recurring Invoice Note Modal 2025-06-18 16:18:01 -04:00
johnnyq
2ff5d2f87c Merge branch 'develop' of github.com:itflow-org/itflow into develop 2025-06-18 15:32:38 -04:00
johnnyq
8f704dade8 Recurring Payments now make the payment on the invoice Due Date instead of when the recurring invoice is generated 2025-06-18 15:32:22 -04:00
wrongecho
3b3e323ce5 Assets - Import CSV now takes purchase date too (MUST be in format YYYY-MM-DD, Excel is annoying and will silently reformat this at random) 2025-06-18 14:48:13 +01:00
wrongecho
43ec144bf0 Fix more debug errors 2025-06-18 14:47:21 +01:00
wrongecho
d5f94819d0 Fix 'Passing null to parameter' debug message 2025-06-18 14:11:18 +01:00
johnnyq
98aa7e4993 Remove url_query_strings_sort var as this functionality has been moved to the filter header that all listing pages share 2025-06-18 01:42:21 -04:00
johnnyq
7c61911dba Added Document Template Delete function 2025-06-18 00:55:57 -04:00
johnnyq
2bb107a5d7 Add Functionality to mark all tasks as complete or incomplete in a ticket 2025-06-18 00:48:18 -04:00
johnnyq
0c4a2aedb7 Show Puzzle Piece Icon if a Vendor has a base vendor template assigned to it 2025-06-18 00:16:19 -04:00
johnnyq
e7e7272002 Migrated Vendor Templates to its own table, lots of code modifications here 2025-06-17 22:44:54 -04:00
johnnyq
f672991089 Remove Document Template field from a few more files 2025-06-17 19:09:43 -04:00
johnnyq
473fa2671d Migrate Document templates to its own table 2025-06-17 19:00:56 -04:00
johnnyq
85e1515080 Move Document Versions to a seperate table much more efficient and allow to reference same document using a link Note this update will delete previous document versions 2025-06-17 17:58:20 -04:00
johnnyq
84437a2732 Bump TCPDF from 6.9.4 to 6.10.0 and TinyMCE from 7.9.0 to 7.9.1 2025-06-17 14:44:06 -04:00
johnnyq
71911f418f Remove Unessesary Code 2025-06-17 14:32:35 -04:00
johnnyq
2741f78bd8 Fully Migrated Quote and Invoice to use TCPDF and elimiated PDFMake 2025-06-17 14:22:57 -04:00
johnnyq
012e54161a Converted PDF Invoice from PDFMake to TCPDF 2025-06-16 18:40:05 -04:00
johnnyq
409084c499 Update UI on Quote, Recurring Invoice and Guest views to match new optimized Invoice UI Layout 2025-06-16 15:49:38 -04:00
johnnyq
27595b2c4a UI Add Ticket to Invoice - Removed Warning about Draf Invoices increase modal size to large and move input to a row to reduce uneessary veritical space being occupied. 2025-06-16 13:13:48 -04:00
johnnyq
62b6535625 UI Invoice make footer text secondary color 2025-06-15 15:42:13 -04:00
johnnyq
e593f438b3 UI Work on Client Overview Increase Quick Notes and Recent Activities width and added contact photos or initials to important contacts 2025-06-15 15:36:54 -04:00
johnnyq
44d46a2cc5 UI Overhaul to invoice Details Page 2025-06-15 15:06:53 -04:00
johnnyq
66e30dd1a8 Added Badge Counts in Client Overview Section 2025-06-13 16:05:49 -04:00
johnnyq
4c74351d21 Added Company Tax ID Field and Option to Show Tax ID on Invoices 2025-06-13 15:51:09 -04:00
johnnyq
5d2b14259c Added Ticket Due Date basic functionality to tickets 2025-06-12 17:13:17 -04:00
johnnyq
878d5444e1 Use Gray Accent color when in client view and use configured theme for Global view, this will help differentiate the view that you are in 2025-06-12 15:00:47 -04:00
johnnyq
ec24ec60c6 Disable Ticket Auto Timer by default 2025-06-12 13:49:11 -04:00
johnnyq
9c096d1f65 Add Setting option to enable or disable ticket autotimer 2025-06-12 13:44:21 -04:00
johnnyq
dba3e895da UI/UX update in ticket details switch to full card stacks with edit icons for the stackable reference items on the right like asset watchers contact etc 2025-06-11 22:28:38 -04:00
johnnyq
07726322df Project Details: Add Bulk Actions to tickets and allow tickets to be sorted 2025-06-11 20:47:27 -04:00
johnnyq
bef18c0d72 Do not Resolved Tickets in Bulk that have Open tasks, display warning and count of ticket not resolved because of open tasks 2025-06-11 18:48:23 -04:00
johnnyq
7c3332570a Add Ticket Category UI for Recurring Tickets 2025-06-11 18:11:08 -04:00
johnnyq
a3d4a52188 Add Mark Sent when invoice is draft to Action Dropdown for invoice listings 2025-06-11 17:29:38 -04:00
johnnyq
5530e89f41 Add one more Non-Billable Check in invoices 2025-06-11 17:18:28 -04:00
johnnyq
a3554b3dfd Add one more Non-Billable Check in invoices 2025-06-11 17:16:03 -04:00
johnnyq
674da36cd1 Do Not calculate Non-Billable Invoices towards a clients balance Convert Add Payment Modal to AJAX and add it as an option from the invoice listing page 2025-06-11 17:12:37 -04:00
johnnyq
18ce12f60d Add Option if visiting a deleted invoice / recurring to return to the listing page and added delete to invoice details page 2025-06-11 15:57:52 -04:00
johnnyq
a462ab36f8 Ticket add / edit / builk sort categories alphabeticaly 2025-06-11 14:56:23 -04:00
Johnny
8aa41edc3e Merge pull request #1222 from itflow-org/functions-ip-addr-leftmost
Update how functions.php gets the remote IP address for logging
2025-06-11 14:01:12 -04:00
wrongecho
4e0252553a rm extra ; 2025-06-11 08:18:32 +01:00
johnnyq
8745d09890 Add sanitize the remaining uris that allow uri type:// refactored service details 2025-06-10 12:11:58 -04:00
wrongecho
ac3a02baea Disallow turning on login key without a secret 2025-06-10 09:19:29 +01:00
wrongecho
f2bbc170da Update how functions.php gets the remote IP address for logging
- Builds on PR #1210 to always get the leftmost IP address
- Cloudflare (HTTP_CF_CONNECTING_IP) must now be explicitly defined, otherwise people could add the HTTP_CF_CONNECTING_IP header to a non-Cloudflare host and spoof IPs
- Tidy up the if/else logic a little
2025-06-10 09:03:00 +01:00
johnnyq
d79a17adb0 Added sanitize_url function to strip out unsupported URI Schemas schema:// if not on the allow list it will show unsupport://URL 2025-06-09 20:28:10 -04:00
johnnyq
680dbb04ce Fix UI Regression with Indenting Columns in Tickets listing when Open and Closed tickets are filters 2025-06-09 13:30:13 -04:00
johnnyq
6c8403fa09 Move MFA Modal out of the Password Reset Form 2025-06-09 12:52:07 -04:00
johnnyq
fec8eaef70 Remove xml from the allowed upload list, if you must zip it up 2025-06-07 01:28:13 -04:00
johnnyq
5f007029b4 Fix Category 2025-06-07 00:58:56 -04:00
johnnyq
4e76ceaa0f Simplify Category filter logic in tickets catrgory is an int not a string duh 2025-06-07 00:46:11 -04:00
johnnyq
08e467baa9 Encode Page Title 2025-06-06 21:48:24 -04:00
Johnny
f78a2250f1 Merge pull request #1221 from itflow-org/develop
Develop to Master for 25.05.1 Release
2025-06-02 14:39:50 -04:00
johnnyq
84e8a459c8 update Changelog 2025-06-02 14:24:52 -04:00
johnnyq
b777f80249 Increment Minor Version and update Changelog 2025-06-02 14:19:04 -04:00
johnnyq
73da203dbb Added Cards for Account Balance, Recurring Monthly for Billing Contacts and Domains Expiring for Technical Contacts to Client Portal 2025-05-31 17:47:08 -04:00
johnnyq
55a31865d0 Updated Client Overview Entities to not show Archived client's Entities even though the entity may not be archived, also added Archive Searching to network and certificates also added unarchive capabilities to them as well 2025-05-30 16:15:12 -04:00
wrongecho
350697869b Fix invoice top banner not showing 2025-05-30 17:31:54 +01:00
171 changed files with 5243 additions and 4331 deletions

View File

@@ -2,6 +2,55 @@
This file documents all notable changes made to ITFlow. This file documents all notable changes made to ITFlow.
## [25.06]
### Breaking CHANGES
- Old Document Verions will be deleted due to the major backend rewrite how document versions work.
### Added / Changed
- Improved function for retrieving remote IP address for logging purposes.
- Ticket categories are now sorted alphabetically.
- Visiting a deleted invoice or recurring invoice now redirects to the listing page; delete option added to invoice details page.
- Added "Mark as Sent" and "Make Payment" actions directly on the invoice listing page.
- Introduced Ticket Category UI for recurring tickets.
- In Project Details, bulk actions and sorting are now available for tickets.
- Updated ticket details UI to use full card stacks with edit icons for stackable items (e.g., asset, watchers, contact).
- Added a new setting to toggle AutoStart Timer in ticket details (disabled by default).
- Applied gray accent theme in the client section to visually distinguish from the global view.
- Introduced Ticket Due Date functionality (currently supports add/edit only; more updates coming next release).
- Added settings option to display Company Tax ID on invoices.
- Client overview now displays badge counts for all entities.
- Overhauled UI for Invoice, Quote, and Recurring Invoice details; switched PDF generation to TCPDF PHP from PDFMake JS.
- Document versioning has been moved to a separate backend table to resolve permanent link issues -- SEE Breaking CHANGES.
- Migrated Document Templates, Vendor Templates, and Software/License Templates to dedicated tables.
- Added functionality to mark all tasks in a ticket as complete or incomplete.
- Asset CSV import now supports a purchase date field.
- Recurring Payments have been restructured to auto-charge on the invoice due date instead of at generation time.
- Added "Base Template" label for vendor templates when available.
- Backup and restore processes now use a temporary directory; files are cleaned up automatically if operations fail.
- Added confirmation prompt when accepting or declining a quote.
- Other minor code UI/UX cleanups and refactoring throughout the app.
### Fixed
- Resolved issue with enabling MFA.
- Fixed UI regression where ticket listing columns would misalign.
- Non-billable invoices are no longer included in calculations.
- Addressed multiple minor reported security vulnerabilities.
- Tickets with open tasks are no longer resolved in bulk; a warning is shown along with a count of affected tickets.
## [25.05.1]
### Added / Changed
- Added Domain Expiring Card to Client Portal Dashboard for Primary and Technical Users.
- Added Balance and Monthly Recurring Amount to Client Portal Dahboard for Primary and Technical Users.
- Added Archive Searching to network and certificates also added unarchive capabilities to them as well.
### Fixed
- Add Payment not showing in Invoice.
- Updated Client Overview Entities to not show archived client's Entities even though the entity may not be archived.
## [25.05] ## [25.05]
### Added / Changed ### Added / Changed

View File

@@ -9,9 +9,6 @@ require_once "includes/inc_all.php";
// Perms // Perms
enforceUserPermission('module_financial'); enforceUserPermission('module_financial');
//Rebuild URL
$url_query_strings_sort = http_build_query($get_copy);
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM accounts "SELECT SQL_CALC_FOUND_ROWS * FROM accounts

View File

@@ -6,10 +6,6 @@ $order = "ASC";
require_once "includes/inc_all_admin.php"; require_once "includes/inc_all_admin.php";
//Rebuild URL
$url_query_strings_sort = http_build_query($get_copy);
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM api_keys "SELECT SQL_CALC_FOUND_ROWS * FROM api_keys

View File

@@ -26,9 +26,6 @@ if (isset($_GET['category']) & !empty($_GET['catergory'])) {
$category_filter = ''; $category_filter = '';
} }
//Rebuild URL
$url_query_strings_sort = http_build_query($get_copy);
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM app_logs "SELECT SQL_CALC_FOUND_ROWS * FROM app_logs

View File

@@ -46,9 +46,6 @@ if (isset($_GET['action']) & !empty($_GET['action'])) {
$action_filter = ''; $action_filter = '';
} }
//Rebuild URL
$url_query_strings_sort = http_build_query($get_copy);
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM logs "SELECT SQL_CALC_FOUND_ROWS * FROM logs

View File

@@ -13,10 +13,6 @@ if (isset($_GET['category'])) {
$category = "Expense"; $category = "Expense";
} }
//Rebuild URL
$url_query_strings_sort = http_build_query($get_copy);
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM categories "SELECT SQL_CALC_FOUND_ROWS * FROM categories

View File

@@ -6,10 +6,6 @@ $order = "ASC";
require_once "includes/inc_all_admin.php"; require_once "includes/inc_all_admin.php";
//Rebuild URL
$url_query_strings_sort = http_build_query($get_copy);
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM custom_links "SELECT SQL_CALC_FOUND_ROWS * FROM custom_links

View File

@@ -1,27 +1,16 @@
<?php <?php
// Default Column Sort by Filter // Default Column Sort by Filter
$sort = "document_name"; $sort = "document_template_name";
$order = "ASC"; $order = "ASC";
require_once "includes/inc_all_admin.php"; require_once "includes/inc_all_admin.php";
// 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);
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM documents "SELECT SQL_CALC_FOUND_ROWS * FROM document_templates
LEFT JOIN users ON document_created_by = user_id LEFT JOIN users ON document_template_created_by = user_id
WHERE document_template = 1 WHERE user_name LIKE '%$q%' OR document_template_name LIKE '%$q%'
$query_snippet
ORDER BY $sort $order LIMIT $record_from, $record_to" ORDER BY $sort $order LIMIT $record_from, $record_to"
); );
@@ -55,18 +44,18 @@
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>"> <thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
<tr> <tr>
<th> <th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=document_name&order=<?php echo $disp; ?>"> <a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=document_template_name&order=<?php echo $disp; ?>">
Template Name <?php if ($sort == 'document_name') { echo $order_icon; } ?> Template Name <?php if ($sort == 'document_template_name') { echo $order_icon; } ?>
</a> </a>
</th> </th>
<th> <th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=document_created_at&order=<?php echo $disp; ?>"> <a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=document_template_created_at&order=<?php echo $disp; ?>">
Created <?php if ($sort == 'document_created_at') { echo $order_icon; } ?> Created <?php if ($sort == 'document_template_created_at') { echo $order_icon; } ?>
</a> </a>
</th> </th>
<th> <th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=document_updated_at&order=<?php echo $disp; ?>"> <a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=document_template_updated_at&order=<?php echo $disp; ?>">
Updated <?php if ($sort == 'document_updated_at') { echo $order_icon; } ?> Updated <?php if ($sort == 'document_template_updated_at') { echo $order_icon; } ?>
</a> </a>
</th> </th>
<th class="text-center"> <th class="text-center">
@@ -78,27 +67,26 @@
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_array($sql)) {
$document_id = intval($row['document_id']); $document_template_id = intval($row['document_template_id']);
$document_name = nullable_htmlentities($row['document_name']); $document_template_name = nullable_htmlentities($row['document_template_name']);
$document_description = nullable_htmlentities($row['document_description']); $document_template_description = nullable_htmlentities($row['document_template_description']);
$document_content = nullable_htmlentities($row['document_content']); $document_template_content = nullable_htmlentities($row['document_template_content']);
$document_created_by_name = nullable_htmlentities($row['user_name']); $document_template_created_by_name = nullable_htmlentities($row['user_name']);
$document_created_at = nullable_htmlentities($row['document_created_at']); $document_template_created_at = nullable_htmlentities($row['document_template_created_at']);
$document_updated_at = nullable_htmlentities($row['document_updated_at']); $document_template_updated_at = nullable_htmlentities($row['document_template_updated_at']);
$document_folder_id = intval($row['document_folder_id']);
?> ?>
<tr> <tr>
<td> <td>
<a class="text-bold" href="admin_document_template_details.php?document_id=<?php echo $document_id; ?>"><i class="fas fa-fw fa-file-alt text-dark"></i> <?php echo $document_name; ?></a> <a class="text-bold" href="admin_document_template_details.php?document_template_id=<?php echo $document_template_id; ?>"><i class="fas fa-fw fa-file-alt text-dark"></i> <?php echo $document_template_name; ?></a>
<div class="mt-1 text-secondary"><?php echo $document_description; ?></div> <div class="mt-1 text-secondary"><?php echo $document_template_description; ?></div>
</td> </td>
<td> <td>
<?php echo $document_created_at; ?> <?php echo $document_template_created_at; ?>
<div class="text-secondary"><?php echo $document_created_by_name; ?></div> <div class="text-secondary"><?php echo $document_template_created_by_name; ?></div>
</td> </td>
<td><?php echo $document_updated_at; ?></td> <td><?php echo $document_template_updated_at; ?></td>
<td> <td>
<div class="dropdown dropleft text-center"> <div class="dropdown dropleft text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown"> <button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
@@ -109,12 +97,12 @@
data-toggle="ajax-modal" data-toggle="ajax-modal"
data-modal-size="xl" data-modal-size="xl"
data-ajax-url="ajax/ajax_document_template_edit.php" data-ajax-url="ajax/ajax_document_template_edit.php"
data-ajax-id="<?php echo $document_id; ?>" data-ajax-id="<?php echo $document_template_id; ?>"
> >
<i class="fas fa-fw fa-edit mr-2"></i>Edit <i class="fas fa-fw fa-edit mr-2"></i>Edit
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold" href="post.php?delete_document=<?php echo $document_id; ?>"> <a class="dropdown-item text-danger text-bold" href="post.php?delete_document_template=<?php echo $document_template_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash mr-2"></i>Delete
</a> </a>
</div> </div>

View File

@@ -11,19 +11,19 @@ $purifier_config->set('Cache.DefinitionImpl', null); // Disable cache by setting
$purifier_config->set('URI.AllowedSchemes', ['data' => true, 'src' => true, 'http' => true, 'https' => true]); $purifier_config->set('URI.AllowedSchemes', ['data' => true, 'src' => true, 'http' => true, 'https' => true]);
$purifier = new HTMLPurifier($purifier_config); $purifier = new HTMLPurifier($purifier_config);
if (isset($_GET['document_id'])) { if (isset($_GET['document_template_id'])) {
$document_id = intval($_GET['document_id']); $document_template_id = intval($_GET['document_template_id']);
} }
$sql_document = mysqli_query($mysqli, "SELECT * FROM documents WHERE document_template = 1 AND document_id = $document_id"); $sql_document = mysqli_query($mysqli, "SELECT * FROM document_templates WHERE document_template_id = $document_template_id");
$row = mysqli_fetch_array($sql_document); $row = mysqli_fetch_array($sql_document);
$document_name = nullable_htmlentities($row['document_name']); $document_template_name = nullable_htmlentities($row['document_template_name']);
$document_description = nullable_htmlentities($row['document_description']); $document_template_description = nullable_htmlentities($row['document_template_description']);
$document_content = $purifier->purify($row['document_content']); $document_template_content = $purifier->purify($row['document_template_content']);
$document_created_at = nullable_htmlentities($row['document_created_at']); $document_template_created_at = nullable_htmlentities($row['document_template_created_at']);
$document_updated_at = nullable_htmlentities($row['document_updated_at']); $document_template_updated_at = nullable_htmlentities($row['document_template_updated_at']);
?> ?>
@@ -37,27 +37,27 @@ $document_updated_at = nullable_htmlentities($row['document_updated_at']);
<li class="breadcrumb-item"> <li class="breadcrumb-item">
<a href="admin_document_template.php">Document Templates</a> <a href="admin_document_template.php">Document Templates</a>
</li> </li>
<li class="breadcrumb-item active"><i class="fas fa-file mr-2"></i><?php echo $document_name; ?></li> <li class="breadcrumb-item active"><i class="fas fa-file mr-2"></i><?php echo $document_template_name; ?></li>
</ol> </ol>
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-2"> <div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fa fa-fw fa-file mr-2"></i><?php echo $document_name; ?></h3> <h3 class="card-title mt-2"><i class="fa fa-fw fa-file mr-2"></i><?php echo $document_template_name; ?></h3>
<div class="card-tools"> <div class="card-tools">
<button type="button" class="btn btn-primary" <button type="button" class="btn btn-primary"
data-toggle="ajax-modal" data-toggle="ajax-modal"
data-modal-size="xl" data-modal-size="xl"
data-ajax-url="ajax/ajax_document_template_edit.php" data-ajax-url="ajax/ajax_document_template_edit.php"
data-ajax-id="<?php echo $document_id; ?>" data-ajax-id="<?php echo $document_template_id; ?>"
> >
<i class="fas fa-edit mr-2"></i>Edit <i class="fas fa-edit mr-2"></i>Edit
</button> </button>
</div> </div>
</div> </div>
<div class="card-body prettyContent"> <div class="card-body prettyContent">
<?php echo $document_content; ?> <?php echo $document_template_content; ?>
</div> </div>
</div> </div>

View File

@@ -6,9 +6,6 @@ $order = "DESC";
require_once "includes/inc_all_admin.php"; require_once "includes/inc_all_admin.php";
//Rebuild URL
$url_query_strings_sort = http_build_query($get_copy);
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM email_queue "SELECT SQL_CALC_FOUND_ROWS * FROM email_queue

View File

@@ -6,10 +6,6 @@ $order = "ASC";
require_once "includes/inc_all_admin.php"; require_once "includes/inc_all_admin.php";
//Rebuild URL
$url_query_strings_sort = http_build_query($get_copy);
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM project_templates "SELECT SQL_CALC_FOUND_ROWS * FROM project_templates

View File

@@ -6,10 +6,6 @@ $order = "DESC";
require_once "includes/inc_all_admin.php"; require_once "includes/inc_all_admin.php";
//Rebuild URL
$url_query_strings_sort = http_build_query($get_copy);
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM user_roles "SELECT SQL_CALC_FOUND_ROWS * FROM user_roles

View File

@@ -19,6 +19,7 @@ $company_website = nullable_htmlentities($row['company_website']);
$company_logo = nullable_htmlentities($row['company_logo']); $company_logo = nullable_htmlentities($row['company_logo']);
$company_locale = nullable_htmlentities($row['company_locale']); $company_locale = nullable_htmlentities($row['company_locale']);
$company_currency = nullable_htmlentities($row['company_currency']); $company_currency = nullable_htmlentities($row['company_currency']);
$company_tax_id = nullable_htmlentities($row['company_tax_id']);
$company_initials = nullable_htmlentities(initials($company_name)); $company_initials = nullable_htmlentities(initials($company_name));
@@ -146,6 +147,16 @@ $company_initials = nullable_htmlentities(initials($company_name));
</div> </div>
</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" value="<?php echo $company_tax_id; ?>" placeholder="Tax ID" maxlength="200">
</div>
</div>
<hr> <hr>
<button type="submit" name="edit_company" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button> <button type="submit" name="edit_company" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>

View File

@@ -13,9 +13,6 @@ if (isset($_GET['table'])) {
$table = "client_assets"; $table = "client_assets";
} }
//Rebuild URL
$url_query_strings_sort = http_build_query($get_copy);
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM custom_fields "SELECT SQL_CALC_FOUND_ROWS * FROM custom_fields

View File

@@ -37,12 +37,21 @@ require_once "includes/inc_all_admin.php";
<textarea class="form-control" rows="4" name="config_invoice_footer"><?php echo nullable_htmlentities($config_invoice_footer); ?></textarea> <textarea class="form-control" rows="4" name="config_invoice_footer"><?php echo nullable_htmlentities($config_invoice_footer); ?></textarea>
</div> </div>
<h5>Show Tax ID On Invoices</h5>
<div class="form-group">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" name="config_invoice_show_tax_id" <?php if ($config_invoice_show_tax_id == 1) { echo "checked"; } ?> value="1" id="customSwitch1">
<label class="custom-control-label" for="customSwitch1">Show Tax ID</label>
</div>
</div>
<h5>Invoice Late Fees</h5> <h5>Invoice Late Fees</h5>
<div class="form-group"> <div class="form-group">
<div class="custom-control custom-switch"> <div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" name="config_invoice_late_fee_enable" <?php if ($config_invoice_late_fee_enable == 1) { echo "checked"; } ?> value="1" id="customSwitch1"> <input type="checkbox" class="custom-control-input" name="config_invoice_late_fee_enable" <?php if ($config_invoice_late_fee_enable == 1) { echo "checked"; } ?> value="1" id="customSwitch2">
<label class="custom-control-label" for="customSwitch1">Enable Late Fee</label> <label class="custom-control-label" for="customSwitch2">Enable Late Fee</label>
</div> </div>
</div> </div>

View File

@@ -76,7 +76,7 @@ require_once "includes/inc_all_admin.php";
<option value="">- Do not expense Stripe fees -</option> <option value="">- Do not expense Stripe fees -</option>
<?php <?php
$sql_select = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = 0 AND vendor_template = 0 AND vendor_archived_at IS NULL ORDER BY vendor_name ASC"); $sql_select = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = 0 AND vendor_archived_at IS NULL ORDER BY vendor_name ASC");
while ($row = mysqli_fetch_array($sql_select)) { while ($row = mysqli_fetch_array($sql_select)) {
$vendor_id = intval($row['vendor_id']); $vendor_id = intval($row['vendor_id']);
$vendor_name = nullable_htmlentities($row['vendor_name']); $vendor_name = nullable_htmlentities($row['vendor_name']);

View File

@@ -53,6 +53,13 @@ require_once "includes/inc_all_admin.php";
</div> </div>
<?php } ?> <?php } ?>
<div class="form-group">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" name="config_ticket_timer_autostart" <?php if ($config_ticket_timer_autostart == 1) { echo "checked"; } ?> value="1" id="ticketTimerSwitch">
<label class="custom-control-label" for="ticketTimerSwitch">Autostart Ticket Timer <small class="text-secondary">(This option will control if the timer starts automatically or manually)</small></label>
</div>
</div>
<div class="form-group"> <div class="form-group">
<label>Number of hours to auto close resolved tickets</label> <label>Number of hours to auto close resolved tickets</label>
<div class="input-group"> <div class="input-group">

View File

@@ -1,20 +1,15 @@
<?php <?php
// Default Column Sortby Filter // Default Column Sortby Filter
$sort = "software_name"; $sort = "software_template_name";
$order = "ASC"; $order = "ASC";
require_once "includes/inc_all_admin.php"; require_once "includes/inc_all_admin.php";
//Rebuild URL
$url_query_strings_sort = http_build_query($get_copy);
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM software "SELECT SQL_CALC_FOUND_ROWS * FROM software_templates
WHERE software_template = 1 WHERE software_template_name LIKE '%$q%' OR software_template_type LIKE '%$q%'
AND (software_name LIKE '%$q%' OR software_type LIKE '%$q%')
ORDER BY $sort $order LIMIT $record_from, $record_to" ORDER BY $sort $order LIMIT $record_from, $record_to"
); );
@@ -53,18 +48,18 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<thead class="text-dark <?php if($num_rows[0] == 0){ echo "d-none"; } ?>"> <thead class="text-dark <?php if($num_rows[0] == 0){ echo "d-none"; } ?>">
<tr> <tr>
<th> <th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=software_name&order=<?php echo $disp; ?>"> <a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=software_template_name&order=<?php echo $disp; ?>">
Template <?php if ($sort == 'software_name') { echo $order_icon; } ?> Template <?php if ($sort == 'software_template_name') { echo $order_icon; } ?>
</a> </a>
</th> </th>
<th> <th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=software_type&order=<?php echo $disp; ?>"> <a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=software_template_type&order=<?php echo $disp; ?>">
Type <?php if ($sort == 'software_type') { echo $order_icon; } ?> Type <?php if ($sort == 'software_template_type') { echo $order_icon; } ?>
</a> </a>
</th> </th>
<th> <th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=software_license_type&order=<?php echo $disp; ?>"> <a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=software_template_license_type&order=<?php echo $disp; ?>">
License Type <?php if ($sort == 'software_license_type') { echo $order_icon; } ?> License Type <?php if ($sort == 'software_template_license_type') { echo $order_icon; } ?>
</a> </a>
</th> </th>
<th class="text-center">Action</th> <th class="text-center">Action</th>
@@ -74,41 +69,41 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php <?php
while($row = mysqli_fetch_array($sql)){ while($row = mysqli_fetch_array($sql)){
$software_id = intval($row['software_id']); $software_template_id = intval($row['software_template_id']);
$software_name = nullable_htmlentities($row['software_name']); $software_template_name = nullable_htmlentities($row['software_template_name']);
$software_version = nullable_htmlentities($row['software_version']); $software_template_version = nullable_htmlentities($row['software_template_version']);
$software_description = nullable_htmlentities($row['software_description']); $software_template_description = nullable_htmlentities($row['software_template_description']);
$software_type = nullable_htmlentities($row['software_type']); $software_template_type = nullable_htmlentities($row['software_template_type']);
$software_license_type = nullable_htmlentities($row['software_license_type']); $software_template_license_type = nullable_htmlentities($row['software_template_license_type']);
$software_notes = nullable_htmlentities($row['software_notes']); $software_template_notes = nullable_htmlentities($row['software_template_notes']);
?> ?>
<tr> <tr>
<td> <td>
<a class="text-dark" href="#" data-toggle="ajax-modal" data-ajax-url="ajax/ajax_software_template_edit.php" data-ajax-id="<?php echo $software_id; ?>"> <a class="text-dark" href="#" data-toggle="ajax-modal" data-ajax-url="ajax/ajax_software_template_edit.php" data-ajax-id="<?php echo $software_template_id; ?>">
<div class="media"> <div class="media">
<i class="fa fa-fw fa-2x fa-cube mr-3"></i> <i class="fa fa-fw fa-2x fa-cube mr-3"></i>
<div class="media-body"> <div class="media-body">
<div><?php echo "$software_name <span>$software_version</span>"; ?></div> <div><?php echo "$software_template_name <span>$software_template_version</span>"; ?></div>
<div><small class="text-secondary"><?php echo $software_description; ?></small></div> <div><small class="text-secondary"><?php echo $software_template_description; ?></small></div>
</div> </div>
</div> </div>
</a> </a>
</td> </td>
<td><?php echo $software_type; ?></td> <td><?php echo $software_template_type; ?></td>
<td><?php echo $software_license_type; ?></td> <td><?php echo $software_template_license_type; ?></td>
<td> <td>
<div class="dropdown dropleft text-center"> <div class="dropdown dropleft text-center">
<button class="btn btn-secondary btn-sm" data-toggle="dropdown"> <button class="btn btn-secondary btn-sm" data-toggle="dropdown">
<i class="fas fa-ellipsis-h"></i> <i class="fas fa-ellipsis-h"></i>
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<a class="dropdown-item" href="#" data-toggle="ajax-modal" data-ajax-url="ajax/ajax_software_template_edit.php" data-ajax-id="<?php echo $software_id; ?>"> <a class="dropdown-item" href="#" data-toggle="ajax-modal" data-ajax-url="ajax/ajax_software_template_edit.php" data-ajax-id="<?php echo $software_template_id; ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit <i class="fas fa-fw fa-edit mr-2"></i>Edit
</a> </a>
<?php if($session_user_role == 3) { ?> <?php if($session_user_role == 3) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_software=<?php echo $software_id; ?>"> <a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_software_template=<?php echo $software_template_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash mr-2"></i>Delete
</a> </a>
<?php } ?> <?php } ?>

View File

@@ -6,10 +6,6 @@ $order = "ASC";
require_once "includes/inc_all_admin.php"; require_once "includes/inc_all_admin.php";
//Rebuild URL
$url_query_strings_sort = http_build_query($get_copy);
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM tags "SELECT SQL_CALC_FOUND_ROWS * FROM tags

View File

@@ -6,10 +6,6 @@ $order = "ASC";
require_once "includes/inc_all_admin.php"; require_once "includes/inc_all_admin.php";
//Rebuild URL
$url_query_strings_sort = http_build_query($get_copy);
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT * FROM taxes "SELECT * FROM taxes

View File

@@ -6,10 +6,6 @@ $order = "ASC";
require_once "includes/inc_all_admin.php"; require_once "includes/inc_all_admin.php";
//Rebuild URL
$url_query_strings_sort = http_build_query($get_copy);
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM ticket_statuses "SELECT SQL_CALC_FOUND_ROWS * FROM ticket_statuses

View File

@@ -6,10 +6,6 @@ $order = "ASC";
require_once "includes/inc_all_admin.php"; require_once "includes/inc_all_admin.php";
//Rebuild URL
$url_query_strings_sort = http_build_query($get_copy);
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM ticket_templates "SELECT SQL_CALC_FOUND_ROWS * FROM ticket_templates

View File

@@ -1,20 +1,15 @@
<?php <?php
// Default Column Sortby Filter // Default Column Sortby Filter
$sort = "vendor_name"; $sort = "vendor_template_name";
$order = "ASC"; $order = "ASC";
require_once "includes/inc_all_admin.php"; require_once "includes/inc_all_admin.php";
//Rebuild URL
$url_query_strings_sort = http_build_query($get_copy);
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM vendors "SELECT SQL_CALC_FOUND_ROWS * FROM vendor_templates
WHERE vendor_template = 1 WHERE vendor_template_name LIKE '%$q%' OR vendor_template_description LIKE '%$q%' OR vendor_template_account_number LIKE '%$q%' OR vendor_template_website LIKE '%$q%' OR vendor_template_contact_name LIKE '%$q%' OR vendor_template_email LIKE '%$q%' OR vendor_template_phone LIKE '%$phone_query%' ORDER BY $sort $order LIMIT $record_from, $record_to"
AND (vendor_name LIKE '%$q%' OR vendor_description LIKE '%$q%' OR vendor_account_number LIKE '%$q%' OR vendor_website LIKE '%$q%' OR vendor_contact_name LIKE '%$q%' OR vendor_email LIKE '%$q%' OR vendor_phone LIKE '%$phone_query%') ORDER BY $sort $order LIMIT $record_from, $record_to"
); );
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
@@ -53,13 +48,13 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>"> <thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
<tr> <tr>
<th> <th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=vendor_name&order=<?php echo $disp; ?>"> <a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=vendor_template_name&order=<?php echo $disp; ?>">
Vendor <?php if ($sort == 'vendor_name') { echo $order_icon; } ?> Vendor <?php if ($sort == 'vendor_template_name') { echo $order_icon; } ?>
</a> </a>
</th> </th>
<th> <th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=vendor_description&order=<?php echo $disp; ?>"> <a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=vendor_template_description&order=<?php echo $disp; ?>">
Description <?php if ($sort == 'vendor_description') { echo $order_icon; } ?> Description <?php if ($sort == 'vendor_template_description') { echo $order_icon; } ?>
</a> </a>
</th> </th>
<th>Contact</th> <th>Contact</th>
@@ -70,30 +65,29 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_array($sql)) {
$vendor_id = intval($row['vendor_id']); $vendor_template_id = intval($row['vendor_template_id']);
$vendor_name = nullable_htmlentities($row['vendor_name']); $vendor_template_name = nullable_htmlentities($row['vendor_template_name']);
$vendor_description = nullable_htmlentities($row['vendor_description']); $vendor_template_description = nullable_htmlentities($row['vendor_template_description']);
if (empty($vendor_description)) { if (empty($vendor_template_description)) {
$vendor_description_display = "-"; $vendor_template_description_display = "-";
} else { } else {
$vendor_description_display = $vendor_description; $vendor_template_description_display = $vendor_template_description;
} }
$vendor_account_number = nullable_htmlentities($row['vendor_account_number']); $vendor_template_account_number = nullable_htmlentities($row['vendor_template_account_number']);
$vendor_contact_name = nullable_htmlentities($row['vendor_contact_name']); $vendor_template_contact_name = nullable_htmlentities($row['vendor_template_contact_name']);
if (empty($vendor_contact_name)) { if (empty($vendor_template_contact_name)) {
$vendor_contact_name_display = "-"; $vendor_template_contact_name_display = "-";
} else { } else {
$vendor_contact_name_display = $vendor_contact_name; $vendor_template_contact_name_display = $vendor_template_contact_name;
} }
$vendor_phone = formatPhoneNumber($row['vendor_phone']); $vendor_template_phone = formatPhoneNumber($row['vendor_template_phone']);
$vendor_extension = nullable_htmlentities($row['vendor_extension']); $vendor_template_extension = nullable_htmlentities($row['vendor_template_extension']);
$vendor_email = nullable_htmlentities($row['vendor_email']); $vendor_template_email = nullable_htmlentities($row['vendor_template_email']);
$vendor_website = nullable_htmlentities($row['vendor_website']); $vendor_template_website = nullable_htmlentities($row['vendor_template_website']);
$vendor_hours = nullable_htmlentities($row['vendor_hours']); $vendor_template_hours = nullable_htmlentities($row['vendor_template_hours']);
$vendor_sla = nullable_htmlentities($row['vendor_sla']); $vendor_template_sla = nullable_htmlentities($row['vendor_template_sla']);
$vendor_code = nullable_htmlentities($row['vendor_code']); $vendor_template_code = nullable_htmlentities($row['vendor_template_code']);
$vendor_notes = nullable_htmlentities($row['vendor_notes']); $vendor_template_notes = nullable_htmlentities($row['vendor_template_notes']);
$vendor_template = intval($row['vendor_template']);
?> ?>
<tr> <tr>
@@ -101,38 +95,38 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<a class="text-dark" href="#" <a class="text-dark" href="#"
data-toggle="ajax-modal" data-toggle="ajax-modal"
data-ajax-url="ajax/ajax_vendor_template_edit.php" data-ajax-url="ajax/ajax_vendor_template_edit.php"
data-ajax-id="<?php echo $vendor_id; ?>" data-ajax-id="<?php echo $vendor_template_id; ?>"
> >
<i class="fa fa-fw fa-building text-secondary mr-2"></i><?php echo $vendor_name; ?> <i class="fa fa-fw fa-building text-secondary mr-2"></i><?php echo $vendor_template_name; ?>
</a> </a>
<?php <?php
if (!empty($vendor_account_number)) { if (!empty($vendor_template_account_number)) {
?> ?>
<br> <br>
<small class="text-secondary"><?php echo $vendor_account_number; ?></small> <small class="text-secondary"><?php echo $vendor_template_account_number; ?></small>
<?php <?php
} }
?> ?>
</th> </th>
<td><?php echo $vendor_description_display; ?></td> <td><?php echo $vendor_template_description_display; ?></td>
<td> <td>
<?php <?php
if (!empty($vendor_contact_name)) { if (!empty($vendor_template_contact_name)) {
?> ?>
<i class="fa fa-fw fa-user text-secondary mr-2 mb-2"></i><?php echo $vendor_contact_name_display; ?> <i class="fa fa-fw fa-user text-secondary mr-2 mb-2"></i><?php echo $vendor_template_contact_name_display; ?>
<br> <br>
<?php <?php
} else { } else {
echo $vendor_contact_name_display; echo $vendor_template_contact_name_display;
} }
if (!empty($vendor_phone)) { ?> if (!empty($vendor_template_phone)) { ?>
<i class="fa fa-fw fa-phone text-secondary mr-2 mb-2"></i><?php echo $vendor_phone; ?> <i class="fa fa-fw fa-phone text-secondary mr-2 mb-2"></i><?php echo $vendor_template_phone; ?>
<br> <br>
<?php } <?php }
if (!empty($vendor_email)) { ?> if (!empty($vendor_template_email)) { ?>
<i class="fa fa-fw fa-envelope text-secondary mr-2 mb-2"></i><?php echo $vendor_email; ?> <i class="fa fa-fw fa-envelope text-secondary mr-2 mb-2"></i><?php echo $vendor_template_email; ?>
<br> <br>
<?php } ?> <?php } ?>
@@ -146,13 +140,13 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<a class="dropdown-item" href="#" <a class="dropdown-item" href="#"
data-toggle="ajax-modal" data-toggle="ajax-modal"
data-ajax-url="ajax/ajax_vendor_template_edit.php" data-ajax-url="ajax/ajax_vendor_template_edit.php"
data-ajax-id="<?php echo $vendor_id; ?>" data-ajax-id="<?php echo $vendor_template_id; ?>"
> >
<i class="fas fa-fw fa-edit mr-2"></i>Edit <i class="fas fa-fw fa-edit mr-2"></i>Edit
</a> </a>
<?php if ($session_user_role == 3) { ?> <?php if ($session_user_role == 3) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_vendor=<?php echo $vendor_id; ?>"> <a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_vendor=<?php echo $vendor_template_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash mr-2"></i>Delete
</a> </a>
<?php } ?> <?php } ?>

View File

@@ -341,7 +341,7 @@ ob_start();
<option value="">- Select Vendor -</option> <option value="">- Select Vendor -</option>
<?php <?php
$sql_vendors = mysqli_query($mysqli, "SELECT * FROM vendors WHERE vendor_archived_at IS NULL AND vendor_client_id = $client_id AND vendor_template = 0 ORDER BY vendor_name ASC"); $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)) { while ($row = mysqli_fetch_array($sql_vendors)) {
$vendor_id_select = intval($row['vendor_id']); $vendor_id_select = intval($row['vendor_id']);
$vendor_name_select = nullable_htmlentities($row['vendor_name']); $vendor_name_select = nullable_htmlentities($row['vendor_name']);

View File

@@ -24,8 +24,8 @@ $asset_make = nullable_htmlentities($row['asset_make']);
$asset_model = nullable_htmlentities($row['asset_model']); $asset_model = nullable_htmlentities($row['asset_model']);
$asset_serial = nullable_htmlentities($row['asset_serial']); $asset_serial = nullable_htmlentities($row['asset_serial']);
$asset_os = nullable_htmlentities($row['asset_os']); $asset_os = nullable_htmlentities($row['asset_os']);
$asset_uri = nullable_htmlentities($row['asset_uri']); $asset_uri = sanitize_url($row['asset_uri']);
$asset_uri_2 = nullable_htmlentities($row['asset_uri_2']); $asset_uri_2 = sanitize_url($row['asset_uri_2']);
$asset_status = nullable_htmlentities($row['asset_status']); $asset_status = nullable_htmlentities($row['asset_status']);
$asset_purchase_reference = nullable_htmlentities($row['asset_purchase_reference']); $asset_purchase_reference = nullable_htmlentities($row['asset_purchase_reference']);
$asset_purchase_date = nullable_htmlentities($row['asset_purchase_date']); $asset_purchase_date = nullable_htmlentities($row['asset_purchase_date']);
@@ -262,25 +262,25 @@ ob_start();
</div> </div>
<div class="card-body"> <div class="card-body">
<?php if ($asset_type) { ?> <?php if ($asset_type) { ?>
<div><i class="fa fa-fw fa-tag text-secondary mr-3"></i><?php echo $asset_type; ?></div> <div><i class="fa fa-fw fa-tag text-secondary mr-2"></i><?php echo $asset_type; ?></div>
<?php } <?php }
if ($asset_make) { ?> if ($asset_make) { ?>
<div class="mt-2"><i class="fa fa-fw fa-circle text-secondary mr-3"></i><?php echo "$asset_make $asset_model"; ?></div> <div class="mt-2"><i class="fa fa-fw fa-circle text-secondary mr-2"></i><?php echo "$asset_make $asset_model"; ?></div>
<?php } <?php }
if ($asset_os) { ?> if ($asset_os) { ?>
<div class="mt-2"><i class="fab fa-fw fa-windows text-secondary mr-3"></i><?php echo "$asset_os"; ?></div> <div class="mt-2"><i class="fab fa-fw fa-windows text-secondary mr-2"></i><?php echo "$asset_os"; ?></div>
<?php } <?php }
if ($asset_serial) { ?> if ($asset_serial) { ?>
<div class="mt-2"><i class="fa fa-fw fa-barcode text-secondary mr-3"></i><?php echo $asset_serial; ?></div> <div class="mt-2"><i class="fa fa-fw fa-barcode text-secondary mr-2"></i><?php echo $asset_serial; ?></div>
<?php } <?php }
if ($asset_purchase_date) { ?> if ($asset_purchase_date) { ?>
<div class="mt-2"><i class="fa fa-fw fa-shopping-cart text-secondary mr-3"></i><?php echo date('Y-m-d', strtotime($asset_purchase_date)); ?></div> <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 } <?php }
if ($asset_install_date) { ?> if ($asset_install_date) { ?>
<div class="mt-2"><i class="fa fa-fw fa-calendar-check text-secondary mr-3"></i><?php echo date('Y-m-d', strtotime($asset_install_date)); ?></div> <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 } <?php }
if ($asset_warranty_expire) { ?> if ($asset_warranty_expire) { ?>
<div class="mt-2"><i class="fa fa-fw fa-exclamation-triangle text-secondary mr-3"></i><?php echo date('Y-m-d', strtotime($asset_warranty_expire)); ?></div> <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 } ?> <?php } ?>
</div> </div>
</div> </div>
@@ -291,19 +291,19 @@ ob_start();
</div> </div>
<div class="card-body"> <div class="card-body">
<?php if ($asset_ip) { ?> <?php if ($asset_ip) { ?>
<div><i class="fa fa-fw fa-globe text-secondary mr-3"></i><?php echo $asset_ip; ?></div> <div><i class="fa fa-fw fa-globe text-secondary mr-2"></i><?php echo $asset_ip; ?></div>
<?php } ?> <?php } ?>
<?php if ($asset_nat_ip) { ?> <?php if ($asset_nat_ip) { ?>
<div class="mt-2"><i class="fa fa-fw fa-random text-secondary mr-3"></i><?php echo $asset_nat_ip; ?></div> <div class="mt-2"><i class="fa fa-fw fa-random text-secondary mr-2"></i><?php echo $asset_nat_ip; ?></div>
<?php } <?php }
if ($asset_mac) { ?> if ($asset_mac) { ?>
<div class="mt-2"><i class="fa fa-fw fa-ethernet text-secondary mr-3"></i><?php echo $asset_mac; ?></div> <div class="mt-2"><i class="fa fa-fw fa-ethernet text-secondary mr-2"></i><?php echo $asset_mac; ?></div>
<?php } <?php }
if ($asset_uri) { ?> if ($asset_uri) { ?>
<div class="mt-2"><i class="fa fa-fw fa-link text-secondary mr-3"></i><a href="<?php echo $asset_uri; ?>" target="_blank">Link</a></div> <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 } <?php }
if ($asset_uri_2) { ?> if ($asset_uri_2) { ?>
<div class="mt-2"><i class="fa fa-fw fa-link text-secondary mr-3"></i><a href="<?php echo $asset_uri_2; ?>" target="_blank">Link 2</a></div> <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 } ?>
</div> </div>
</div> </div>
@@ -315,19 +315,19 @@ ob_start();
</div> </div>
<div class="card-body"> <div class="card-body">
<?php if ($location_name) { ?> <?php if ($location_name) { ?>
<div><i class="fa fa-fw fa-map-marker-alt text-secondary mr-3"></i><?php echo $location_name_display; ?></div> <div><i class="fa fa-fw fa-map-marker-alt text-secondary mr-2"></i><?php echo $location_name_display; ?></div>
<?php } <?php }
if ($contact_name) { ?> if ($contact_name) { ?>
<div class="mt-2"><i class="fa fa-fw fa-user text-secondary mr-3"></i><?php echo $contact_name_display; ?></div> <div class="mt-2"><i class="fa fa-fw fa-user text-secondary mr-2"></i><?php echo $contact_name_display; ?></div>
<?php } <?php }
if ($contact_email) { ?> if ($contact_email) { ?>
<div class="mt-2"><i class="fa fa-fw fa-envelope text-secondary mr-3"></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> <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 } <?php }
if ($contact_phone) { ?> if ($contact_phone) { ?>
<div class="mt-2"><i class="fa fa-fw fa-phone text-secondary mr-3"></i><?php echo formatPhoneNumber($contact_phone); echo " $contact_extension"; ?></div> <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 } <?php }
if ($contact_mobile) { ?> if ($contact_mobile) { ?>
<div class="mt-2"><i class="fa fa-fw fa-mobile-alt text-secondary mr-3"></i><?php echo formatPhoneNumber($contact_mobile); ?></div> <div class="mt-2"><i class="fa fa-fw fa-mobile-alt text-secondary mr-2"></i><?php echo formatPhoneNumber($contact_mobile); ?></div>
<?php } ?> <?php } ?>
</div> </div>

View File

@@ -125,7 +125,6 @@ $sql_linked_documents = mysqli_query($mysqli, "SELECT * FROM contact_documents,
LEFT JOIN users ON document_created_by = user_id LEFT JOIN users ON document_created_by = user_id
WHERE contact_documents.contact_id = $contact_id WHERE contact_documents.contact_id = $contact_id
AND contact_documents.document_id = documents.document_id AND contact_documents.document_id = documents.document_id
AND document_template = 0
AND document_archived_at IS NULL AND document_archived_at IS NULL
ORDER BY document_name ASC" ORDER BY document_name ASC"
); );

View File

@@ -12,6 +12,8 @@ $credential_name = nullable_htmlentities($row['credential_name']);
$credential_description = nullable_htmlentities($row['credential_description']); $credential_description = nullable_htmlentities($row['credential_description']);
$credential_uri = nullable_htmlentities($row['credential_uri']); $credential_uri = nullable_htmlentities($row['credential_uri']);
$credential_uri_2 = nullable_htmlentities($row['credential_uri_2']); $credential_uri_2 = nullable_htmlentities($row['credential_uri_2']);
$credential_uri_link = sanitize_url($row['credential_uri']);
$credential_uri_2_link = sanitize_url($row['credential_uri_2']);
$credential_username = nullable_htmlentities(decryptCredentialEntry($row['credential_username'])); $credential_username = nullable_htmlentities(decryptCredentialEntry($row['credential_username']));
$credential_password = nullable_htmlentities(decryptCredentialEntry($row['credential_password'])); $credential_password = nullable_htmlentities(decryptCredentialEntry($row['credential_password']));
$credential_otp_secret = nullable_htmlentities($row['credential_otp_secret']); $credential_otp_secret = nullable_htmlentities($row['credential_otp_secret']);
@@ -137,7 +139,7 @@ ob_start();
<input type="text" class="form-control" name="uri" placeholder="ex. http://192.168.1.1" maxlength="500" value="<?php echo $credential_uri; ?>"> <input type="text" class="form-control" name="uri" placeholder="ex. http://192.168.1.1" maxlength="500" value="<?php echo $credential_uri; ?>">
<div class="input-group-append"> <div class="input-group-append">
<a href="<?php echo $credential_uri; ?>" class="input-group-text"><i class="fa fa-fw fa-link"></i></a> <a href="<?php echo $credential_uri_link; ?>" target="_blank" class="input-group-text"><i class="fa fa-fw fa-link"></i></a>
</div> </div>
<div class="input-group-append"> <div class="input-group-append">
<button class="input-group-text clipboardjs" type="button" data-clipboard-text="<?php echo $credential_uri; ?>"><i class="fa fa-fw fa-copy"></i></button> <button class="input-group-text clipboardjs" type="button" data-clipboard-text="<?php echo $credential_uri; ?>"><i class="fa fa-fw fa-copy"></i></button>
@@ -153,7 +155,7 @@ ob_start();
</div> </div>
<input type="text" class="form-control" name="uri_2" placeholder="ex. https://server.company.com:5001" maxlength="500" value="<?php echo $credential_uri_2; ?>"> <input type="text" class="form-control" name="uri_2" placeholder="ex. https://server.company.com:5001" maxlength="500" value="<?php echo $credential_uri_2; ?>">
<div class="input-group-append"> <div class="input-group-append">
<a href="<?php echo $credential_uri_2; ?>" class="input-group-text"><i class="fa fa-fw fa-link"></i></a> <a href="<?php echo $credential_uri_2_link; ?>" target="_blank" class="input-group-text"><i class="fa fa-fw fa-link"></i></a>
</div> </div>
<div class="input-group-append"> <div class="input-group-append">
<button class="input-group-text clipboardjs" type="button" data-clipboard-text="<?php echo $credential_uri_2; ?>"><i class="fa fa-fw fa-copy"></i></button> <button class="input-group-text clipboardjs" type="button" data-clipboard-text="<?php echo $credential_uri_2; ?>"><i class="fa fa-fw fa-copy"></i></button>

View File

@@ -10,12 +10,7 @@ $row = mysqli_fetch_array($sql);
$document_name = nullable_htmlentities($row['document_name']); $document_name = nullable_htmlentities($row['document_name']);
$document_description = nullable_htmlentities($row['document_description']); $document_description = nullable_htmlentities($row['document_description']);
$document_content = nullable_htmlentities($row['document_content']); $document_content = nullable_htmlentities($row['document_content']);
$document_created_by_id = intval($row['document_created_by']);
$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_folder_id = intval($row['document_folder_id']);
$document_parent = intval($row['document_parent']);
$document_client_visible = intval($row['document_client_visible']); $document_client_visible = intval($row['document_client_visible']);
$client_id = intval($row['document_client_id']); $client_id = intval($row['document_client_id']);
@@ -30,10 +25,8 @@ ob_start();
</button> </button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="document_id" value="<?php if($document_parent == 0){ echo $document_id; } else { echo $document_parent; } ?>"> <input type="hidden" name="document_id" value="<?php echo $document_id; ?>">
<input type="hidden" name="document_parent" value="<?php echo $document_parent; ?>">
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>"> <input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<input type="hidden" name="created_by" value="<?php echo $document_created_by_id; ?>">
<div class="modal-body bg-white"> <div class="modal-body bg-white">
<div class="form-group"> <div class="form-group">

View File

@@ -2,38 +2,38 @@
require_once '../includes/ajax_header.php'; require_once '../includes/ajax_header.php';
$document_id = intval($_GET['id']); $document_template_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM documents WHERE document_id = $document_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM document_templates WHERE document_template_id = $document_template_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_array($sql);
$document_name = nullable_htmlentities($row['document_name']); $document_template_name = nullable_htmlentities($row['document_template_name']);
$document_description = nullable_htmlentities($row['document_description']); $document_template_description = nullable_htmlentities($row['document_template_description']);
$document_content = nullable_htmlentities($row['document_content']); $document_template_content = nullable_htmlentities($row['document_template_content']);
// Generate the HTML form content using output buffering. // Generate the HTML form content using output buffering.
ob_start(); ob_start();
?> ?>
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title"><i class="fa fa-fw fa-file-alt mr-2"></i>Editing template: <strong><?php echo $document_name; ?></strong></h5> <h5 class="modal-title"><i class="fa fa-fw fa-file-alt mr-2"></i>Editing template: <strong><?php echo $document_template_name; ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span> <span>&times;</span>
</button> </button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="document_id" value="<?php echo $document_id; ?>"> <input type="hidden" name="document_template_id" value="<?php echo $document_template_id; ?>">
<div class="modal-body bg-white"> <div class="modal-body bg-white">
<div class="form-group"> <div class="form-group">
<input type="text" class="form-control" name="name" maxlength="200" value="<?php echo $document_name; ?>" placeholder="Name" required> <input type="text" class="form-control" name="name" maxlength="200" value="<?php echo $document_template_name; ?>" placeholder="Name" required>
</div> </div>
<div class="form-group"> <div class="form-group">
<textarea class="form-control tinymce" name="content"><?php echo $document_content; ?></textarea> <textarea class="form-control tinymce" name="content"><?php echo $document_template_content; ?></textarea>
</div> </div>
<div class="form-group"> <div class="form-group">
<input type="text" class="form-control" name="description" value="<?php echo $document_description; ?>" placeholder="Short summary"> <input type="text" class="form-control" name="description" value="<?php echo $document_template_description; ?>" placeholder="Short summary">
</div> </div>
</div> </div>

View File

@@ -0,0 +1,39 @@
<?php
require_once '../includes/ajax_header.php';
// Initialize the HTML Purifier to prevent XSS
require_once "../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);
$document_version_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM document_versions WHERE document_version_id = $document_version_id LIMIT 1");
$row = mysqli_fetch_array($sql);
$document_version_name = nullable_htmlentities($row['document_version_name']);
$document_version_content = $purifier->purify($row['document_version_content']);
// Generate the HTML form content using output buffering.
ob_start();
?>
<div class="modal-header">
<h5 class="modal-title text-white"><i class="fa fa-fw fa-file-alt mr-2"></i><?php echo $document_version_name; ?></h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body bg-white prettyContent">
<?php echo $document_version_content; ?>
</div>
<script src="../js/pretty_content.js"></script>
<?php
require_once "../includes/ajax_footer.php";

View File

@@ -33,5 +33,8 @@ ob_start();
<?php echo $document_content; ?> <?php echo $document_content; ?>
</div> </div>
<script src="../js/pretty_content.js"></script>
<?php <?php
require_once "../includes/ajax_footer.php"; require_once "../includes/ajax_footer.php";

View File

@@ -105,7 +105,7 @@ ob_start();
<select class="form-control select2" name="vendor" required> <select class="form-control select2" name="vendor" required>
<?php <?php
$sql_vendors = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = 0 AND vendor_template = 0 ORDER BY vendor_name ASC"); $sql_vendors = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = 0 ORDER BY vendor_name ASC");
while ($row = mysqli_fetch_array($sql_vendors)) { while ($row = mysqli_fetch_array($sql_vendors)) {
$vendor_id_select = intval($row['vendor_id']); $vendor_id_select = intval($row['vendor_id']);
$vendor_name_select = nullable_htmlentities($row['vendor_name']); $vendor_name_select = nullable_htmlentities($row['vendor_name']);

View File

@@ -119,7 +119,7 @@ ob_start();
<select class="form-control select2" name="vendor" required> <select class="form-control select2" name="vendor" required>
<?php <?php
$sql_select = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = 0 AND vendor_template = 0 AND (vendor_archived_at > '$expense_created_at' OR vendor_archived_at IS NULL) ORDER BY vendor_name ASC"); $sql_select = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = 0 AND (vendor_archived_at > '$expense_created_at' OR vendor_archived_at IS NULL) ORDER BY vendor_name ASC");
while ($row = mysqli_fetch_array($sql_select)) { while ($row = mysqli_fetch_array($sql_select)) {
$vendor_id_select = intval($row['vendor_id']); $vendor_id_select = intval($row['vendor_id']);
$vendor_name_select = nullable_htmlentities($row['vendor_name']); $vendor_name_select = nullable_htmlentities($row['vendor_name']);

182
ajax/ajax_invoice_pay.php Normal file
View File

@@ -0,0 +1,182 @@
<?php
require_once '../includes/ajax_header.php';
$invoice_id = intval($_GET['id']);
$sql = mysqli_query(
$mysqli,
"SELECT * FROM invoices
LEFT JOIN clients ON invoice_client_id = client_id
LEFT JOIN contacts ON client_id = contact_client_id AND contact_primary = 1
WHERE invoice_id = $invoice_id
LIMIT 1"
);
$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_amount = floatval($row['invoice_amount']);
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
$client_currency_code = nullable_htmlentities($row['client_currency_code']);
$contact_name = nullable_htmlentities($row['contact_name']);
$contact_email = nullable_htmlentities($row['contact_email']);
//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;
// Generate the HTML form content using output buffering.
ob_start();
?>
<div class="modal-header">
<h5 class="modal-title"><i class="fa fa-fw fa-credit-card mr-2"></i><?php echo "$invoice_prefix$invoice_number"; ?>: Make Payment</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="invoice_id" value="<?php echo $invoice_id; ?>">
<input type="hidden" name="balance" value="<?php echo $balance; ?>">
<input type="hidden" name="currency_code" value="<?php echo $client_currency_code; ?>">
<div class="modal-body bg-white">
<div class="form-row">
<div class="col-md">
<div class="form-group">
<label>Date <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>
<input type="date" class="form-control" name="date" max="2999-12-31" value="<?php echo date("Y-m-d"); ?>" required>
</div>
</div>
</div>
<div class="col-md">
<div class="form-group">
<label>Amount <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="amount" value="<?php echo number_format($balance, 2, '.', ''); ?>" placeholder="0.00" required>
</div>
</div>
</div>
</div>
<div class="form-group">
<label>Account <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>
<select class="form-control select2" name="account" required>
<option value="">- Select an Account -</option>
<?php
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
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']);
$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']);
$account_balance = $opening_balance + $total_payments + $total_revenues - $total_expenses;
?>
<option <?php if ($config_default_payment_account == $account_id) { echo "selected"; } ?>
value="<?php echo $account_id; ?>">
<?php echo $account_name; ?> [$<?php echo number_format($account_balance, 2); ?>]
</option>
<?php
}
?>
</select>
</div>
</div>
<div class="form-group">
<label>Payment Method <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-check-alt"></i></span>
</div>
<select class="form-control select2" name="payment_method" required>
<option value="">- Method of Payment -</option>
<?php
$sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Payment Method' AND category_archived_at IS NULL ORDER BY category_name ASC");
while ($row = mysqli_fetch_array($sql)) {
$category_name = nullable_htmlentities($row['category_name']);
?>
<option <?php if ($config_default_payment_method == $category_name) {
echo "selected";
} ?>><?php echo $category_name; ?></option>
<?php
}
?>
</select>
</div>
</div>
<div class="form-group">
<label>Reference</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="reference" placeholder="Check #, Trans #, etc" maxlength="200">
</div>
</div>
<?php if (!empty($config_smtp_host) && !empty($contact_email)) { ?>
<div class="form-group">
<label>Email Receipt</label>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="customControlAutosizing" name="email_receipt" value="1" checked>
<label class="custom-control-label" for="customControlAutosizing"><?php echo $contact_email; ?></label>
</div>
</div>
<?php } ?>
</div>
<div class="modal-footer bg-white">
<button type="submit" name="add_payment" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Pay</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
</div>
</form>
<?php
require_once "../includes/ajax_footer.php";

View File

@@ -157,7 +157,7 @@ ob_start();
<select class="form-control select2" name="vendor" required> <select class="form-control select2" name="vendor" required>
<?php <?php
$sql_select = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = 0 AND vendor_template = 0 AND (vendor_archived_at > '$recurring_expense_created_at' OR vendor_archived_at IS NULL) ORDER BY vendor_name ASC"); $sql_select = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = 0 AND (vendor_archived_at > '$recurring_expense_created_at' OR vendor_archived_at IS NULL) ORDER BY vendor_name ASC");
while ($row = mysqli_fetch_array($sql_select)) { while ($row = mysqli_fetch_array($sql_select)) {
$vendor_id_select = intval($row['vendor_id']); $vendor_id_select = intval($row['vendor_id']);
$vendor_name_select = nullable_htmlentities($row['vendor_name']); $vendor_name_select = nullable_htmlentities($row['vendor_name']);

View File

@@ -16,6 +16,7 @@ $recurring_ticket_next_run = nullable_htmlentities($row['recurring_ticket_next_r
$recurring_ticket_assigned_to = intval($row['recurring_ticket_assigned_to']); $recurring_ticket_assigned_to = intval($row['recurring_ticket_assigned_to']);
$recurring_ticket_contact_id = intval($row['recurring_ticket_contact_id']); $recurring_ticket_contact_id = intval($row['recurring_ticket_contact_id']);
$recurring_ticket_asset_id = intval($row['recurring_ticket_asset_id']); $recurring_ticket_asset_id = intval($row['recurring_ticket_asset_id']);
$recurring_ticket_category = intval($row['recurring_ticket_category']);
$recurring_ticket_billable = intval($row['recurring_ticket_billable']); $recurring_ticket_billable = intval($row['recurring_ticket_billable']);
// Additional Assets Selected // Additional Assets Selected
@@ -75,17 +76,53 @@ ob_start();
<textarea class="form-control tinymce" name="details"><?php echo $recurring_ticket_details; ?></textarea> <textarea class="form-control tinymce" name="details"><?php echo $recurring_ticket_details; ?></textarea>
</div> </div>
<div class="form-group"> <div class="row">
<label>Priority <strong class="text-danger">*</strong></label> <div class="col">
<div class="input-group"> <div class="form-group">
<div class="input-group-prepend"> <label>Priority <strong class="text-danger">*</strong></label>
<span class="input-group-text"><i class="fa fa-fw fa-thermometer-half"></i></span> <div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-thermometer-half"></i></span>
</div>
<select class="form-control select2" name="priority" required>
<option <?php if ($recurring_ticket_priority == "Low") { echo "selected"; } ?> >Low</option>
<option <?php if ($recurring_ticket_priority == "Medium") { echo "selected"; } ?> >Medium</option>
<option <?php if ($recurring_ticket_priority == "High") { echo "selected"; } ?> >High</option>
</select>
</div>
</div>
</div>
<div class="col">
<div class="form-group">
<label>Category</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-layer-group"></i></span>
</div>
<select class="form-control select2" name="category">
<option value="0">- Uncategorized -</option>
<?php
$sql_categories = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Ticket' AND category_archived_at IS NULL ORDER BY category_name ASC");
while ($row = mysqli_fetch_array($sql_categories)) {
$category_id = intval($row['category_id']);
$category_name = nullable_htmlentities($row['category_name']);
?>
<option <?php if ($recurring_ticket_category == $category_id) {echo "selected";} ?> value="<?php echo $category_id; ?>"><?php echo $category_name; ?></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=Ticket">
<i class="fas fa-fw fa-plus"></i>
</button>
</div>
</div>
</div> </div>
<select class="form-control select2" name="priority" required>
<option <?php if ($recurring_ticket_priority == "Low") { echo "selected"; } ?> >Low</option>
<option <?php if ($recurring_ticket_priority == "Medium") { echo "selected"; } ?> >Medium</option>
<option <?php if ($recurring_ticket_priority == "High") { echo "selected"; } ?> >High</option>
</select>
</div> </div>
</div> </div>

View File

@@ -5,7 +5,6 @@ require_once '../includes/ajax_header.php';
$service_id = intval($_GET['id']); $service_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM services WHERE service_id = $service_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM services WHERE service_id = $service_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_array($sql);
$service_name = nullable_htmlentities($row['service_name']); $service_name = nullable_htmlentities($row['service_name']);
$service_description = nullable_htmlentities($row['service_description']); $service_description = nullable_htmlentities($row['service_description']);
@@ -17,6 +16,7 @@ $service_created_at = nullable_htmlentities($row['service_created_at']);
$service_updated_at = nullable_htmlentities($row['service_updated_at']); $service_updated_at = nullable_htmlentities($row['service_updated_at']);
$service_review_due = nullable_htmlentities($row['service_review_due']); $service_review_due = nullable_htmlentities($row['service_review_due']);
$client_id = intval($row['service_client_id']); $client_id = intval($row['service_client_id']);
// Service Importance // Service Importance
if ($service_importance == "High") { if ($service_importance == "High") {
$service_importance_display = "<span class='p-2 badge badge-danger'>$service_importance</span>"; $service_importance_display = "<span class='p-2 badge badge-danger'>$service_importance</span>";
@@ -55,6 +55,7 @@ $sql_domains = mysqli_query(
LEFT JOIN domains ON service_domains.domain_id = domains.domain_id LEFT JOIN domains ON service_domains.domain_id = domains.domain_id
WHERE service_id = $service_id" WHERE service_id = $service_id"
); );
// Associated Certificates // Associated Certificates
$sql_certificates = mysqli_query( $sql_certificates = mysqli_query(
$mysqli, $mysqli,
@@ -63,10 +64,6 @@ $sql_certificates = mysqli_query(
WHERE service_id = $service_id" WHERE service_id = $service_id"
); );
// Associated URLs ---- REMOVED for now
//$sql_urls = mysqli_query($mysqli, "SELECT * FROM service_urls
//WHERE service_id = '$service_id'");
// Associated Vendors // Associated Vendors
$sql_vendors = mysqli_query( $sql_vendors = mysqli_query(
$mysqli, $mysqli,
@@ -116,149 +113,99 @@ ob_start();
<!-- Assets --> <!-- Assets -->
<?php <?php
if (mysqli_num_rows($sql_assets) > 0) { ?> if (mysqli_num_rows($sql_assets) > 0) {
<h5><i class="fas fa-fw fa-desktop mr-2"></i>Assets</h5> echo "<h5><i class='fas fa-fw fa-desktop mr-2'></i>Assets</h5><ul>";
<ul> mysqli_data_seek($sql_assets, 0);
<?php while ($row = mysqli_fetch_array($sql_assets)) {
// Reset the $sql_assets pointer to the start - as we've already cycled through once $asset_id = intval($row['asset_id']);
mysqli_data_seek($sql_assets, 0); $asset_name = nullable_htmlentities($row['asset_name']);
$ip = !empty($row['interface_ip']) ? '(' . nullable_htmlentities($row['interface_ip']) . ')' : '';
while ($row = mysqli_fetch_array($sql_assets)) { echo "<li><a href='#' data-toggle='ajax-modal' data-modal-size='lg' data-ajax-url='ajax/ajax_asset_details.php' data-ajax-id='$asset_id'>$asset_name</a>$ip</li>";
$asset_id = intval($row['asset_id']); }
$asset_name = nullable_htmlentities($row['asset_name']); echo "</ul>";
if (!empty($row['interface_ip'])) {
$ip = '('.nullable_htmlentities($row["interface_ip"]).')';
} else {
$ip = '';
}
echo "<li><a href='#' data-toggle='ajax-modal'
data-modal-size='lg'
data-ajax-url='ajax/ajax_asset_details.php'
data-ajax-id='$asset_id'>$asset_name</a>$ip</li>";
}
?>
</ul>
<?php
} }
?> ?>
<!-- Networks --> <!-- Networks -->
<?php <?php
$networks = [];
if ($sql_assets) { if ($sql_assets) {
$networks = [];
// Reset the $sql_assets pointer to the start
mysqli_data_seek($sql_assets, 0); mysqli_data_seek($sql_assets, 0);
// Get networks linked to assets - push name to array
while ($row = mysqli_fetch_array($sql_assets)) { while ($row = mysqli_fetch_array($sql_assets)) {
if (!empty($row['network_name'])) { if (!empty($row['network_name'])) {
$network_data = nullable_htmlentities("$row[network_name]:$row[network_vlan]"); $network_data = nullable_htmlentities($row["network_name"]) . ':' . nullable_htmlentities($row["network_vlan"]);
array_push($networks, $network_data); $networks[] = $network_data;
} }
} }
// Remove duplicates
$networks = array_unique($networks); $networks = array_unique($networks);
if (!empty($networks)) {
// Display echo "<h5><i class='fas fa-fw fa-network-wired mr-2'></i>Networks</h5><ul>";
if (!empty($networks)) { ?> foreach ($networks as $network) {
<h5><i class="fas fa-fw fa-network-wired mr-2"></i>Networks</h5> $network_parts = explode(":", $network);
<ul> $network_name = $network_parts[0];
<?php $network_vlan = $network_parts[1] ?? '';
echo "<li><a href='networks.php?client_id=$client_id&q=$network_name'>$network_name</a> (VLAN $network_vlan)</li>";
}
echo "</ul>";
} }
foreach($networks as $network) {
$network = explode(":", $network);
echo "<li><a href=\"networks.php?client_id=$client_id&q=$network[0]\">$network[0] </a>(VLAN $network[1])</li>";
}
?>
</ul>
<?php
} }
?> ?>
<!-- Locations --> <!-- Locations -->
<?php <?php
$location_names = [];
if ($sql_assets) { if ($sql_assets) {
$location_names = [];
// Reset the $sql_assets pointer to the start - as we've already cycled through once
mysqli_data_seek($sql_assets, 0); mysqli_data_seek($sql_assets, 0);
// Get locations linked to assets - push their name and vlan to arrays
while ($row = mysqli_fetch_array($sql_assets)) { while ($row = mysqli_fetch_array($sql_assets)) {
if (!empty($row['location_name'])) { if (!empty($row['location_name'])) {
array_push($location_names, $row['location_name']); $location_names[] = nullable_htmlentities($row['location_name']);
} }
} }
// Remove duplicates
$location_names = array_unique($location_names); $location_names = array_unique($location_names);
if (!empty($location_names)) {
// Display echo "<h5><i class='fas fa-fw fa-map-marker-alt mr-2'></i>Locations</h5><ul>";
if (!empty($location_names)) { ?> foreach ($location_names as $location) {
<h5><i class="fas fa-fw fa-map-marker-alt mr-2"></i>Locations</h5> echo "<li><a href='locations.php?client_id=$client_id&q=$location'>$location</a></li>";
<ul> }
<?php echo "</ul>";
} }
foreach($location_names as $location) {
echo "<li><a href=\"locations.php?client_id=$client_id&q=$location\">$location</a></li>";
}
?>
</ul>
<?php
} }
?> ?>
<!-- Domains --> <!-- Domains -->
<?php <?php
if (mysqli_num_rows($sql_domains) > 0) { ?> if (mysqli_num_rows($sql_domains) > 0) {
<h5><i class="fas fa-fw fa-globe mr-2"></i>Domains</h5> echo "<h5><i class='fas fa-fw fa-globe mr-2'></i>Domains</h5><ul>";
<ul> mysqli_data_seek($sql_domains, 0);
<?php while ($row = mysqli_fetch_array($sql_domains)) {
// Reset the $sql_domains pointer to the start if (!empty($row['domain_name'])) {
mysqli_data_seek($sql_domains, 0); $domain_name = nullable_htmlentities($row['domain_name']);
echo "<li><a href='domains.php?client_id=$client_id&q=$domain_name'>$domain_name</a></li>";
// Showing linked domains
while ($row = mysqli_fetch_array($sql_domains)) {
if (!empty($row['domain_name'])) {
echo "<li><a href=\"domains.php?client_id=$client_id&q=$row[domain_name]\">$row[domain_name]</a></li>";
}
} }
?> }
</ul> echo "</ul>";
<?php
} }
?> ?>
<!-- Certificates --> <!-- Certificates -->
<?php <?php
if (mysqli_num_rows($sql_certificates) > 0) { ?> if (mysqli_num_rows($sql_certificates) > 0) {
<h5><i class="fas fa-fw fa-lock mr-2"></i>Certificates</h5> echo "<h5><i class='fas fa-fw fa-lock mr-2'></i>Certificates</h5><ul>";
<ul> mysqli_data_seek($sql_certificates, 0);
<?php while ($row = mysqli_fetch_array($sql_certificates)) {
// Reset the $sql_certificates pointer to the start if (!empty($row['certificate_name'])) {
mysqli_data_seek($sql_certificates, 0); $certificate_name = nullable_htmlentities($row['certificate_name']);
$certificate_domain = nullable_htmlentities($row['certificate_domain']);
// Showing linked certs echo "<li><a href='certificates.php?client_id=$client_id&q=$certificate_name'>$certificate_name ($certificate_domain)</a></li>";
while ($row = mysqli_fetch_array($sql_certificates)) {
if (!empty($row['certificate_name'])) {
echo "<li><a href=\"certificates.php?client_id=$client_id&q=$row[certificate_name]\">$row[certificate_name] ($row[certificate_domain])</a></li>";
}
} }
?> }
</ul> echo "</ul>";
<?php
} }
?> ?>
</div> </div>
</div> </div>
<!-- Right side --> <!-- Right side -->
<div class="col-4"> <div class="col-4">
<div class="col-12"> <div class="col-12">
@@ -267,148 +214,96 @@ ob_start();
<!-- Vendors --> <!-- Vendors -->
<?php <?php
// Reset the $sql_vendors pointer to the start if (mysqli_num_rows($sql_vendors) > 0) {
mysqli_data_seek($sql_vendors, 0); echo "<h5><i class='fas fa-fw fa-building mr-2'></i>Vendors</h5><ul>";
mysqli_data_seek($sql_vendors, 0);
if (mysqli_num_rows($sql_vendors) > 0) { ?> while ($row = mysqli_fetch_array($sql_vendors)) {
<h5><i class="fas fa-fw fa-building mr-2"></i>Vendors</h5> $vendor_id = intval($row['vendor_id']);
<ul> $vendor_name = nullable_htmlentities($row['vendor_name']);
<?php echo "<li><a href='#' data-toggle='ajax-modal' data-modal-size='lg' data-ajax-url='ajax/ajax_vendor_details.php' data-ajax-id='$vendor_id'>$vendor_name</a></li>";
while ($row = mysqli_fetch_array($sql_vendors)) { }
echo "</ul>";
$vendor_id = intval($row['vendor_id']);
$vendor_name = nullable_htmlentities($row['vendor_name']);
echo "<li><a href='#' data-toggle='ajax-modal'
data-modal-size='lg'
data-ajax-url='ajax/ajax_vendor_details.php'
data-ajax-id='$vendor_id'>
$vendor_name
</a>
</li>";
}
?>
</ul>
<?php
} }
?> ?>
<!-- Contacts --> <!-- Contacts -->
<?php <?php
if (mysqli_num_rows($sql_contacts) > 0) { ?> if (mysqli_num_rows($sql_contacts) > 0) {
<h5><i class="fas fa-fw fa-users mr-2"></i>Contacts</h5> echo "<h5><i class='fas fa-fw fa-users mr-2'></i>Contacts</h5><ul>";
<ul> mysqli_data_seek($sql_contacts, 0);
<?php while ($row = mysqli_fetch_array($sql_contacts)) {
// Reset the $sql_contacts pointer to the start $contact_id = intval($row['contact_id']);
mysqli_data_seek($sql_contacts, 0); $contact_name = nullable_htmlentities($row['contact_name']);
echo "<li><a href='#' data-toggle='ajax-modal' data-modal-size='lg' data-ajax-url='ajax/ajax_contact_details.php' data-ajax-id='$contact_id'>$contact_name</a></li>";
while ($row = mysqli_fetch_array($sql_contacts)) { }
$contact_id = intval($row['contact_id']); echo "</ul>";
$contact_name = nullable_htmlentities($row['contact_name']);
echo "<li><a href='#' data-toggle='ajax-modal'
data-modal-size='lg'
data-ajax-url='ajax/ajax_contact_details.php'
data-ajax-id='$contact_id'>
$contact_name
</a>
</li>";
}
?>
</ul>
<?php
} }
?> ?>
<!-- Credentials --> <!-- Credentials -->
<?php <?php
if (mysqli_num_rows($sql_assets) > 0 || mysqli_num_rows($sql_credentials) > 0) { ?> if (mysqli_num_rows($sql_assets) > 0 || mysqli_num_rows($sql_credentials) > 0) {
<h5><i class="fas fa-fw fa-key mr-2"></i>Credentials</h5> echo "<h5><i class='fas fa-fw fa-key mr-2'></i>Credentials</h5><ul>";
<ul> // Credentials linked to assets
<?php mysqli_data_seek($sql_assets, 0);
// Reset the $sql_assets/credentials pointer to the start while ($row = mysqli_fetch_array($sql_assets)) {
mysqli_data_seek($sql_assets, 0); $credential_name = nullable_htmlentities($row['credential_name']);
mysqli_data_seek($sql_credentials, 0); if (!empty($credential_name)) {
echo "<li><a href='credentials.php?client_id=$client_id&q=$credential_name'>$credential_name</a></li>";
// Showing credentials linked to assets
while ($row = mysqli_fetch_array($sql_assets)) {
if (!empty($row['credential_name'])) {
echo "<li><a href=\"credentials.php?client_id=$client_id&q=$row[credential_name]\">$row[credential_name]</a></li>";
}
} }
}
// Showing explicitly linked credentials // Explicitly linked credentials
while ($row = mysqli_fetch_array($sql_credentials)) { mysqli_data_seek($sql_credentials, 0);
if (!empty($row['credential_name'])) { while ($row = mysqli_fetch_array($sql_credentials)) {
echo "<li><a href=\"credentials.php?client_id=$client_id&q=$row[credential_name]\">$row[credential_name]</a></li>"; $credential_name = nullable_htmlentities($row['credential_name']);
} if (!empty($credential_name)) {
echo "<li><a href='credentials.php?client_id=$client_id&q=$credential_name'>$credential_name</a></li>";
} }
?> }
</ul> echo "</ul>";
<?php
} }
?> ?>
<!-- URLs --> <!-- URLs -->
<?php <?php
if ($sql_credentials || $sql_assets) { ?> $urls = [];
<h5><i class="fas fa-fw fa-link mr-2"></i>URLs</h5> mysqli_data_seek($sql_credentials, 0);
<ul> while ($row = mysqli_fetch_array($sql_credentials)) {
<?php if (!empty($row['credential_uri'])) {
// Reset the $sql_credentials pointer to the start $urls[] = sanitize_url($row['credential_uri']);
mysqli_data_seek($sql_credentials, 0); }
}
// Showing URLs linked to credentials mysqli_data_seek($sql_assets, 0);
while ($row = mysqli_fetch_array($sql_credentials)) { while ($row = mysqli_fetch_array($sql_assets)) {
if (!empty($row['credential_uri'])) { if (!empty($row['asset_uri'])) {
echo "<li><a href=\"https://$row[credential_uri]\">$row[credential_uri]</a></li>"; $urls[] = sanitize_url($row['asset_uri']);
} }
} }
$urls = array_unique($urls);
// Reset the $sql_assets pointer to the start if (!empty($urls)) {
mysqli_data_seek($sql_assets, 0); echo "<h5><i class='fas fa-fw fa-link mr-2'></i>URLs</h5><ul>";
foreach ($urls as $url) {
// Show URLs linked to assets, that also have credentials $label = htmlspecialchars(parse_url($url, PHP_URL_HOST) ?: $url);
while ($row = mysqli_fetch_array($sql_assets)) { echo "<li><a href='$url' target='_blank'>$label</a></li>";
if (!empty($row['credential_uri'])) { }
echo "<li><a href=\"https://$row[credential_uri]\">$row[credential_uri]</a></li>"; echo "</ul>";
}
}
?>
</ul>
<?php
} }
?> ?>
<!-- Documents --> <!-- Documents -->
<?php <?php
if (mysqli_num_rows($sql_docs) > 0) { ?> if (mysqli_num_rows($sql_docs) > 0) {
<h5><i class="fas fa-fw fa-file-alt mr-2"></i>Documents</h5> echo "<h5><i class='fas fa-fw fa-file-alt mr-2'></i>Documents</h5><ul>";
<ul> mysqli_data_seek($sql_docs, 0);
<?php while ($row = mysqli_fetch_array($sql_docs)) {
// Reset the $sql_docs pointer to the start $document_id = intval($row['document_id']);
mysqli_data_seek($sql_docs, 0); $document_name = nullable_htmlentities($row['document_name']);
echo "<li><a href='#' data-toggle='ajax-modal' data-modal-size='lg' data-ajax-url='ajax/ajax_document_view.php' data-ajax-id='$document_id'>$document_name</a></li>";
while ($row = mysqli_fetch_array($sql_docs)) { }
$document_id = intval($row['document_id']); echo "</ul>";
$document_name = nullable_htmlentities($row['document_name']);
echo "<li><a href='#' data-toggle='ajax-modal'
data-modal-size='lg'
data-ajax-url='ajax/ajax_document_view.php'
data-ajax-id='$document_id'>
$document_name
</a>
</li>";
}
?>
</ul>
<?php
} }
?> ?>
<!-- <h5><i class="nav-icon fas fa-file-alt"></i> Services</h5>-->
<!-- <ul>-->
<!-- <li>Related Service - Coming soon!</li>-->
<!-- </ul>-->
</div> </div>
</div> </div>
</div> </div>
@@ -416,3 +311,4 @@ ob_start();
<?php <?php
require_once "../includes/ajax_footer.php"; require_once "../includes/ajax_footer.php";
?>

View File

@@ -211,7 +211,7 @@ ob_start();
<?php <?php
$selected_ids = array_column(mysqli_fetch_all($sql_vendors, MYSQLI_ASSOC), "vendor_id"); $selected_ids = array_column(mysqli_fetch_all($sql_vendors, MYSQLI_ASSOC), "vendor_id");
$sql_all = mysqli_query($mysqli, "SELECT * FROM vendors WHERE (vendor_archived_at > '$service_created_at' OR vendor_archived_at IS NULL) AND vendor_template = 0 AND vendor_client_id = $client_id"); $sql_all = mysqli_query($mysqli, "SELECT * FROM vendors WHERE (vendor_archived_at > '$service_created_at' OR vendor_archived_at IS NULL) AND vendor_client_id = $client_id");
while ($row_all = mysqli_fetch_array($sql_all)) { while ($row_all = mysqli_fetch_array($sql_all)) {
$vendor_id = intval($row_all['vendor_id']); $vendor_id = intval($row_all['vendor_id']);
$vendor_name = nullable_htmlentities($row_all['vendor_name']); $vendor_name = nullable_htmlentities($row_all['vendor_name']);

View File

@@ -2,16 +2,16 @@
require_once '../includes/ajax_header.php'; require_once '../includes/ajax_header.php';
$software_id = intval($_GET['id']); $software_template_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM software WHERE software_id = $software_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM software_templates WHERE software_template_id = $software_template_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_array($sql);
$software_name = nullable_htmlentities($row['software_name']); $software_name = nullable_htmlentities($row['software_template_name']);
$software_version = nullable_htmlentities($row['software_version']); $software_version = nullable_htmlentities($row['software_template_version']);
$software_description = nullable_htmlentities($row['software_description']); $software_description = nullable_htmlentities($row['software_template_description']);
$software_type = nullable_htmlentities($row['software_type']); $software_type = nullable_htmlentities($row['software_template_type']);
$software_license_type = nullable_htmlentities($row['software_license_type']); $software_license_type = nullable_htmlentities($row['software_template_license_type']);
$software_notes = nullable_htmlentities($row['software_notes']); $software_notes = nullable_htmlentities($row['software_template_notes']);
// Generate the HTML form content using output buffering. // Generate the HTML form content using output buffering.
ob_start(); ob_start();
@@ -24,7 +24,7 @@ ob_start();
</button> </button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="software_id" value="<?php echo $software_id; ?>"> <input type="hidden" name="software_template_id" value="<?php echo $software_template_id; ?>">
<div class="modal-body bg-white"> <div class="modal-body bg-white">
<div class="form-group"> <div class="form-group">

View File

@@ -18,6 +18,8 @@ $ticket_priority = nullable_htmlentities($row['ticket_priority']);
$ticket_billable = intval($row['ticket_billable']); $ticket_billable = intval($row['ticket_billable']);
$ticket_vendor_ticket_number = nullable_htmlentities($row['ticket_vendor_ticket_number']); $ticket_vendor_ticket_number = nullable_htmlentities($row['ticket_vendor_ticket_number']);
$ticket_created_at = nullable_htmlentities($row['ticket_created_at']); $ticket_created_at = nullable_htmlentities($row['ticket_created_at']);
$ticket_due_at = nullable_htmlentities($row['ticket_due_at']);
$ticket_assigned_to = intval($row['ticket_assigned_to']);
$contact_id = intval($row['ticket_contact_id']); $contact_id = intval($row['ticket_contact_id']);
$asset_id = intval($row['ticket_asset_id']); $asset_id = intval($row['ticket_asset_id']);
$location_id = intval($row['ticket_location_id']); $location_id = intval($row['ticket_location_id']);
@@ -105,7 +107,7 @@ ob_start();
<select class="form-control select2" name="category"> <select class="form-control select2" name="category">
<option value="0">- Uncategorized -</option> <option value="0">- Uncategorized -</option>
<?php <?php
$sql_categories = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Ticket' AND category_archived_at IS NULL"); $sql_categories = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Ticket' AND category_archived_at IS NULL ORDER BY category_name ASC");
while ($row = mysqli_fetch_array($sql_categories)) { while ($row = mysqli_fetch_array($sql_categories)) {
$category_id = intval($row['category_id']); $category_id = intval($row['category_id']);
$category_name = nullable_htmlentities($row['category_name']); $category_name = nullable_htmlentities($row['category_name']);
@@ -128,6 +130,49 @@ ob_start();
</div> </div>
</div> </div>
<div class="row">
<div class="col">
<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="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_type = 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 ($ticket_assigned_to === $user_id) { echo "selected"; } ?> value="<?php echo $user_id; ?>"><?php echo $user_name; ?></option>
<?php } ?>
</select>
</div>
</div>
</div>
<div class="col">
<div class="form-group">
<label>Due</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="due" value="<?php echo $ticket_due_at; ?>">
</div>
</div>
</div>
</div>
<?php if ($config_module_enable_accounting && lookupUserPermission("module_sales") >= 2) { ?> <?php if ($config_module_enable_accounting && lookupUserPermission("module_sales") >= 2) { ?>
<div class="form-group"> <div class="form-group">
<div class="custom-control custom-switch"> <div class="custom-control custom-switch">
@@ -283,7 +328,7 @@ ob_start();
<option value="0">- None -</option> <option value="0">- None -</option>
<?php <?php
$sql_vendors = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = $client_id AND vendor_template = 0 AND vendor_archived_at IS NULL ORDER BY vendor_name ASC"); $sql_vendors = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = $client_id AND vendor_archived_at IS NULL ORDER BY vendor_name ASC");
while ($row = mysqli_fetch_array($sql_vendors)) { while ($row = mysqli_fetch_array($sql_vendors)) {
$vendor_id_select = intval($row['vendor_id']); $vendor_id_select = intval($row['vendor_id']);
$vendor_name_select = nullable_htmlentities($row['vendor_name']); $vendor_name_select = nullable_htmlentities($row['vendor_name']);

View File

@@ -104,10 +104,10 @@ ob_start();
<option value="0">- None -</option> <option value="0">- None -</option>
<?php <?php
$sql_vendor_templates = mysqli_query($mysqli, "SELECT * FROM vendors WHERE vendor_template = 1 AND vendor_archived_at IS NULL ORDER BY vendor_name ASC"); $sql_vendor_templates = mysqli_query($mysqli, "SELECT * FROM vendor_templates WHERE vendor_template_archived_at IS NULL ORDER BY vendor_template_name ASC");
while ($row = mysqli_fetch_array($sql_vendor_templates)) { while ($row = mysqli_fetch_array($sql_vendor_templates)) {
$vendor_template_id_select = $row['vendor_id']; $vendor_template_id_select = $row['vendor_template_id'];
$vendor_template_name_select = nullable_htmlentities($row['vendor_name']); ?> $vendor_template_name_select = nullable_htmlentities($row['vendor_template_name']); ?>
<option <?php if ($vendor_template_id == $vendor_template_id_select) { echo "selected"; } ?> value="<?php echo $vendor_template_id_select; ?>"><?php echo $vendor_template_name_select; ?></option> <option <?php if ($vendor_template_id == $vendor_template_id_select) { echo "selected"; } ?> value="<?php echo $vendor_template_id_select; ?>"><?php echo $vendor_template_name_select; ?></option>
<?php } ?> <?php } ?>

View File

@@ -2,23 +2,22 @@
require_once '../includes/ajax_header.php'; require_once '../includes/ajax_header.php';
$vendor_id = intval($_GET['id']); $vendor_template_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM vendors WHERE vendor_id = $vendor_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM vendor_templates WHERE vendor_template_id = $vendor_template_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_array($sql);
$vendor_name = nullable_htmlentities($row['vendor_name']); $vendor_name = nullable_htmlentities($row['vendor_template_name']);
$vendor_description = nullable_htmlentities($row['vendor_description']); $vendor_description = nullable_htmlentities($row['vendor_template_description']);
$vendor_account_number = nullable_htmlentities($row['vendor_account_number']); $vendor_account_number = nullable_htmlentities($row['vendor_template_account_number']);
$vendor_contact_name = nullable_htmlentities($row['vendor_contact_name']); $vendor_contact_name = nullable_htmlentities($row['vendor_template_contact_name']);
$vendor_phone = formatPhoneNumber($row['vendor_phone']); $vendor_phone = formatPhoneNumber($row['vendor_template_phone']);
$vendor_extension = nullable_htmlentities($row['vendor_extension']); $vendor_extension = nullable_htmlentities($row['vendor_template_extension']);
$vendor_email = nullable_htmlentities($row['vendor_email']); $vendor_email = nullable_htmlentities($row['vendor_template_email']);
$vendor_website = nullable_htmlentities($row['vendor_website']); $vendor_website = nullable_htmlentities($row['vendor_template_website']);
$vendor_hours = nullable_htmlentities($row['vendor_hours']); $vendor_hours = nullable_htmlentities($row['vendor_template_hours']);
$vendor_sla = nullable_htmlentities($row['vendor_sla']); $vendor_sla = nullable_htmlentities($row['vendor_template_sla']);
$vendor_code = nullable_htmlentities($row['vendor_code']); $vendor_code = nullable_htmlentities($row['vendor_template_code']);
$vendor_notes = nullable_htmlentities($row['vendor_notes']); $vendor_notes = nullable_htmlentities($row['vendor_template_notes']);
$vendor_template = intval($row['vendor_template']);
// Generate the HTML form content using output buffering. // Generate the HTML form content using output buffering.
ob_start(); ob_start();
@@ -31,18 +30,18 @@ ob_start();
</button> </button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="vendor_id" value="<?php echo $vendor_id; ?>"> <input type="hidden" name="vendor_template_id" value="<?php echo $vendor_template_id; ?>">
<div class="modal-body bg-white"> <div class="modal-body bg-white">
<ul class="nav nav-pills nav-justified mb-3"> <ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-details<?php echo $vendor_id; ?>">Details</a> <a class="nav-link active" data-toggle="pill" href="#pills-details<?php echo $vendor_template_id; ?>">Details</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-support<?php echo $vendor_id; ?>">Support</a> <a class="nav-link" data-toggle="pill" href="#pills-support<?php echo $vendor_template_id; ?>">Support</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-notes<?php echo $vendor_id; ?>">Notes</a> <a class="nav-link" data-toggle="pill" href="#pills-notes<?php echo $vendor_template_id; ?>">Notes</a>
</li> </li>
</ul> </ul>
@@ -52,7 +51,7 @@ ob_start();
<div class="tab-content"> <div class="tab-content">
<div class="tab-pane fade show active" id="pills-details<?php echo $vendor_id; ?>"> <div class="tab-pane fade show active" id="pills-details<?php echo $vendor_template_id; ?>">
<div class="form-group"> <div class="form-group">
@@ -117,14 +116,14 @@ ob_start();
<div class="form-group"> <div class="form-group">
<div class="custom-control custom-checkbox"> <div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="updateVendorsCheckbox<?php echo $vendor_id; ?>" name="update_base_vendors" value="1" > <input type="checkbox" class="custom-control-input" id="updateVendorsCheckbox<?php echo $vendor_template_id; ?>" name="update_base_vendors" value="1" >
<label class="custom-control-label" for="updateVendorsCheckbox<?php echo $vendor_id; ?>">Update All Base Vendors</label> <label class="custom-control-label" for="updateVendorsCheckbox<?php echo $vendor_template_id; ?>">Update All Base Vendors</label>
</div> </div>
</div> </div>
</div> </div>
<div class="tab-pane fade" id="pills-support<?php echo $vendor_id; ?>"> <div class="tab-pane fade" id="pills-support<?php echo $vendor_template_id; ?>">
<label>Support Phone</label> <label>Support Phone</label>
<div class="form-row"> <div class="form-row">
@@ -225,7 +224,7 @@ ob_start();
</div> </div>
<div class="tab-pane fade" id="pills-notes<?php echo $vendor_id; ?>"> <div class="tab-pane fade" id="pills-notes<?php echo $vendor_template_id; ?>">
<div class="form-group"> <div class="form-group">
<textarea class="form-control" rows="8" placeholder="Enter some notes" name="notes"><?php echo $vendor_notes; ?></textarea> <textarea class="form-control" rows="8" placeholder="Enter some notes" name="notes"><?php echo $vendor_notes; ?></textarea>

View File

@@ -13,15 +13,12 @@ $insert_id = false;
if (!empty($name) && !(empty($content))) { if (!empty($name) && !(empty($content))) {
// Create document // Create document
$insert_sql = mysqli_query($mysqli,"INSERT INTO documents SET document_name = '$name', document_description = '$description', document_content = '$content', document_content_raw = '$content_raw', document_template = 0, document_folder_id = $folder, document_created_by = 0, document_client_id = $client_id"); $insert_sql = mysqli_query($mysqli,"INSERT INTO documents SET document_name = '$name', document_description = '$description', document_content = '$content', document_content_raw = '$content_raw', document_folder_id = $folder, document_created_by = 0, document_client_id = $client_id");
// Check insert & get insert ID // Check insert & get insert ID
if ($insert_sql) { if ($insert_sql) {
$insert_id = mysqli_insert_id($mysqli); $insert_id = mysqli_insert_id($mysqli);
// Update field document_parent to be the same id as document ID as this is the only version of the document.
mysqli_query($mysqli,"UPDATE documents SET document_parent = $insert_id WHERE document_id = $insert_id");
// Logging // Logging
logAction("Document", "Create", "$name via API ($api_key_name)", $client_id, $insert_id); logAction("Document", "Create", "$name via API ($api_key_name)", $client_id, $insert_id);
logAction("API", "Success", "Created document $name via API ($api_key_name)", $client_id); logAction("API", "Success", "Created document $name via API ($api_key_name)", $client_id);

View File

@@ -18,34 +18,12 @@ if (!empty($document_id)) {
require_once 'document_model.php'; require_once 'document_model.php';
// Documents are a little weird as we update them by *inserting* a new document row // Documents are a little weird as we update them by *inserting* a new document row
$update_insert_sql = mysqli_query($mysqli,"INSERT INTO documents SET document_name = '$name', document_description = '$description', document_content = '$content', document_content_raw = '$content_raw', document_template = 0, document_folder_id = $folder, document_created_by = 0, document_client_id = $client_id"); $update_insert_sql = mysqli_query($mysqli,"INSERT INTO documents SET document_name = '$name', document_description = '$description', document_content = '$content', document_content_raw = '$content_raw', document_folder_id = $folder, document_created_by = 0, document_client_id = $client_id");
// Check insert & get insert ID // Check insert & get insert ID
if ($update_insert_sql) { if ($update_insert_sql) {
$insert_id = $new_document_id = mysqli_insert_id($mysqli); $insert_id = $new_document_id = mysqli_insert_id($mysqli);
// Update the parent ID of the new document to match its new document ID
mysqli_query($mysqli,"UPDATE documents SET document_parent = $new_document_id WHERE document_id = $new_document_id");
// Link all existing links with old document with new document
mysqli_query($mysqli,"UPDATE documents SET document_parent = $new_document_id, document_archived_at = NOW() WHERE document_parent = $document_id");
// Update Links to the new parent document:-
// Document files
mysqli_query($mysqli,"UPDATE document_files SET document_id = $new_document_id WHERE document_id = $document_id");
// Contact documents
mysqli_query($mysqli,"UPDATE contact_documents SET document_id = $new_document_id WHERE document_id = $document_id");
// Asset documents
mysqli_query($mysqli,"UPDATE asset_documents SET document_id = $new_document_id WHERE document_id = $document_id");
// Software documents
mysqli_query($mysqli,"UPDATE software_documents SET document_id = $new_document_id WHERE document_id = $document_id");
// Vendor documents
mysqli_query($mysqli,"UPDATE vendor_documents SET document_id = $new_document_id WHERE document_id = $document_id");
// Logging // Logging
logAction("Document", "Edit", "$name via API ($api_key_name) previous version kept", $client_id, $insert_id); logAction("Document", "Edit", "$name via API ($api_key_name) previous version kept", $client_id, $insert_id);
logAction("API", "Success", "Edited document $name via API ($api_key_name)", $client_id); logAction("API", "Success", "Edited document $name via API ($api_key_name)", $client_id);

View File

@@ -34,8 +34,8 @@ if (isset($_GET['asset_id'])) {
$asset_model = nullable_htmlentities($row['asset_model']); $asset_model = nullable_htmlentities($row['asset_model']);
$asset_serial = nullable_htmlentities($row['asset_serial']); $asset_serial = nullable_htmlentities($row['asset_serial']);
$asset_os = nullable_htmlentities($row['asset_os']); $asset_os = nullable_htmlentities($row['asset_os']);
$asset_uri = nullable_htmlentities($row['asset_uri']); $asset_uri = sanitize_url($row['asset_uri']);
$asset_uri_2 = nullable_htmlentities($row['asset_uri_2']); $asset_uri_2 = sanitize_url($row['asset_uri_2']);
$asset_status = nullable_htmlentities($row['asset_status']); $asset_status = nullable_htmlentities($row['asset_status']);
$asset_purchase_reference = nullable_htmlentities($row['asset_purchase_reference']); $asset_purchase_reference = nullable_htmlentities($row['asset_purchase_reference']);
$asset_purchase_date = nullable_htmlentities($row['asset_purchase_date']); $asset_purchase_date = nullable_htmlentities($row['asset_purchase_date']);
@@ -177,7 +177,6 @@ if (isset($_GET['asset_id'])) {
LEFT JOIN users ON document_created_by = user_id LEFT JOIN users ON document_created_by = user_id
WHERE asset_documents.asset_id = $asset_id WHERE asset_documents.asset_id = $asset_id
AND asset_documents.document_id = documents.document_id AND asset_documents.document_id = documents.document_id
AND document_template = 0
AND document_archived_at IS NULL AND document_archived_at IS NULL
ORDER BY document_name ASC" ORDER BY document_name ASC"
); );
@@ -283,19 +282,19 @@ if (isset($_GET['asset_id'])) {
</div> </div>
<div class="card-body"> <div class="card-body">
<?php if ($asset_ip) { ?> <?php if ($asset_ip) { ?>
<div><i class="fa fa-fw fa-globe text-secondary mr-3"></i><?php echo $asset_ip; ?></div> <div><i class="fa fa-fw fa-globe text-secondary mr-2"></i><?php echo $asset_ip; ?></div>
<?php } ?> <?php } ?>
<?php if ($asset_nat_ip) { ?> <?php if ($asset_nat_ip) { ?>
<div class="mt-2"><i class="fa fa-fw fa-random text-secondary mr-3"></i><?php echo $asset_nat_ip; ?></div> <div class="mt-2"><i class="fa fa-fw fa-random text-secondary mr-2"></i><?php echo $asset_nat_ip; ?></div>
<?php } <?php }
if ($asset_mac) { ?> if ($asset_mac) { ?>
<div class="mt-2"><i class="fa fa-fw fa-ethernet text-secondary mr-3"></i><?php echo $asset_mac; ?></div> <div class="mt-2"><i class="fa fa-fw fa-ethernet text-secondary mr-2"></i><?php echo $asset_mac; ?></div>
<?php } <?php }
if ($asset_uri) { ?> if ($asset_uri) { ?>
<div class="mt-2"><i class="fa fa-fw fa-link text-secondary mr-3"></i><a href="<?php echo $asset_uri; ?>" target="_blank">Link</a></div> <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 } <?php }
if ($asset_uri_2) { ?> if ($asset_uri_2) { ?>
<div class="mt-2"><i class="fa fa-fw fa-link text-secondary mr-3"></i><a href="<?php echo $asset_uri_2; ?>" target="_blank">Link 2</a></div> <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 } ?>
</div> </div>
</div> </div>
@@ -307,19 +306,19 @@ if (isset($_GET['asset_id'])) {
</div> </div>
<div class="card-body"> <div class="card-body">
<?php if ($location_name) { ?> <?php if ($location_name) { ?>
<div><i class="fa fa-fw fa-map-marker-alt text-secondary mr-3"></i><?php echo $location_name_display; ?></div> <div><i class="fa fa-fw fa-map-marker-alt text-secondary mr-2"></i><?php echo $location_name_display; ?></div>
<?php } <?php }
if ($contact_name) { ?> if ($contact_name) { ?>
<div class="mt-2"><i class="fa fa-fw fa-user text-secondary mr-3"></i><?php echo $contact_name_display; ?></div> <div class="mt-2"><i class="fa fa-fw fa-user text-secondary mr-2"></i><?php echo $contact_name_display; ?></div>
<?php } <?php }
if ($contact_email) { ?> if ($contact_email) { ?>
<div class="mt-2"><i class="fa fa-fw fa-envelope text-secondary mr-3"></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> <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 } <?php }
if ($contact_phone) { ?> if ($contact_phone) { ?>
<div class="mt-2"><i class="fa fa-fw fa-phone text-secondary mr-3"></i><?php echo formatPhoneNumber($contact_phone); echo " $contact_extension"; ?></div> <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 } <?php }
if ($contact_mobile) { ?> if ($contact_mobile) { ?>
<div class="mt-2"><i class="fa fa-fw fa-mobile-alt text-secondary mr-3"></i><?php echo formatPhoneNumber($contact_mobile); ?></div> <div class="mt-2"><i class="fa fa-fw fa-mobile-alt text-secondary mr-2"></i><?php echo formatPhoneNumber($contact_mobile); ?></div>
<?php } ?> <?php } ?>
</div> </div>

View File

@@ -9,10 +9,26 @@ if (isset($_GET['client_id'])) {
require_once "includes/inc_all_client.php"; require_once "includes/inc_all_client.php";
$client_query = "AND asset_client_id = $client_id"; $client_query = "AND asset_client_id = $client_id";
$client_url = "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 { } else {
require_once "includes/inc_client_overview_all.php"; require_once "includes/inc_client_overview_all.php";
$client_query = ''; $client_query = '';
$client_url = ''; $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 // Perms
@@ -71,7 +87,7 @@ $row = mysqli_fetch_assoc(mysqli_query($mysqli, "
LEFT JOIN contacts ON asset_contact_id = contact_id LEFT JOIN contacts ON asset_contact_id = contact_id
LEFT JOIN locations ON asset_location_id = location_id LEFT JOIN locations ON asset_location_id = location_id
LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1 LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1
WHERE asset_$archive_query WHERE $archive_query
$access_permission_query $access_permission_query
$client_query $client_query
) AS filtered_assets; ) AS filtered_assets;
@@ -105,7 +121,7 @@ $sql = mysqli_query(
LEFT JOIN contacts ON asset_contact_id = contact_id LEFT JOIN contacts ON asset_contact_id = contact_id
LEFT JOIN locations ON asset_location_id = location_id LEFT JOIN locations ON asset_location_id = location_id
LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1 LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1
WHERE asset_$archive_query 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 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 (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 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) AND ($type_query)
$access_permission_query $access_permission_query
@@ -470,8 +486,8 @@ if (mysqli_num_rows($os_sql) > 0) {
$asset_ipv6 = nullable_htmlentities($row['interface_ipv6']); $asset_ipv6 = nullable_htmlentities($row['interface_ipv6']);
$asset_nat_ip = nullable_htmlentities($row['interface_nat_ip']); $asset_nat_ip = nullable_htmlentities($row['interface_nat_ip']);
$asset_mac = nullable_htmlentities($row['interface_mac']); $asset_mac = nullable_htmlentities($row['interface_mac']);
$asset_uri = nullable_htmlentities($row['asset_uri']); $asset_uri = sanitize_url($row['asset_uri']);
$asset_uri_2 = nullable_htmlentities($row['asset_uri_2']); $asset_uri_2 = sanitize_url($row['asset_uri_2']);
$asset_status = nullable_htmlentities($row['asset_status']); $asset_status = nullable_htmlentities($row['asset_status']);
$asset_purchase_reference = nullable_htmlentities($row['asset_purchase_reference']); $asset_purchase_reference = nullable_htmlentities($row['asset_purchase_reference']);
$asset_purchase_date = nullable_htmlentities($row['asset_purchase_date']); $asset_purchase_date = nullable_htmlentities($row['asset_purchase_date']);
@@ -519,7 +535,7 @@ if (mysqli_num_rows($os_sql) > 0) {
if ($contact_name) { if ($contact_name) {
$contact_name_display = "<a href='#' $contact_name_display = "<a href='#'
data-toggle='ajax-modal' data-toggle='ajax-modal'
data-modal-size='xl' data-modal-size='lg'
data-ajax-url='ajax/ajax_contact_details.php' data-ajax-url='ajax/ajax_contact_details.php'
data-ajax-id='$asset_contact_id'> data-ajax-id='$asset_contact_id'>
$contact_name $contact_archive_display $contact_name $contact_archive_display

View File

@@ -303,7 +303,7 @@ while ($row = mysqli_fetch_array($sql)) {
} }
//Vendors Added Created //Vendors Added Created
$sql = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN vendors ON client_id = vendor_client_id $client_query AND vendor_template = 0 "); $sql = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN vendors ON client_id = vendor_client_id $client_query");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_array($sql)) {
$event_id = intval($row['vendor_id']); $event_id = intval($row['vendor_id']);
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);

View File

@@ -9,10 +9,26 @@ if (isset($_GET['client_id'])) {
require_once "includes/inc_all_client.php"; require_once "includes/inc_all_client.php";
$client_query = "AND certificate_client_id = $client_id"; $client_query = "AND certificate_client_id = $client_id";
$client_url = "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 { } else {
require_once "includes/inc_client_overview_all.php"; require_once "includes/inc_client_overview_all.php";
$client_query = ''; $client_query = '';
$client_url = ''; $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 // Perms
@@ -32,7 +48,7 @@ if (!$client_url) {
$sql = mysqli_query($mysqli, "SELECT SQL_CALC_FOUND_ROWS * FROM certificates $sql = mysqli_query($mysqli, "SELECT SQL_CALC_FOUND_ROWS * FROM certificates
LEFT JOIN clients ON client_id = certificate_client_id LEFT JOIN clients ON client_id = certificate_client_id
WHERE certificate_archived_at IS NULL WHERE $archive_query
AND (certificate_name LIKE '%$q%' OR certificate_domain LIKE '%$q%' OR certificate_issued_by LIKE '%$q%' OR client_name LIKE '%$q%') AND (certificate_name LIKE '%$q%' OR certificate_domain LIKE '%$q%' OR certificate_issued_by LIKE '%$q%' OR client_name LIKE '%$q%')
$access_permission_query $access_permission_query
$client_query $client_query
@@ -65,6 +81,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php if ($client_url) { ?> <?php if ($client_url) { ?>
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>"> <input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<?php } ?> <?php } ?>
<input type="hidden" name="archived" value="<?php echo $archived; ?>">
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4">
@@ -109,6 +126,10 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<div class="col-md-6"> <div class="col-md-6">
<div class="btn-group float-right"> <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> <div class="dropdown ml-2" id="bulkActionButton" hidden>
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown"> <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>) <i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>)
@@ -182,6 +203,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$certificate_issued_by = nullable_htmlentities($row['certificate_issued_by']); $certificate_issued_by = nullable_htmlentities($row['certificate_issued_by']);
$certificate_expire = nullable_htmlentities($row['certificate_expire']); $certificate_expire = nullable_htmlentities($row['certificate_expire']);
$certificate_created_at = nullable_htmlentities($row['certificate_created_at']); $certificate_created_at = nullable_htmlentities($row['certificate_created_at']);
$certificate_archived_at = nullable_htmlentities($row['certificate_archived_at']);
$certificate_expire_ago = timeAgo($certificate_expire); $certificate_expire_ago = timeAgo($certificate_expire);
// Convert the expiry date to a timestamp // Convert the expiry date to a timestamp
@@ -250,14 +272,22 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<i class="fas fa-fw fa-edit mr-2"></i>Edit <i class="fas fa-fw fa-edit mr-2"></i>Edit
</a> </a>
<?php if ($session_user_role == 3) { ?> <?php if ($session_user_role == 3) { ?>
<?php if ($certificate_archived_at) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_certificate=<?php echo $certificate_id; ?>"> <a class="dropdown-item text-info confirm-link" href="post.php?unarchive_certificate=<?php echo $certificate_id; ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive <i class="fas fa-fw fa-redo mr-2"></i>Restore
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_certificate=<?php echo $certificate_id; ?>"> <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 <i class="fas fa-fw fa-trash mr-2"></i>Delete
</a> </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 } ?> <?php } ?>
</div> </div>
</div> </div>

View File

@@ -8,7 +8,235 @@ header("Content-Security-Policy: default-src 'self'");
require_once "includes/inc_all.php"; require_once "includes/inc_all.php";
// Billing Card Queries
//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 = $session_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 = $session_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 = $session_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 = $session_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;
// Technical Card Queries
// 8 - 45 Day Warning
// Get Domains Expiring
$sql_domains_expiring = mysqli_query(
$mysqli,
"SELECT * FROM domains
WHERE domain_client_id = $session_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 = $session_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 = $session_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 = $session_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 = $session_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 = $session_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 = $session_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 = $session_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 = $session_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 = $session_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"
);
?> ?>
<?php
// Billing Cards
if ($session_contact_primary == 1 || $session_contact_is_billing_contact) { ?>
<div class="row">
<?php if ($balance > 0) { ?>
<div class="col-sm-3 offset-1">
<div class="card">
<div class="card-header">
<h3 class="card-title text-bold">Account Balance</h3>
</div>
<div class="card-body">
<div class="h4 text-danger"><b><?php echo numfmt_format_currency($currency_format, $balance, $session_company_currency); ?></b></div>
</div>
</div>
</div>
<?php } ?>
<?php if ($recurring_monthly_total > 0) { ?>
<div class="col-sm-3">
<div class="card">
<div class="card-header">
<h3 class="card-title">Recurring Monthly</h3>
</div>
<div class="card-body">
<div class="h4"><b><?php echo numfmt_format_currency($currency_format, $recurring_monthly_total, $session_company_currency); ?></b></div>
</div>
</div>
</div>
<?php } ?>
</div>
<?php } //End Billing Cards ?>
<?php
// Technical Cards
if ($session_contact_primary == 1 || $session_contact_is_technical_contact) {
?>
<div class="row">
<?php if (mysqli_num_rows($sql_domains_expiring) > 0) { ?>
<div class="col-sm-3 offset-1">
<div class="card">
<div class="card-header">
<h3 class="card-title text-bold">Domains Expiring</h3>
</div>
<div class="card-body">
<?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>
Domain: <?php echo $domain_name; ?>
<span>-- <?php echo $domain_expire; ?> (<?php echo $domain_expire_human; ?>)</span>
</p>
<?php
}
?>
</div>
</div>
</div>
<?php } ?>
</div>
<?php } ?>
<div class="col-md-2 offset-1"> <div class="col-md-2 offset-1">
<a href="ticket_add.php" class="btn btn-primary btn-block">New ticket</a> <a href="ticket_add.php" class="btn btn-primary btn-block">New ticket</a>
</div> </div>

View File

@@ -35,7 +35,6 @@ $document_created_at = nullable_htmlentities($row['document_created_at']);
$document_updated_at = nullable_htmlentities($row['document_updated_at']); $document_updated_at = nullable_htmlentities($row['document_updated_at']);
$document_archived_at = nullable_htmlentities($row['document_archived_at']); $document_archived_at = nullable_htmlentities($row['document_archived_at']);
$document_folder_id = intval($row['document_folder_id']); $document_folder_id = intval($row['document_folder_id']);
$document_parent = intval($row['document_parent']);
$document_client_visible = intval($row['document_client_visible']); $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 // Override Tab Title // No Sanitizing needed as this var will opnly be used in the tab title
@@ -115,45 +114,44 @@ $page_title = $row['document_name'];
<table class="table table-sm"> <table class="table table-sm">
<thead class="thead-light"> <thead class="thead-light">
<th>Revision</th> <th>Version</th>
<th>Date</th> <th>Date</th>
<th>Name</th>
<th>Description</th> <th>Description</th>
<th>Author</th> <th>Author</th>
</thead> </thead>
<tbody> <tbody>
<?php <?php
$sql_document_revisions = mysqli_query($mysqli, "SELECT * FROM documents $sql_document_versions = mysqli_query($mysqli, "SELECT * FROM document_versions
LEFT JOIN users ON document_updated_by = user_id LEFT JOIN users ON document_version_created_by = user_id
WHERE document_parent = $document_parent WHERE document_version_document_id = $document_id
ORDER BY document_created_at ASC" ORDER BY document_version_created_at ASC"
); );
$revision_count = 1; // Initialize the revision counter $document_version_count = 1; // Initialize the document version counter
while ($row = mysqli_fetch_array($sql_document_revisions)) { while ($row = mysqli_fetch_array($sql_document_versions)) {
$revision_document_id = intval($row['document_id']); $document_version_id = intval($row['document_version_id']);
$revision_document_name = nullable_htmlentities($row['document_name']); $document_version_name = nullable_htmlentities($row['document_version_name']);
$revision_document_description = nullable_htmlentities($row['document_description']); $document_version_description = nullable_htmlentities($row['document_version_description']);
if ($revision_document_description ) { if ($document_version_description ) {
$revision_document_description_display = $revision_document_description; $document_version_description_display = $document_version_description;
} else { } else {
$revision_document_description_display = "-"; $document_version_description_display = "-";
} }
$revision_document_author = nullable_htmlentities($row['user_name']); $document_version_author = nullable_htmlentities($row['user_name']);
if (empty($revision_document_author)) { $document_version_created_date = date('Y-m-d', strtotime($row['document_version_created_at']));
$revision_document_author = $document_created_by_name;
}
$revision_document_created_date = date('Y-m-d', strtotime($row['document_created_at']));
?> ?>
<tr> <tr>
<td><?php echo "$revision_count.0"; ?></td> <td><?php echo $document_version_count; ?></td>
<td><?php echo $revision_document_created_date; ?></td> <td><?php echo $document_version_created_date; ?></td>
<td><?php echo $revision_document_description_display; ?></td> <td><?php echo $document_version_name; ?></td>
<td><?php echo $revision_document_author; ?></td> <td><?php echo $document_version_description_display; ?></td>
<td><?php echo $document_version_author; ?></td>
</tr> </tr>
<?php <?php
$revision_count++; // Increment the counter $document_version_count++; // Increment the counter
} }
?> ?>
</tbody> </tbody>
@@ -378,29 +376,30 @@ $page_title = $row['document_name'];
<h6><i class="fas fa-history mr-2"></i>Revisions</h6> <h6><i class="fas fa-history mr-2"></i>Revisions</h6>
<?php <?php
$sql_document_revisions = mysqli_query($mysqli, "SELECT * FROM documents $sql_document_versions = mysqli_query($mysqli, "SELECT * FROM document_versions
LEFT JOIN users ON document_created_by = user_id LEFT JOIN users ON document_version_created_by = user_id
WHERE document_parent = $document_parent WHERE document_version_document_id = $document_id
ORDER BY document_created_at DESC" ORDER BY document_version_created_at DESC"
); );
while ($row = mysqli_fetch_array($sql_document_revisions)) { while ($row = mysqli_fetch_array($sql_document_versions)) {
$revision_document_id = intval($row['document_id']); $document_version_id = intval($row['document_version_id']);
$revision_document_name = nullable_htmlentities($row['document_name']); $document_version_name = nullable_htmlentities($row['document_version_name']);
$revision_document_description = nullable_htmlentities($row['document_description']); $document_version_description = nullable_htmlentities($row['document_version_description']);
$revision_document_created_by_name = nullable_htmlentities($row['user_name']); $document_version_author = nullable_htmlentities($row['user_name']);
$revision_document_created_date = nullable_htmlentities($row['document_created_at']); $document_version_created_date = nullable_htmlentities($row['document_version_created_at']);
?> ?>
<div class="mt-1 <?php if($document_id == $revision_document_id){ echo "text-bold"; } ?>"> <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 href="?client_id=<?php echo $client_id; ?>&document_id=<?php echo $revision_document_id; ?>"><?php echo " $revision_document_created_date"; ?></a><?php if($document_parent == $revision_document_id){ echo "<span class='float-right'>(Parent)</span>"; <i class="fas fa-fw fa-history text-secondary mr-2"></i>
} else { ?> <a href="#"
<a class="confirm-link float-right" href="post.php?delete_document_version=<?php echo $revision_document_id; ?>"> data-toggle="ajax-modal"
<i class="fas fa-fw fa-trash-alt text-secondary"></i> data-modal-size="lg"
</a> data-ajax-url="ajax/ajax_document_version_view.php"
<?php data-ajax-id="<?php echo $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> </div>
<?php <?php
} }

View File

@@ -41,8 +41,6 @@ if ($get_folder_id == 0 && $_GET["q"]) {
"SELECT SQL_CALC_FOUND_ROWS * FROM documents "SELECT SQL_CALC_FOUND_ROWS * FROM documents
LEFT JOIN users ON document_created_by = user_id LEFT JOIN users ON document_created_by = user_id
WHERE document_client_id = $client_id WHERE document_client_id = $client_id
AND document_template = 0
AND document_archived_at IS NULL AND document_archived_at IS NULL
$query_snippet $query_snippet
ORDER BY $sort $order LIMIT $record_from, $record_to" ORDER BY $sort $order LIMIT $record_from, $record_to"
@@ -53,7 +51,6 @@ if ($get_folder_id == 0 && $_GET["q"]) {
"SELECT SQL_CALC_FOUND_ROWS * FROM documents "SELECT SQL_CALC_FOUND_ROWS * FROM documents
LEFT JOIN users ON document_created_by = user_id LEFT JOIN users ON document_created_by = user_id
WHERE document_client_id = $client_id WHERE document_client_id = $client_id
AND document_template = 0
AND document_folder_id = $folder AND document_folder_id = $folder
AND document_archived_at IS NULL AND document_archived_at IS NULL
$query_snippet $query_snippet
@@ -353,7 +350,11 @@ while ($folder_id > 0) {
$document_content = nullable_htmlentities($row['document_content']); $document_content = nullable_htmlentities($row['document_content']);
$document_created_by_name = nullable_htmlentities($row['user_name']); $document_created_by_name = nullable_htmlentities($row['user_name']);
$document_created_at = date("m/d/Y",strtotime($row['document_created_at'])); $document_created_at = date("m/d/Y",strtotime($row['document_created_at']));
$document_updated_at = date("m/d/Y",strtotime($row['document_updated_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']); $document_folder_id = intval($row['document_folder_id']);
// Check if shared // Check if shared
@@ -398,7 +399,7 @@ while ($folder_id > 0) {
<?php echo $document_created_at; ?> <?php echo $document_created_at; ?>
<div class="text-secondary mt-1"><?php echo $document_created_by_name; ?> <div class="text-secondary mt-1"><?php echo $document_created_by_name; ?>
</td> </td>
<td><?php echo $document_updated_at; ?></td> <td><?php echo $document_updated_at_display; ?></td>
<td> <td>
<?php if (mysqli_num_rows($sql_shared) > 0) { ?> <?php if (mysqli_num_rows($sql_shared) > 0) { ?>
<div class="media" title="Expires <?php echo $item_expire_at_human; ?>"> <div class="media" title="Expires <?php echo $item_expire_at_human; ?>">

View File

@@ -193,7 +193,7 @@ $sql_asset_retired = mysqli_query(
<!-- Notes --> <!-- Notes -->
<div class="col-md-4"> <div class="col-md-8">
<div class="card card-dark mb-3"> <div class="card card-dark mb-3">
<div class="card-header"> <div class="card-header">
@@ -226,19 +226,42 @@ $sql_asset_retired = mysqli_query(
$contact_extension = nullable_htmlentities($row['contact_extension']); $contact_extension = nullable_htmlentities($row['contact_extension']);
$contact_mobile_country_code = nullable_htmlentities($row['contact_mobile_country_code']); $contact_mobile_country_code = nullable_htmlentities($row['contact_mobile_country_code']);
$contact_mobile = nullable_htmlentities(formatPhoneNumber($row['contact_mobile'], $contact_mobile_country_code)); $contact_mobile = nullable_htmlentities(formatPhoneNumber($row['contact_mobile'], $contact_mobile_country_code));
$contact_photo = nullable_htmlentities($row['contact_photo']);
$contact_initials = initials($contact_name);
?> ?>
<tr> <tr>
<td> <td>
<a href="#" class="text-bold" <a href="#" data-toggle="ajax-modal"
data-toggle="ajax-modal"
data-modal-size="lg" data-modal-size="lg"
data-ajax-url="ajax/ajax_contact_details.php" data-ajax-url="ajax/ajax_contact_details.php"
data-ajax-id="<?php echo $contact_id; ?>"> data-ajax-id="<?php echo $contact_id; ?>">
<?php echo $contact_name; ?> <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> </a>
<br>
<small class="text-secondary"><?php echo $contact_title; ?></small>
</td> </td>
<td> <td>
<?php if (!empty($contact_phone)) { ?> <?php if (!empty($contact_phone)) { ?>
@@ -613,7 +636,7 @@ $sql_asset_retired = mysqli_query(
<!-- Recent Activities --> <!-- Recent Activities -->
<div class="col-md-4"> <div class="col-md-6">
<div class="card card-dark mb-3"> <div class="card card-dark mb-3">
<div class="card-header"> <div class="card-header">
@@ -631,7 +654,7 @@ $sql_asset_retired = mysqli_query(
?> ?>
<tr> <tr>
<td><?php echo $log_created_at_time_ago; ?></td> <td class="text-nowrap text-secondary"><?php echo $log_created_at_time_ago; ?></td>
<td><?php echo $log_description; ?></td> <td><?php echo $log_description; ?></td>
</tr> </tr>

View File

@@ -339,7 +339,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$client_tags_display = implode('', $client_tag_name_display_array); $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 //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 NOT LIKE 'Draft' AND invoice_status NOT LIKE 'Cancelled' "); $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); $row = mysqli_fetch_array($sql_invoice_amounts);
$invoice_amounts = floatval($row['invoice_amounts']); $invoice_amounts = floatval($row['invoice_amounts']);
@@ -404,13 +404,11 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
if (!empty($contact_name)) { ?> if (!empty($contact_name)) { ?>
<div class="text-bold"> <div class="text-bold">
<i class="fa fa-fw fa-user text-secondary mr-2 mb-2"></i> <i class="fa fa-fw fa-user text-secondary mr-2 mb-2"></i><a href="#"
<a href="#"
data-toggle="ajax-modal" data-toggle="ajax-modal"
data-modal-size="lg" data-modal-size="lg"
data-ajax-url="ajax/ajax_contact_details.php?client_id=<?php echo $client_id; ?>" data-ajax-url="ajax/ajax_contact_details.php?client_id=<?php echo $client_id; ?>"
data-ajax-id="<?php echo $contact_id; ?>"> data-ajax-id="<?php echo $contact_id; ?>"><?php echo $contact_name; ?>
<?php echo $contact_name; ?>
</a> </a>
</div> </div>
<?php } else { <?php } else {

View File

@@ -143,7 +143,6 @@ if (isset($_GET['contact_id'])) {
LEFT JOIN users ON document_created_by = user_id LEFT JOIN users ON document_created_by = user_id
WHERE contact_documents.contact_id = $contact_id WHERE contact_documents.contact_id = $contact_id
AND contact_documents.document_id = documents.document_id AND contact_documents.document_id = documents.document_id
AND document_template = 0
AND document_archived_at IS NULL AND document_archived_at IS NULL
ORDER BY document_name ASC" ORDER BY document_name ASC"
); );

View File

@@ -9,10 +9,26 @@ if (isset($_GET['client_id'])) {
require_once "includes/inc_all_client.php"; require_once "includes/inc_all_client.php";
$client_query = "AND contact_client_id = $client_id"; $client_query = "AND contact_client_id = $client_id";
$client_url = "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 { } else {
require_once "includes/inc_client_overview_all.php"; require_once "includes/inc_client_overview_all.php";
$client_query = ''; $client_query = '';
$client_url = ''; $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 // Tags Filter
@@ -55,7 +71,7 @@ $sql = mysqli_query($mysqli, "SELECT SQL_CALC_FOUND_ROWS contacts.*, clients.*,
LEFT JOIN users ON user_id = contact_user_id LEFT JOIN users ON user_id = contact_user_id
LEFT JOIN contact_tags ON contact_tags.contact_id = contacts.contact_id LEFT JOIN contact_tags ON contact_tags.contact_id = contacts.contact_id
LEFT JOIN tags ON tags.tag_id = contact_tags.tag_id LEFT JOIN tags ON tags.tag_id = contact_tags.tag_id
WHERE contact_$archive_query WHERE $archive_query
$tag_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%') 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 $access_permission_query

View File

@@ -9,12 +9,30 @@ if (isset($_GET['client_id'])) {
require_once "includes/inc_all_client.php"; require_once "includes/inc_all_client.php";
$client_query = "AND credential_client_id = $client_id"; $client_query = "AND credential_client_id = $client_id";
$client_url = "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 = "c.credential_archived_at IS NOT NULL";
} else {
$archived = 0;
$archive_query = "c.credential_archived_at IS NULL";
}
// Log when users load the Credentials page // Log when users load the Credentials page
logAction("Credential", "View", "$session_name viewed the Credentials page for client", $client_id); logAction("Credential", "View", "$session_name viewed the Credentials page for client", $client_id);
} else { } else {
require_once "includes/inc_client_overview_all.php"; require_once "includes/inc_client_overview_all.php";
$client_query = ''; $client_query = '';
$client_url = ''; $client_url = '';
// Overide Filter Header Archived
if (isset($_GET['archived']) && $_GET['archived'] == 1) {
$archived = 1;
$archive_query = "(client_archived_at IS NOT NULL OR c.credential_archived_at IS NOT NULL)";
} else {
$archived = 0;
$archive_query = "(client_archived_at IS NULL AND c.credential_archived_at IS NULL)";
}
// Log when users load the Credentials page // Log when users load the Credentials page
logAction("Credential", "View", "$session_name viewed the All Credentials page"); logAction("Credential", "View", "$session_name viewed the All Credentials page");
} }
@@ -68,7 +86,7 @@ $sql = mysqli_query(
LEFT JOIN contacts ON contact_id = credential_contact_id LEFT JOIN contacts ON contact_id = credential_contact_id
LEFT JOIN assets ON asset_id = credential_asset_id LEFT JOIN assets ON asset_id = credential_asset_id
$location_query_innerjoin $location_query_innerjoin
WHERE c.credential_$archive_query WHERE $archive_query
$tag_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%') 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 $location_query
@@ -282,13 +300,13 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$credential_id = intval($row['c_credential_id']); $credential_id = intval($row['c_credential_id']);
$credential_name = nullable_htmlentities($row['credential_name']); $credential_name = nullable_htmlentities($row['credential_name']);
$credential_description = nullable_htmlentities($row['credential_description']); $credential_description = nullable_htmlentities($row['credential_description']);
$credential_uri = nullable_htmlentities($row['credential_uri']); $credential_uri = sanitize_url($row['credential_uri']);
if (empty($credential_uri)) { if (empty($credential_uri)) {
$credential_uri_display = "-"; $credential_uri_display = "-";
} else { } else {
$credential_uri_display = truncate($credential_uri,40) . "<button class='btn btn-sm clipboardjs' type='button' data-clipboard-text='$credential_uri'><i class='far fa-copy text-secondary'></i></button>"; $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 = nullable_htmlentities($row['credential_uri_2']); $credential_uri_2 = sanitize_url($row['credential_uri_2']);
$credential_username = nullable_htmlentities(decryptCredentialEntry($row['credential_username'])); $credential_username = nullable_htmlentities(decryptCredentialEntry($row['credential_username']));
if (empty($credential_username)) { if (empty($credential_username)) {
$credential_username_display = "-"; $credential_username_display = "-";

View File

@@ -91,7 +91,7 @@ if ($user_config_dashboard_financial_enable == 1) {
$row = mysqli_fetch_array($sql_total_expenses); $row = mysqli_fetch_array($sql_total_expenses);
$total_expenses = floatval($row['total_expenses']); $total_expenses = floatval($row['total_expenses']);
$sql_invoice_totals = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS invoice_totals FROM invoices WHERE invoice_status NOT LIKE 'Draft' AND invoice_status NOT LIKE 'Cancelled' AND YEAR(invoice_date) = $year"); $sql_invoice_totals = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS invoice_totals FROM invoices WHERE invoice_status != 'Draft' AND invoice_status != 'Cancelled' AND invoice_status != 'Non-Billable' AND YEAR(invoice_date) = $year");
$row = mysqli_fetch_array($sql_invoice_totals); $row = mysqli_fetch_array($sql_invoice_totals);
$invoice_totals = floatval($row['invoice_totals']); $invoice_totals = floatval($row['invoice_totals']);
@@ -99,7 +99,7 @@ if ($user_config_dashboard_financial_enable == 1) {
$row = mysqli_fetch_array($sql_total_payments_to_invoices_all_years); $row = mysqli_fetch_array($sql_total_payments_to_invoices_all_years);
$total_payments_to_invoices_all_years = floatval($row['total_payments_to_invoices_all_years']); $total_payments_to_invoices_all_years = floatval($row['total_payments_to_invoices_all_years']);
$sql_invoice_totals_all_years = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS invoice_totals_all_years FROM invoices WHERE invoice_status NOT LIKE 'Draft' AND invoice_status NOT LIKE 'Cancelled'"); $sql_invoice_totals_all_years = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS invoice_totals_all_years FROM invoices WHERE invoice_status != 'Draft' AND invoice_status != 'Cancelled' AND invoice_status != 'Non-Billable'");
$row = mysqli_fetch_array($sql_invoice_totals_all_years); $row = mysqli_fetch_array($sql_invoice_totals_all_years);
$invoice_totals_all_years = floatval($row['invoice_totals_all_years']); $invoice_totals_all_years = floatval($row['invoice_totals_all_years']);
@@ -158,7 +158,7 @@ if ($user_config_dashboard_financial_enable == 1) {
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT(client_id) AS clients_added FROM clients WHERE YEAR(client_created_at) = $year AND client_archived_at IS NULL")); $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT(client_id) AS clients_added FROM clients WHERE YEAR(client_created_at) = $year AND client_archived_at IS NULL"));
$clients_added = intval($row['clients_added']); $clients_added = intval($row['clients_added']);
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT(vendor_id) AS vendors_added FROM vendors WHERE YEAR(vendor_created_at) = $year AND vendor_client_id = 0 AND vendor_template = 0 AND vendor_archived_at IS NULL")); $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT(vendor_id) AS vendors_added FROM vendors WHERE YEAR(vendor_created_at) = $year AND vendor_client_id = 0 AND vendor_archived_at IS NULL"));
$vendors_added = intval($row['vendors_added']); $vendors_added = intval($row['vendors_added']);
?> ?>
<div class="card card-body"> <div class="card card-body">
@@ -808,7 +808,7 @@ if ($user_config_dashboard_technical_enable == 1) {
<?php <?php
$largest_invoice_month = 0; $largest_invoice_month = 0;
for ($month = 1; $month <= 12; $month++) { for ($month = 1; $month <= 12; $month++) {
$sql_projected = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS invoice_amount_for_month FROM invoices WHERE YEAR(invoice_due) = $year AND MONTH(invoice_due) = $month AND invoice_status NOT LIKE 'Cancelled' AND invoice_status NOT LIKE 'Draft'"); $sql_projected = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS invoice_amount_for_month FROM invoices WHERE YEAR(invoice_due) = $year AND MONTH(invoice_due) = $month AND invoice_status != 'Cancelled' AND invoice_status != 'Draft' AND invoice_status != 'Non-Billable'");
$row = mysqli_fetch_array($sql_projected); $row = mysqli_fetch_array($sql_projected);
$invoice_for_month = floatval($row['invoice_amount_for_month']); $invoice_for_month = floatval($row['invoice_amount_for_month']);

View File

@@ -3464,12 +3464,216 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.1.4'"); mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.1.4'");
} }
if (CURRENT_DATABASE_VERSION == '2.1.4') {
mysqli_query($mysqli, "ALTER TABLE `settings` ADD `config_ticket_timer_autostart` TINYINT(1) NOT NULL DEFAULT '0' AFTER `config_ticket_default_billable`");
mysqli_query($mysqli, "ALTER TABLE `tickets` ADD `ticket_due_at` DATETIME DEFAULT NULL AFTER `ticket_updated_at`");
mysqli_query($mysqli, "ALTER TABLE `companies` ADD `company_tax_id` VARCHAR(200) DEFAULT NULL AFTER `company_currency`");
mysqli_query($mysqli, "ALTER TABLE `settings` ADD `config_invoice_show_tax_id` TINYINT(1) NOT NULL DEFAULT '0' AFTER `config_invoice_paid_notification_email`");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.1.5'");
}
// if (CURRENT_DATABASE_VERSION == '2.1.4') { if (CURRENT_DATABASE_VERSION == '2.1.5') {
// // Insert queries here required to update to DB version 2.1.5
mysqli_query($mysqli, "CREATE TABLE `document_versions` (
`document_version_id` INT(11) NOT NULL AUTO_INCREMENT,
`document_version_name` VARCHAR(200) NOT NULL,
`document_version_description` TEXT DEFAULT NULL,
`document_version_content` LONGTEXT NOT NULL,
`document_version_created_by` INT(11) DEFAULT 0,
`document_version_created_at` DATETIME NOT NULL,
`document_version_document_id` INT(11) NOT NULL,
PRIMARY KEY (`document_version_id`)
)");
// Delete all Current Document Versions
mysqli_query($mysqli, "
DELETE FROM `documents`
WHERE `document_parent` > 0 AND `document_parent` != `document_id`
");
mysqli_query($mysqli, "ALTER TABLE `documents` DROP `document_parent`");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.1.6'");
}
if (CURRENT_DATABASE_VERSION == '2.1.6') {
mysqli_query($mysqli, "CREATE TABLE `document_templates` (
`document_template_id` INT(11) NOT NULL AUTO_INCREMENT,
`document_template_name` VARCHAR(200) NOT NULL,
`document_template_description` TEXT DEFAULT NULL,
`document_template_content` LONGTEXT NOT NULL,
`document_template_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`document_template_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
`document_template_archived_at` DATETIME NULL DEFAULT NULL,
`document_template_created_by` INT(11) NOT NULL DEFAULT 0,
`document_template_updated_by` INT(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`document_template_id`)
)");
// Copy Document Templates over to new document templates table
mysqli_query($mysqli, "
INSERT INTO document_templates (
document_template_name,
document_template_description,
document_template_content,
document_template_created_at,
document_template_updated_at,
document_template_archived_at,
document_template_created_by,
document_template_updated_by
)
SELECT
document_name,
document_description,
document_content,
document_created_at,
document_updated_at,
document_archived_at,
document_created_by,
document_updated_by
FROM
documents
WHERE
document_template = 1
");
mysqli_query($mysqli, "DELETE FROM documents WHERE document_template = 1");
mysqli_query($mysqli, "ALTER TABLE `documents` DROP `document_template`");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.1.7'");
}
if (CURRENT_DATABASE_VERSION == '2.1.7') {
mysqli_query($mysqli, "CREATE TABLE `software_templates` (
`software_template_id` INT(11) NOT NULL AUTO_INCREMENT,
`software_template_name` VARCHAR(200) NOT NULL,
`software_template_description` TEXT DEFAULT NULL,
`software_template_version` VARCHAR(200) DEFAULT NULL,
`software_template_type` VARCHAR(200) NOT NULL,
`software_template_license_type` VARCHAR(200) DEFAULT NULL,
`software_template_notes` TEXT DEFAULT NULL,
`software_template_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`software_template_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
`software_template_archived_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`software_template_id`)
)");
// Copy software Templates over to new software templates table
mysqli_query($mysqli, "
INSERT INTO software_templates (
software_template_name,
software_template_description,
software_template_version,
software_template_type,
software_template_license_type,
software_template_notes,
software_template_created_at,
software_template_updated_at,
software_template_archived_at
)
SELECT
software_name,
software_description,
software_version,
software_type,
software_license_type,
software_notes,
software_created_at,
software_updated_at,
software_archived_at
FROM
software
WHERE
software_template = 1
");
mysqli_query($mysqli, "DELETE FROM software WHERE software_template = 1");
mysqli_query($mysqli, "ALTER TABLE `software` DROP `software_template`");
mysqli_query($mysqli, "ALTER TABLE `software` DROP `software_template_id`");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.1.8'");
}
if (CURRENT_DATABASE_VERSION == '2.1.8') {
mysqli_query($mysqli, "CREATE TABLE `vendor_templates` (
`vendor_template_id` INT(11) NOT NULL AUTO_INCREMENT,
`vendor_template_name` VARCHAR(200) NOT NULL,
`vendor_template_description` VARCHAR(200) DEFAULT NULL,
`vendor_template_contact_name` VARCHAR(200) DEFAULT NULL,
`vendor_template_phone_country_code` VARCHAR(10) DEFAULT NULL,
`vendor_template_phone` VARCHAR(200) DEFAULT NULL,
`vendor_template_extension` VARCHAR(200) DEFAULT NULL,
`vendor_template_email` VARCHAR(200) DEFAULT NULL,
`vendor_template_website` VARCHAR(200) DEFAULT NULL,
`vendor_template_hours` VARCHAR(200) DEFAULT NULL,
`vendor_template_sla` VARCHAR(200) DEFAULT NULL,
`vendor_template_code` VARCHAR(200) DEFAULT NULL,
`vendor_template_account_number` VARCHAR(200) DEFAULT NULL,
`vendor_template_notes` TEXT DEFAULT NULL,
`vendor_template_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`vendor_template_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
`vendor_template_archived_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`vendor_template_id`)
)");
// Copy Vendor Templates over to new vendor templates table
mysqli_query($mysqli, "
INSERT INTO vendor_templates (
vendor_template_name,
vendor_template_description,
vendor_template_contact_name,
vendor_template_phone_country_code,
vendor_template_phone,
vendor_template_extension,
vendor_template_email,
vendor_template_website,
vendor_template_hours,
vendor_template_sla,
vendor_template_code,
vendor_template_account_number,
vendor_template_notes,
vendor_template_created_at,
vendor_template_updated_at,
vendor_template_archived_at
)
SELECT
vendor_name,
vendor_description,
vendor_contact_name,
vendor_phone_country_code,
vendor_phone,
vendor_extension,
vendor_email,
vendor_website,
vendor_hours,
vendor_sla,
vendor_code,
vendor_account_number,
vendor_notes,
vendor_created_at,
vendor_updated_at,
vendor_archived_at
FROM
vendors
WHERE
vendor_template = 1
");
mysqli_query($mysqli, "DELETE FROM vendors WHERE vendor_template = 1");
mysqli_query($mysqli, "ALTER TABLE `vendors` DROP `vendor_template`");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.1.9'");
}
// if (CURRENT_DATABASE_VERSION == '2.1.9') {
// // Insert queries here required to update to DB version 2.2.0
// // Then, update the database to the next sequential version // // Then, update the database to the next sequential version
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.1.5'"); // mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.2.0'");
// } // }
} else { } else {

102
db.sql
View File

@@ -555,6 +555,7 @@ CREATE TABLE `companies` (
`company_logo` varchar(250) DEFAULT NULL, `company_logo` varchar(250) DEFAULT NULL,
`company_locale` varchar(200) DEFAULT NULL, `company_locale` varchar(200) DEFAULT NULL,
`company_currency` varchar(200) NOT NULL, `company_currency` varchar(200) NOT NULL,
`company_tax_id` varchar(200) DEFAULT NULL,
`company_created_at` datetime NOT NULL DEFAULT current_timestamp(), `company_created_at` datetime NOT NULL DEFAULT current_timestamp(),
`company_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(), `company_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
PRIMARY KEY (`company_id`) PRIMARY KEY (`company_id`)
@@ -829,6 +830,46 @@ CREATE TABLE `document_files` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `document_templates`
--
DROP TABLE IF EXISTS `document_templates`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `document_templates` (
`document_template_id` int(11) NOT NULL AUTO_INCREMENT,
`document_template_name` varchar(200) NOT NULL,
`document_template_description` text DEFAULT NULL,
`document_template_content` longtext NOT NULL,
`document_template_created_at` datetime NOT NULL DEFAULT current_timestamp(),
`document_template_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
`document_template_archived_at` datetime DEFAULT NULL,
`document_template_created_by` int(11) NOT NULL DEFAULT 0,
`document_template_updated_by` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`document_template_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `document_versions`
--
DROP TABLE IF EXISTS `document_versions`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `document_versions` (
`document_version_id` int(11) NOT NULL AUTO_INCREMENT,
`document_version_name` varchar(200) NOT NULL,
`document_version_description` text DEFAULT NULL,
`document_version_content` longtext NOT NULL,
`document_version_created_by` int(11) DEFAULT 0,
`document_version_created_at` datetime NOT NULL,
`document_version_document_id` int(11) NOT NULL,
PRIMARY KEY (`document_version_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
-- --
-- Table structure for table `documents` -- Table structure for table `documents`
-- --
@@ -843,13 +884,11 @@ CREATE TABLE `documents` (
`document_content` longtext NOT NULL, `document_content` longtext NOT NULL,
`document_content_raw` longtext NOT NULL, `document_content_raw` longtext NOT NULL,
`document_important` tinyint(1) NOT NULL DEFAULT 0, `document_important` tinyint(1) NOT NULL DEFAULT 0,
`document_parent` int(11) NOT NULL DEFAULT 0,
`document_client_visible` int(11) NOT NULL DEFAULT 1, `document_client_visible` int(11) NOT NULL DEFAULT 1,
`document_created_at` datetime NOT NULL DEFAULT current_timestamp(), `document_created_at` datetime NOT NULL DEFAULT current_timestamp(),
`document_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(), `document_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
`document_archived_at` datetime DEFAULT NULL, `document_archived_at` datetime DEFAULT NULL,
`document_accessed_at` datetime DEFAULT NULL, `document_accessed_at` datetime DEFAULT NULL,
`document_template` tinyint(1) NOT NULL DEFAULT 0,
`document_folder_id` int(11) NOT NULL DEFAULT 0, `document_folder_id` int(11) NOT NULL DEFAULT 0,
`document_created_by` int(11) NOT NULL DEFAULT 0, `document_created_by` int(11) NOT NULL DEFAULT 0,
`document_updated_by` int(11) NOT NULL DEFAULT 0, `document_updated_by` int(11) NOT NULL DEFAULT 0,
@@ -1794,6 +1833,7 @@ CREATE TABLE `settings` (
`config_invoice_late_fee_enable` tinyint(1) NOT NULL DEFAULT 0, `config_invoice_late_fee_enable` tinyint(1) NOT NULL DEFAULT 0,
`config_invoice_late_fee_percent` decimal(5,2) NOT NULL DEFAULT 0.00, `config_invoice_late_fee_percent` decimal(5,2) NOT NULL DEFAULT 0.00,
`config_invoice_paid_notification_email` varchar(200) DEFAULT NULL, `config_invoice_paid_notification_email` varchar(200) DEFAULT NULL,
`config_invoice_show_tax_id` tinyint(1) NOT NULL DEFAULT 0,
`config_recurring_invoice_prefix` varchar(200) DEFAULT NULL, `config_recurring_invoice_prefix` varchar(200) DEFAULT NULL,
`config_recurring_invoice_next_number` int(11) NOT NULL DEFAULT 1, `config_recurring_invoice_next_number` int(11) NOT NULL DEFAULT 1,
`config_quote_prefix` varchar(200) DEFAULT NULL, `config_quote_prefix` varchar(200) DEFAULT NULL,
@@ -1812,6 +1852,7 @@ CREATE TABLE `settings` (
`config_ticket_autoclose_hours` int(5) NOT NULL DEFAULT 72, `config_ticket_autoclose_hours` int(5) NOT NULL DEFAULT 72,
`config_ticket_new_ticket_notification_email` varchar(200) DEFAULT NULL, `config_ticket_new_ticket_notification_email` varchar(200) DEFAULT NULL,
`config_ticket_default_billable` tinyint(1) NOT NULL DEFAULT 0, `config_ticket_default_billable` tinyint(1) NOT NULL DEFAULT 0,
`config_ticket_timer_autostart` tinyint(1) NOT NULL DEFAULT 0,
`config_enable_cron` tinyint(1) NOT NULL DEFAULT 0, `config_enable_cron` tinyint(1) NOT NULL DEFAULT 0,
`config_recurring_auto_send_invoice` tinyint(1) NOT NULL DEFAULT 1, `config_recurring_auto_send_invoice` tinyint(1) NOT NULL DEFAULT 1,
`config_enable_alert_domain_expire` tinyint(1) NOT NULL DEFAULT 1, `config_enable_alert_domain_expire` tinyint(1) NOT NULL DEFAULT 1,
@@ -1900,14 +1941,12 @@ CREATE TABLE `software` (
`software_purchase` date DEFAULT NULL, `software_purchase` date DEFAULT NULL,
`software_expire` date DEFAULT NULL, `software_expire` date DEFAULT NULL,
`software_notes` text DEFAULT NULL, `software_notes` text DEFAULT NULL,
`software_template` tinyint(1) NOT NULL DEFAULT 0,
`software_created_at` datetime NOT NULL DEFAULT current_timestamp(), `software_created_at` datetime NOT NULL DEFAULT current_timestamp(),
`software_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(), `software_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
`software_archived_at` datetime DEFAULT NULL, `software_archived_at` datetime DEFAULT NULL,
`software_accessed_at` datetime DEFAULT NULL, `software_accessed_at` datetime DEFAULT NULL,
`software_vendor_id` int(11) DEFAULT 0, `software_vendor_id` int(11) DEFAULT 0,
`software_client_id` int(11) NOT NULL, `software_client_id` int(11) NOT NULL,
`software_template_id` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`software_id`) PRIMARY KEY (`software_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET character_set_client = @saved_cs_client */;
@@ -1997,6 +2036,28 @@ CREATE TABLE `software_files` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `software_templates`
--
DROP TABLE IF EXISTS `software_templates`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `software_templates` (
`software_template_id` int(11) NOT NULL AUTO_INCREMENT,
`software_template_name` varchar(200) NOT NULL,
`software_template_description` text DEFAULT NULL,
`software_template_version` varchar(200) DEFAULT NULL,
`software_template_type` varchar(200) NOT NULL,
`software_template_license_type` varchar(200) DEFAULT NULL,
`software_template_notes` text DEFAULT NULL,
`software_template_created_at` datetime NOT NULL DEFAULT current_timestamp(),
`software_template_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
`software_template_archived_at` datetime DEFAULT NULL,
PRIMARY KEY (`software_template_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
-- --
-- Table structure for table `tags` -- Table structure for table `tags`
-- --
@@ -2244,6 +2305,7 @@ CREATE TABLE `tickets` (
`ticket_url_key` varchar(200) DEFAULT NULL, `ticket_url_key` varchar(200) DEFAULT NULL,
`ticket_created_at` datetime NOT NULL DEFAULT current_timestamp(), `ticket_created_at` datetime NOT NULL DEFAULT current_timestamp(),
`ticket_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(), `ticket_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
`ticket_due_at` datetime DEFAULT NULL,
`ticket_resolved_at` datetime DEFAULT NULL, `ticket_resolved_at` datetime DEFAULT NULL,
`ticket_archived_at` datetime DEFAULT NULL, `ticket_archived_at` datetime DEFAULT NULL,
`ticket_first_response_at` datetime DEFAULT NULL, `ticket_first_response_at` datetime DEFAULT NULL,
@@ -2458,6 +2520,35 @@ CREATE TABLE `vendor_files` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `vendor_templates`
--
DROP TABLE IF EXISTS `vendor_templates`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `vendor_templates` (
`vendor_template_id` int(11) NOT NULL AUTO_INCREMENT,
`vendor_template_name` varchar(200) NOT NULL,
`vendor_template_description` varchar(200) DEFAULT NULL,
`vendor_template_contact_name` varchar(200) DEFAULT NULL,
`vendor_template_phone_country_code` varchar(10) DEFAULT NULL,
`vendor_template_phone` varchar(200) DEFAULT NULL,
`vendor_template_extension` varchar(200) DEFAULT NULL,
`vendor_template_email` varchar(200) DEFAULT NULL,
`vendor_template_website` varchar(200) DEFAULT NULL,
`vendor_template_hours` varchar(200) DEFAULT NULL,
`vendor_template_sla` varchar(200) DEFAULT NULL,
`vendor_template_code` varchar(200) DEFAULT NULL,
`vendor_template_account_number` varchar(200) DEFAULT NULL,
`vendor_template_notes` text DEFAULT NULL,
`vendor_template_created_at` datetime NOT NULL DEFAULT current_timestamp(),
`vendor_template_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
`vendor_template_archived_at` datetime DEFAULT NULL,
PRIMARY KEY (`vendor_template_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
-- --
-- Table structure for table `vendors` -- Table structure for table `vendors`
-- --
@@ -2480,7 +2571,6 @@ CREATE TABLE `vendors` (
`vendor_code` varchar(200) DEFAULT NULL, `vendor_code` varchar(200) DEFAULT NULL,
`vendor_account_number` varchar(200) DEFAULT NULL, `vendor_account_number` varchar(200) DEFAULT NULL,
`vendor_notes` text DEFAULT NULL, `vendor_notes` text DEFAULT NULL,
`vendor_template` tinyint(1) NOT NULL DEFAULT 0,
`vendor_created_at` datetime NOT NULL DEFAULT current_timestamp(), `vendor_created_at` datetime NOT NULL DEFAULT current_timestamp(),
`vendor_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(), `vendor_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
`vendor_archived_at` datetime DEFAULT NULL, `vendor_archived_at` datetime DEFAULT NULL,
@@ -2500,4 +2590,4 @@ CREATE TABLE `vendors` (
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2025-05-24 13:23:21 -- Dump completed on 2025-06-17 22:44:10

View File

@@ -154,7 +154,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<option value="">- All Vendors -</option> <option value="">- All Vendors -</option>
<?php <?php
$sql_vendors_filter = mysqli_query($mysqli, "SELECT * FROM vendors WHERE vendor_client_id = 0 AND vendor_template = 0 ORDER BY vendor_name ASC"); $sql_vendors_filter = mysqli_query($mysqli, "SELECT * FROM vendors WHERE vendor_client_id = 0 ORDER BY vendor_name ASC");
while ($row = mysqli_fetch_array($sql_vendors_filter)) { while ($row = mysqli_fetch_array($sql_vendors_filter)) {
$vendor_id = intval($row['vendor_id']); $vendor_id = intval($row['vendor_id']);
$vendor_name = nullable_htmlentities($row['vendor_name']); $vendor_name = nullable_htmlentities($row['vendor_name']);
@@ -348,7 +348,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<i class="fas fa-fw fa-copy mr-2"></i>Copy <i class="fas fa-fw fa-copy mr-2"></i>Copy
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item" <a class="dropdown-item" href="#"
data-toggle="ajax-modal" data-toggle="ajax-modal"
data-modal-size="lg" data-modal-size="lg"
data-ajax-url="ajax/ajax_expense_refund.php" data-ajax-url="ajax/ajax_expense_refund.php"

View File

@@ -77,17 +77,21 @@ function getUserAgent() {
} }
function getIP() { function getIP() {
if (defined("CONST_GET_IP_METHOD")) {
if (CONST_GET_IP_METHOD == "HTTP_X_FORWARDED_FOR") { // Default way to get IP
$ip = getenv('HTTP_X_FORWARDED_FOR'); $ip = $_SERVER['REMOTE_ADDR'];
} else {
$ip = $_SERVER["HTTP_CF_CONNECTING_IP"] ?? $_SERVER['REMOTE_ADDR']; // Allow overrides via config.php in-case we use a proxy - https://docs.itflow.org/config_php
} if (defined("CONST_GET_IP_METHOD") && CONST_GET_IP_METHOD == "HTTP_X_FORWARDED_FOR") {
} else { $ip = explode(',', getenv('HTTP_X_FORWARDED_FOR'))[0] ?? $_SERVER['REMOTE_ADDR'];
} elseif (defined("CONST_GET_IP_METHOD") && CONST_GET_IP_METHOD == "HTTP_CF_CONNECTING_IP") {
$ip = $_SERVER["HTTP_CF_CONNECTING_IP"] ?? $_SERVER['REMOTE_ADDR']; $ip = $_SERVER["HTTP_CF_CONNECTING_IP"] ?? $_SERVER['REMOTE_ADDR'];
} }
// Abort if something isn't right
if (!filter_var($ip, FILTER_VALIDATE_IP)) { if (!filter_var($ip, FILTER_VALIDATE_IP)) {
error_log("ITFlow - Could not validate remote IP address");
error_log("ITFlow - IP was [$ip] using method " . CONST_GET_IP_METHOD);
exit("Potential Security Violation"); exit("Potential Security Violation");
} }
@@ -195,7 +199,7 @@ function truncate($text, $chars) {
function formatPhoneNumber($phoneNumber, $country_code = '', $show_country_code = false) { function formatPhoneNumber($phoneNumber, $country_code = '', $show_country_code = false) {
// Remove all non-digit characters // Remove all non-digit characters
$digits = preg_replace('/\D/', '', $phoneNumber); $digits = preg_replace('/\D/', '', $phoneNumber ?? '');
$formatted = ''; $formatted = '';
// If no digits at all, fallback early // If no digits at all, fallback early
@@ -1652,3 +1656,22 @@ function display_folder_options($parent_folder_id, $client_id, $folder_location
display_folder_options($folder_id, $client_id, $folder_location, $indent + 1); display_folder_options($folder_id, $client_id, $folder_location, $indent + 1);
} }
} }
function sanitize_url($url) {
$allowed = ['http', 'https', 'file', 'ftp', 'ftps', 'sftp', 'dav', 'webdav', 'caldav', 'carddav', 'ssh', 'telnet', 'smb', 'rdp', 'vnc', 'rustdesk', 'anydesk', 'connectwise', 'splashtop', 'sip', 'sips', 'ldap', 'ldaps'];
$parts = parse_url($url ?? '');
if (isset($parts['scheme']) && !in_array(strtolower($parts['scheme']), $allowed)) {
// Remove the scheme and colon
$pos = strpos($url, ':');
$without_scheme = $url;
if ($pos !== false) {
$without_scheme = substr($url, $pos + 1); // This keeps slashes (e.g. //pizza.com)
}
// Prepend 'unsupported://' (strip any leading slashes from $without_scheme to avoid triple slashes)
$unsupported = 'unsupported://' . ltrim($without_scheme, '/');
return htmlspecialchars($unsupported, ENT_QUOTES, 'UTF-8');
}
// Safe schemes: return escaped original URL
return htmlspecialchars($url ?? '', ENT_QUOTES, 'UTF-8');
}

View File

@@ -43,7 +43,6 @@ if (isset($_GET['query'])) {
$sql_vendors = mysqli_query($mysqli, "SELECT * FROM vendors $sql_vendors = mysqli_query($mysqli, "SELECT * FROM vendors
LEFT JOIN clients ON vendor_client_id = client_id LEFT JOIN clients ON vendor_client_id = client_id
WHERE vendor_archived_at IS NULL WHERE vendor_archived_at IS NULL
AND vendor_template = 0
AND (vendor_name LIKE '%$query%' OR vendor_phone LIKE '%$phone_query%') AND (vendor_name LIKE '%$query%' OR vendor_phone LIKE '%$phone_query%')
$access_permission_query $access_permission_query
ORDER BY vendor_id DESC LIMIT 5" ORDER BY vendor_id DESC LIMIT 5"

View File

@@ -2,6 +2,7 @@
require_once "../config.php"; require_once "../config.php";
require_once "../functions.php"; require_once "../functions.php";
require_once "../includes/get_settings.php";
session_start(); session_start();
@@ -201,6 +202,437 @@ if (isset($_GET['add_ticket_feedback'], $_GET['url_key'])) {
} }
} }
if (isset($_GET['export_quote_pdf'])) {
$quote_id = intval($_GET['export_quote_pdf']);
$url_key = sanitizeInput($_GET['url_key']);
$sql = mysqli_query(
$mysqli,
"SELECT * FROM quotes
LEFT JOIN clients ON quote_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 quote_id = $quote_id AND quote_url_key = '$url_key'
LIMIT 1"
);
if (mysqli_num_rows($sql) == 1) {
$row = mysqli_fetch_array($sql);
$quote_id = intval($row['quote_id']);
$quote_prefix = nullable_htmlentities($row['quote_prefix']);
$quote_number = intval($row['quote_number']);
$quote_scope = nullable_htmlentities($row['quote_scope']);
$quote_status = nullable_htmlentities($row['quote_status']);
$quote_date = nullable_htmlentities($row['quote_date']);
$quote_expire = nullable_htmlentities($row['quote_expire']);
$quote_amount = floatval($row['quote_amount']);
$quote_discount = floatval($row['quote_discount_amount']);
$quote_currency_code = nullable_htmlentities($row['quote_currency_code']);
$quote_note = nullable_htmlentities($row['quote_note']);
$quote_url_key = nullable_htmlentities($row['quote_url_key']);
$quote_created_at = nullable_htmlentities($row['quote_created_at']);
$category_id = intval($row['quote_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;
}
$sql = mysqli_query($mysqli, "SELECT * FROM companies, settings WHERE companies.company_id = settings.company_id AND companies.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_logo = nullable_htmlentities($row['company_logo']);
$company_locale = nullable_htmlentities($row['company_locale']);
//Set Currency Format
$currency_format = numfmt_create($company_locale, NumberFormatter::CURRENCY);
require_once("../plugins/TCPDF/tcpdf.php");
// Start TCPDF
$pdf = new TCPDF('P', 'mm', 'A4', true, 'UTF-8', false);
$pdf->SetMargins(15, 15, 15);
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
$pdf->AddPage();
$pdf->SetFont('helvetica', '', 10);
// Logo + Right Columns
$html = '<table width="100%" cellspacing="0" cellpadding="5">
<tr>
<td width="40%">';
if (!empty($company_logo)) {
$logo_path = "../uploads/settings/$company_logo";
if (file_exists($logo_path)) {
$pdf->Image($logo_path, $pdf->GetX(), $pdf->GetY(), 40);
}
}
$html .= '</td>
<td width="60%" align="right">
<span style="font-size:18pt; font-weight:bold;">QUOTE</span><br>
<span style="font-size:14pt;">' . $quote_prefix . $quote_number . '</span><br>';
if (strtolower($quote_status) === 'accepted') {
$html .= '<span style="color:green; font-weight:bold;">ACCEPTED</span><br>';
}
if (strtolower($quote_status) === 'declined') {
$html .= '<span style="color:red; font-weight:bold;">DECLINED</span><br>';
}
$html .= '</td>
</tr>
</table><br><br>';
// Billing titles
$html .= '<table width="100%" cellspacing="0" cellpadding="2">
<tr>
<td width="50%" style="font-size:14pt; font-weight:bold;">' . $company_name . '</td>
<td width="50%" align="right" style="font-size:14pt; font-weight:bold;">' . $client_name . '</td>
</tr>
<tr>
<td style="font-size:10pt; line-height:1.4;">' . nl2br("$company_address\n$company_city $company_state $company_zip\n$company_country\n$company_phone\n$company_website") . '</td>
<td style="font-size:10pt; line-height:1.4;" align="right">' . nl2br("$location_address\n$location_city $location_state $location_zip\n$location_country\n$contact_email\n$contact_phone") . '</td>
</tr>
</table><br>';
// Date table
$html .= '<table border="0" cellpadding="3" cellspacing="0" width="100%">
<tr>
<td width="60%"></td>
<td width="20%" style="font-size:10pt;"><strong>Date:</strong></td>
<td width="20%" style="font-size:10pt;" align="right">' . $quote_date . '</td>
</tr>
<tr>
<td></td>
<td style="font-size:10pt;"><strong>Expires:</strong></td>
<td style="font-size:10pt;" align="right">' . $quote_expire . '</td>
</tr>
</table><br><br>';
// Items header
$html .= '
<table border="0" cellpadding="5" cellspacing="0" width="100%">
<tr style="background-color:#f0f0f0;">
<th align="left" width="40%"><strong>Item</strong></th>
<th align="center" width="10%"><strong>Qty</strong></th>
<th align="right" width="15%"><strong>Price</strong></th>
<th align="right" width="15%"><strong>Tax</strong></th>
<th align="right" width="20%"><strong>Amount</strong></th>
</tr>';
// Load items
$sql_items = mysqli_query($mysqli, "SELECT * FROM invoice_items WHERE item_quote_id = $quote_id ORDER BY item_order ASC");
while ($item = mysqli_fetch_array($sql_items)) {
$name = $item['item_name'];
$desc = $item['item_description'];
$qty = $item['item_quantity'];
$price = $item['item_price'];
$tax = $item['item_tax'];
$total = $item['item_total'];
$sub_total += $price * $qty;
$total_tax += $tax;
$html .= '
<tr>
<td>
<strong>' . $name . '</strong><br>
<span style="font-style:italic; font-size:9pt;">' . nl2br($desc) . '</span>
</td>
<td align="center">' . number_format($qty, 2) . '</td>
<td align="right">' . numfmt_format_currency($currency_format, $price, $quote_currency_code) . '</td>
<td align="right">' . numfmt_format_currency($currency_format, $tax, $quote_currency_code) . '</td>
<td align="right">' . numfmt_format_currency($currency_format, $total, $quote_currency_code) . '</td>
</tr>';
}
$html .= '</table><br><hr><br><br>';
// Totals
$html .= '<table width="100%" cellspacing="0" cellpadding="4">
<tr>
<td width="70%" rowspan="6" valign="top"><i>' . nl2br($quote_note) . '</i></td>
<td width="30%">
<table width="100%" cellpadding="3" cellspacing="0">
<tr><td>Subtotal:</td><td align="right">' . numfmt_format_currency($currency_format, $sub_total, $quote_currency_code) . '</td></tr>';
if ($quote_discount > 0) {
$html .= '<tr><td>Discount:</td><td align="right">-' . numfmt_format_currency($currency_format, $quote_discount, $quote_currency_code) . '</td></tr>';
}
if ($total_tax > 0) {
$html .= '<tr><td>Tax:</td><td align="right">' . numfmt_format_currency($currency_format, $total_tax, $quote_currency_code) . '</td></tr>';
}
$html .= '
<tr><td><h3><strong>Total:</strong></h3></td><td align="right"><h3><strong>' . numfmt_format_currency($currency_format, $quote_amount, $quote_currency_code) . '</strong></h3></td></tr>
</table>
</td>
</tr>
</table><br><br>';
// Footer
$html .= '<div style="text-align:center; font-size:9pt; color:gray;">' . nl2br($config_quote_footer) . '</div>';
$pdf->writeHTML($html, true, false, true, false, '');
$filename = preg_replace('/[^A-Za-z0-9_\-]/', '_', "{$quote_date}_{$company_name}_{$client_name}_Quote_{$quote_prefix}{$quote_number}");
$pdf->Output("$filename.pdf", 'I');
}
exit;
}
if (isset($_GET['export_invoice_pdf'])) {
$invoice_id = intval($_GET['export_invoice_pdf']);
$url_key = sanitizeInput($_GET['url_key']);
$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 AND invoice_url_key = '$url_key'
LIMIT 1"
);
if (mysqli_num_rows($sql) == 1) {
$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_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;
}
$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']);
$company_locale = nullable_htmlentities($row['company_locale']);
//Set Currency Format
$currency_format = numfmt_create($company_locale, NumberFormatter::CURRENCY);
$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");
//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;
//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);
require_once("../plugins/TCPDF/tcpdf.php");
// Start TCPDF
$pdf = new TCPDF('P', 'mm', 'A4', true, 'UTF-8', false);
$pdf->SetMargins(15, 15, 15);
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
$pdf->AddPage();
$pdf->SetFont('helvetica', '', 10);
// Logo + Right Columns
$html = '<table width="100%" cellspacing="0" cellpadding="5">
<tr>
<td width="40%">';
if (!empty($company_logo)) {
$logo_path = "../uploads/settings/$company_logo";
if (file_exists($logo_path)) {
$pdf->Image($logo_path, $pdf->GetX(), $pdf->GetY(), 40);
}
}
$html .= '</td>
<td width="60%" align="right">
<span style="font-size:18pt; font-weight:bold;">Invoice</span><br>
<span style="font-size:14pt;">' . $invoice_prefix . $invoice_number . '</span><br>';
if (strtolower($invoice_status) === 'paid') {
$html .= '<span style="color:green; font-weight:bold;">PAID</span><br>';
}
$html .= '</td>
</tr>
</table><br><br>';
// Billing titles
$html .= '<table width="100%" cellspacing="0" cellpadding="2">
<tr>
<td width="50%" style="font-size:14pt; font-weight:bold;">' . $company_name . '</td>
<td width="50%" align="right" style="font-size:14pt; font-weight:bold;">' . $client_name . '</td>
</tr>
<tr>
<td style="font-size:10pt; line-height:1.4;">' . nl2br("$company_address\n$company_city $company_state $company_zip\n$company_country\n$company_phone\n$company_website\n$company_tax_id_display") . '</td>
<td style="font-size:10pt; line-height:1.4;" align="right">' . nl2br("$location_address\n$location_city $location_state $location_zip\n$location_country\n$contact_email\n$contact_phone") . '</td>
</tr>
</table><br>';
// Date table
$html .= '<table border="0" cellpadding="3" cellspacing="0" width="100%">
<tr>
<td width="60%"></td>
<td width="20%" style="font-size:10pt;"><strong>Date:</strong></td>
<td width="20%" style="font-size:10pt;" align="right">' . $invoice_date . '</td>
</tr>
<tr>
<td></td>
<td style="font-size:10pt;"><strong>Due:</strong></td>
<td style="font-size:10pt;" align="right">' . $invoice_due . '</td>
</tr>
</table><br><br>';
// Items header
$html .= '
<table border="0" cellpadding="5" cellspacing="0" width="100%">
<tr style="background-color:#f0f0f0;">
<th align="left" width="40%"><strong>Item</strong></th>
<th align="center" width="10%"><strong>Qty</strong></th>
<th align="right" width="15%"><strong>Price</strong></th>
<th align="right" width="15%"><strong>Tax</strong></th>
<th align="right" width="20%"><strong>Amount</strong></th>
</tr>';
// Load items
$sql_items = mysqli_query($mysqli, "SELECT * FROM invoice_items WHERE item_invoice_id = $invoice_id ORDER BY item_order ASC");
while ($item = mysqli_fetch_array($sql_items)) {
$name = $item['item_name'];
$desc = $item['item_description'];
$qty = $item['item_quantity'];
$price = $item['item_price'];
$tax = $item['item_tax'];
$total = $item['item_total'];
$sub_total += $price * $qty;
$total_tax += $tax;
$html .= '
<tr>
<td>
<strong>' . $name . '</strong><br>
<span style="font-style:italic; font-size:9pt;">' . nl2br($desc) . '</span>
</td>
<td align="center">' . number_format($qty, 2) . '</td>
<td align="right">' . numfmt_format_currency($currency_format, $price, $invoice_currency_code) . '</td>
<td align="right">' . numfmt_format_currency($currency_format, $tax, $invoice_currency_code) . '</td>
<td align="right">' . numfmt_format_currency($currency_format, $total, $invoice_currency_code) . '</td>
</tr>';
}
$html .= '</table><br><hr><br><br>';
// Totals
$html .= '<table width="100%" cellspacing="0" cellpadding="4">
<tr>
<td width="70%" rowspan="6" valign="top"><i>' . nl2br($invoice_note) . '</i></td>
<td width="30%">
<table width="100%" cellpadding="3" cellspacing="0">
<tr><td>Subtotal:</td><td align="right">' . numfmt_format_currency($currency_format, $sub_total, $invoice_currency_code) . '</td></tr>';
if ($invoice_discount > 0) {
$html .= '<tr><td>Discount:</td><td align="right">-' . numfmt_format_currency($currency_format, $invoice_discount, $invoice_currency_code) . '</td></tr>';
}
if ($total_tax > 0) {
$html .= '<tr><td>Tax:</td><td align="right">' . numfmt_format_currency($currency_format, $total_tax, $invoice_currency_code) . '</td></tr>';
}
$html .= '
<tr><td>Total:</td><td align="right">' . numfmt_format_currency($currency_format, $invoice_amount, $invoice_currency_code) . '</td></tr>';
if ($amount_paid > 0) {
$html .= '<tr><td>Paid:</td><td align="right">' . numfmt_format_currency($currency_format, $amount_paid, $invoice_currency_code) . '</td></tr>';
}
$html .= '
<tr><td><h3><strong>Balance:</strong></h3></td><td align="right"><h3><strong>' . numfmt_format_currency($currency_format, $balance, $invoice_currency_code) . '</strong></h3></td></tr>
</table>
</td>
</tr>
</table><br><br>';
// Footer
$html .= '<div style="text-align:center; font-size:9pt; color:gray;">' . nl2br($config_invoice_footer) . '</div>';
$pdf->writeHTML($html, true, false, true, false, '');
$filename = preg_replace('/[^A-Za-z0-9_\-]/', '_', "{$invoice_date}_{$company_name}_{$client_name}_Invoice_{$invoice_prefix}{$invoice_number}");
$pdf->Output("$filename.pdf", 'I');
}
exit;
}
if (isset($_POST['guest_quote_upload_file'])) { if (isset($_POST['guest_quote_upload_file'])) {
$quote_id = intval($_POST['quote_id']); $quote_id = intval($_POST['quote_id']);
$url_key = sanitizeInput($_POST['url_key']); $url_key = sanitizeInput($_POST['url_key']);

File diff suppressed because it is too large Load Diff

View File

@@ -87,6 +87,21 @@ $config_quote_footer = nullable_htmlentities($row['config_quote_footer']);
//Set Currency Format //Set Currency Format
$currency_format = numfmt_create($company_locale, NumberFormatter::CURRENCY); $currency_format = numfmt_create($company_locale, NumberFormatter::CURRENCY);
//Set Badge color based off of quote status
if ($quote_status == "Sent") {
$quote_badge_color = "warning text-white";
} elseif ($quote_status == "Viewed") {
$quote_badge_color = "primary";
} elseif ($quote_status == "Accepted") {
$quote_badge_color = "success";
} elseif ($quote_status == "Declined") {
$quote_badge_color = "danger";
} elseif ($quote_status == "Invoiced") {
$quote_badge_color = "info";
} else {
$quote_badge_color = "secondary";
}
//Update status to Viewed only if invoice_status = "Sent" //Update status to Viewed only if invoice_status = "Sent"
if ($quote_status == 'Sent') { if ($quote_status == 'Sent') {
mysqli_query($mysqli, "UPDATE quotes SET quote_status = 'Viewed' WHERE quote_id = $quote_id"); mysqli_query($mysqli, "UPDATE quotes SET quote_status = 'Viewed' WHERE quote_id = $quote_id");
@@ -102,627 +117,188 @@ if ($quote_status == "Draft" || $quote_status == "Sent" || $quote_status == "Vie
?> ?>
<div class="card"> <div class="card">
<div class="card-header d-print-none"> <div class="card-header d-print-none">
<div class="float-right"> <div class="float-right">
<a class="btn btn-primary" href="#" onclick="window.print();"><i class="fas fa-fw fa-print mr-2"></i>Print</a> <a class="btn btn-primary" href="#" onclick="window.print();"><i class="fas fa-fw fa-print mr-2"></i>Print</a>
<a class="btn btn-primary" href="#" onclick="pdfMake.createPdf(docDefinition).download('<?php echo strtoAZaz09(html_entity_decode("$quote_date-$company_name-QUOTE-$quote_prefix$quote_number")); ?>');"> <a class="btn btn-primary" href="guest_post.php?export_quote_pdf=<?php echo $quote_id; ?>&url_key=<?php echo $url_key; ?>">
<i class="fa fa-fw fa-download mr-2"></i>Download <i class="fa fa-fw fa-download mr-2"></i>Download
</a> </a>
</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>
</ul>
</div>
<div class="col-sm-4">
<h3 class="text-right"><strong>QUOTE</strong></h3>
<h5 class="badge badge-<?php echo $quote_badge_color; ?> p-2 float-right">
<?php echo "$quote_status"; ?>
</h5>
<table class="table table-sm table-borderless">
<tr>
<th>Quote #:</th>
<td class="text-right"><?php echo "$quote_prefix$quote_number"; ?></td>
</tr>
<tr>
<th>Date:</th>
<td class="text-right"><?php echo $quote_date; ?></td>
</tr>
<tr>
<th>Expires:</th>
<td class="text-right"><?php echo $quote_expire; ?></td>
</tr>
</table>
</div>
</div>
<div class="row mb-3 bg-light p-3">
<div class="col">
<h6><strong>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>
</div> </div>
<div class="card-body">
<div class="row mb-4"> <?php $sql_items = mysqli_query($mysqli, "SELECT * FROM invoice_items WHERE item_quote_id = $quote_id ORDER BY item_order ASC"); ?>
<div class="col-sm-2">
<img class="img-fluid" src="<?php echo "../uploads/settings/$company_logo"; ?>">
</div>
<div class="col-sm-10">
<?php if ($quote_status == "Accepted" || $quote_status == "Declined") { ?>
<div class="ribbon-wrapper">
<div class="ribbon bg-success <?php if ($quote_status == 'Declined') { echo 'bg-danger'; } ?>">
<?php echo $quote_status; ?>
</div>
</div>
<?php } ?>
<h3 class="text-right mt-5"><strong>Quote</strong><br><small class="text-secondary"><?php echo "$quote_prefix$quote_number"; ?></small></h3>
</div>
</div>
<div class="row mb-4"> <div class="row mb-3">
<div class="col-md-12">
<div class="card">
<div class="table-responsive">
<table class="table table-borderless">
<thead class="bg-light">
<tr>
<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
<div class="col-sm"> $total_tax = $sub_total = 0; // Default 0
<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"; ?></li>
<li><small><?php echo $company_country; ?></small></li>
<li><?php echo $company_phone; ?></li>
<li><?php echo $company_email; ?></li>
</ul>
</div> while ($row = mysqli_fetch_array($sql_items)) {
$item_id = intval($row['item_id']);
<div class="col-sm"> $item_name = nullable_htmlentities($row['item_name']);
$item_description = nullable_htmlentities($row['item_description']);
<ul class="list-unstyled text-right"> $item_quantity = floatval($row['item_quantity']);
<li><h4><strong><?php echo $client_name; ?></strong></h4></li> $item_price = floatval($row['item_price']);
<li><?php echo $location_address; ?></li> $item_tax = floatval($row['item_tax']);
<li><?php echo "$location_city $location_state $location_zip"; ?></li> $item_total = floatval($row['item_total']);
<li><small><?php echo $location_country; ?></small></li> $total_tax = $item_tax + $total_tax;
<li><?php echo "$contact_phone $contact_extension"; ?></li> $sub_total = $item_price * $item_quantity + $sub_total;
<li><?php echo $contact_mobile; ?></li>
<li><?php echo $contact_email; ?></li>
</ul>
</div>
</div>
<div class="row mb-4">
<div class="col-sm-8">
</div>
<div class="col-sm-4">
<table class="table">
<tr>
<td>Date</td>
<td class="text-right"><?php echo $quote_date; ?></td>
</tr>
<tr class="text-bold">
<td>Expire</td>
<td class="text-right"><?php echo $quote_expire; ?></td>
</tr>
</table>
</div>
</div>
<?php $sql_items = mysqli_query($mysqli, "SELECT * FROM invoice_items WHERE item_quote_id = $quote_id ORDER BY item_order ASC"); ?>
<div class="row mb-4">
<div class="col-md-12">
<div class="card">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Product</th>
<th>Description</th>
<th class="text-center">Qty</th>
<th class="text-right">Price</th>
<th class="text-right">Tax</th>
<th class="text-right">Total</th>
</tr>
</thead>
<tbody>
<?php
$total_tax = $sub_total = 0; // Default 0
while ($row = mysqli_fetch_array($sql_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']);
$total_tax = $item_tax + $total_tax;
$sub_total = $item_price * $item_quantity + $sub_total;
?>
<tr>
<td><?php echo $item_name; ?></td>
<td><?php echo nl2br($item_description); ?></td>
<td class="text-center"><?php echo $item_quantity; ?></td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $item_price, $quote_currency_code); ?></td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $item_tax, $quote_currency_code); ?></td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $item_total, $quote_currency_code); ?></td>
</tr>
<?php
}
?> ?>
</tbody> <tr>
</table> <td><?php echo $item_name; ?></td>
</div> <td><?php echo nl2br($item_description); ?></td>
<td class="text-center"><?php echo $item_quantity; ?></td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $item_price, $quote_currency_code); ?></td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $item_tax, $quote_currency_code); ?></td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $item_total, $quote_currency_code); ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
</div> </div>
</div> </div>
</div> </div>
<div class="row mb-4">
<div class="col-sm-7">
<?php if (!empty($quote_note)) { ?>
<div class="card">
<div class="card-body">
<?php echo nl2br($quote_note); ?>
</div>
</div>
<?php } ?>
</div>
<div class="col-sm-3 offset-sm-2">
<table class="table table-borderless">
<tbody>
<tr class="border-bottom">
<td>Subtotal</td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $sub_total, $quote_currency_code); ?></td>
</tr>
<?php if ($quote_discount > 0) { ?>
<tr class="border-bottom">
<td>Discount</td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, -$quote_discount, $quote_currency_code); ?></td>
</tr>
<?php } ?>
<?php if ($total_tax > 0) { ?>
<tr class="border-bottom">
<td>Tax</td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $total_tax, $quote_currency_code); ?></td>
</tr>
<?php } ?>
<tr class="border-bottom">
<td><strong>Total</strong></td>
<td class="text-right"><strong><?php echo numfmt_format_currency($currency_format, $quote_amount, $quote_currency_code); ?></strong></td>
</tr>
</tbody>
</table>
</div>
</div>
<hr class="mt-5">
<div class="text-center"><?php echo nl2br($config_quote_footer); ?></div>
<div class="">
<?php
if ($quote_status == "Sent" || $quote_status == "Viewed" && strtotime($quote_expire) > strtotime("now")) { ?>
<a class="btn btn-success confirm-link" href="guest_post.php?accept_quote=<?php echo $quote_id; ?>&url_key=<?php echo $url_key; ?>">
<i class="fas fa-fw fa-thumbs-up mr-2"></i>Accept
</a>
<a class="btn btn-danger confirm-link" href="guest_post.php?decline_quote=<?php echo $quote_id; ?>&url_key=<?php echo $url_key; ?>">
<i class="fas fa-fw fa-thumbs-down mr-2"></i>Decline
</a>
<?php } ?>
<?php if ($quote_status == "Accepted") { ?>
<button type="button" class="btn btn-success" data-toggle="modal" data-target="#uploadFileModal">
<i class="fas fa-fw fa-cloud-upload-alt mr-2"></i>Upload File
</button>
<?php } ?>
</div>
</div> </div>
<div class="row mb-3">
<div class="col-sm-7">
<?php if (!empty($quote_note)) { ?>
<div class="card">
<div class="card-body">
<?php echo nl2br($quote_note); ?>
</div>
</div>
<?php } ?>
</div>
<div class="col-sm-3 offset-sm-2">
<table class="table table-borderless">
<tbody>
<tr>
<td>Subtotal:</td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $sub_total, $quote_currency_code); ?></td>
</tr>
<?php if ($quote_discount > 0) { ?>
<tr>
<td>Discount:</td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, -$quote_discount, $quote_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, $quote_currency_code); ?></td>
</tr>
<?php } ?>
<tr class="border-top h5 text-bold">
<td><strong>Total:</strong></td>
<td class="text-right"><strong><?php echo numfmt_format_currency($currency_format, $quote_amount, $quote_currency_code); ?></strong></td>
</tr>
</tbody>
</table>
</div>
</div>
<hr class="mt-5">
<div class="text-center"><?php echo nl2br($config_quote_footer); ?></div>
<div class="">
<?php
if ($quote_status == "Sent" || $quote_status == "Viewed" && strtotime($quote_expire) > strtotime("now")) { ?>
<a class="btn btn-success confirm-link" href="guest_post.php?accept_quote=<?php echo $quote_id; ?>&url_key=<?php echo $url_key; ?>">
<i class="fas fa-fw fa-thumbs-up mr-2"></i>Accept
</a>
<a class="btn btn-danger confirm-link" href="guest_post.php?decline_quote=<?php echo $quote_id; ?>&url_key=<?php echo $url_key; ?>">
<i class="fas fa-fw fa-thumbs-down mr-2"></i>Decline
</a>
<?php } ?>
<?php if ($quote_status == "Accepted") { ?>
<button type="button" class="btn btn-success" data-toggle="modal" data-target="#uploadFileModal">
<i class="fas fa-fw fa-cloud-upload-alt mr-2"></i>Upload File
</button>
<?php } ?>
</div>
</div> </div>
</div>
<script src='../plugins/pdfmake/pdfmake.min.js'></script>
<script src='../plugins/pdfmake/vfs_fonts.js'></script>
<script>
var docDefinition = {
info: {
title: <?php echo json_encode(html_entity_decode($company_name) . "- Quote") ?>,
author: <?php echo json_encode(html_entity_decode($company_name)) ?>
},
//watermark: {text: '<?php echo $quote_status; ?>', color: 'lightgrey', opacity: 0.3, bold: true, italics: false},
content: [
// Header
{
columns: [
<?php if (!empty($company_logo_base64)) { ?>
{
image: <?php echo json_encode("data:image;base64,$company_logo_base64") ?>,
width: 120
},
<?php } ?>
[
{
text: 'Quote',
style: 'invoiceTitle',
width: '*'
},
{
text: <?php echo json_encode(html_entity_decode("$quote_prefix$quote_number")) ?>,
style: 'invoiceNumber',
width: '*'
},
],
],
},
// Billing Headers
{
columns: [
{
text: <?php echo json_encode(html_entity_decode($company_name)) ?>,
style: 'invoiceBillingTitle'
},
{
text: <?php echo json_encode(html_entity_decode($client_name)) ?>,
style: 'invoiceBillingTitleClient'
},
]
},
// Billing Address
{
columns: [
{
text: <?php echo json_encode(html_entity_decode("$company_address \n $company_city $company_state $company_zip \n $company_country \n $company_phone \n $company_website")) ?>,
style: 'invoiceBillingAddress'
},
{
text: <?php echo json_encode(html_entity_decode("$location_address \n $location_city $location_state $location_zip \n $location_country \n $contact_email \n $contact_phone")) ?>,
style: 'invoiceBillingAddressClient'
},
]
},
//Invoice Dates Table
{
table: {
// headers are automatically repeated if the table spans over multiple pages
// you can declare how many rows should be treated as headers
headerRows: 0,
widths: [ '*',80, 80 ],
body: [
// Total
[
{
text: '',
rowSpan: 3
},
{},
{},
],
[
{},
{
text: 'Date',
style: 'invoiceDateTitle'
},
{
text: <?php echo json_encode(html_entity_decode($quote_date)) ?>,
style: 'invoiceDateValue'
},
],
[
{},
{
text: 'Expire',
style: 'invoiceDueDateTitle'
},
{
text: <?php echo json_encode(html_entity_decode($quote_expire)) ?>,
style: 'invoiceDueDateValue'
},
],
]
}, // table
layout: 'lightHorizontalLines'
},
// Line breaks
'\n\n',
// Items
{
table: {
// headers are automatically repeated if the table spans over multiple pages
// you can declare how many rows should be treated as headers
headerRows: 1,
widths: [ '*', 40, 'auto', 'auto', 80 ],
body: [
// Table Header
[
{
text: 'Product',
style: [ 'itemsHeader', 'left']
},
{
text: 'Qty',
style: [ 'itemsHeader', 'center']
},
{
text: 'Price',
style: [ 'itemsHeader', 'right']
},
{
text: 'Tax',
style: [ 'itemsHeader', 'right']
},
{
text: 'Total',
style: [ 'itemsHeader', 'right']
}
],
// Items
<?php
$total_tax = 0;
$sub_total = 0;
$sql_invoice_items = mysqli_query($mysqli, "SELECT * FROM invoice_items WHERE item_quote_id = $quote_id ORDER BY item_order ASC");
while ($row = mysqli_fetch_array($sql_invoice_items)) {
$item_name = $row['item_name'];
$item_description = $row['item_description'];
$item_quantity = $row['item_quantity'];
$item_price = $row['item_price'];
$item_subtotal = $row['item_price'];
$item_tax = $row['item_tax'];
$item_total = $row['item_total'];
$tax_id = $row['item_tax_id'];
$total_tax = $item_tax + $total_tax;
$sub_total = $item_price * $item_quantity + $sub_total;
?>
// Item
[
[
{
text: <?php echo json_encode($item_name) ?>,
style: 'itemTitle'
},
{
text: <?php echo json_encode($item_description) ?>,
style: 'itemDescription'
}
],
{
text: <?php echo $item_quantity ?>,
style: 'itemQty'
},
{
text: <?php echo json_encode(numfmt_format_currency($currency_format, $item_price, $quote_currency_code)) ?>,
style: 'itemNumber'
},
{
text: <?php echo json_encode(numfmt_format_currency($currency_format, $item_tax, $quote_currency_code)) ?>,
style: 'itemNumber'
},
{
text: <?php echo json_encode(numfmt_format_currency($currency_format, $item_total, $quote_currency_code)) ?>,
style: 'itemNumber'
}
],
<?php
}
?>
// END Items
]
}, // table
layout: 'lightHorizontalLines'
},
// TOTAL
{
table: {
// headers are automatically repeated if the table spans over multiple pages
// you can declare how many rows should be treated as headers
headerRows: 0,
widths: [ '*','auto', 80 ],
body: [
// Total
[
{
text: 'Notes',
style:'notesTitle'
},
{},
{}
],
[
{
rowSpan: '*',
text: <?php echo json_encode(html_entity_decode($quote_note)) ?>,
style: 'notesText'
},
{
text: 'Subtotal',
style: 'itemsFooterSubTitle'
},
{
text: <?php echo json_encode(numfmt_format_currency($currency_format, $sub_total, $quote_currency_code)) ?>,
style: 'itemsFooterSubValue'
}
],
<?php if ($quote_discount > 0) { ?>
[
{},
{
text: 'Discount',
style: 'itemsFooterSubTitle'
},
{
text: <?php echo json_encode(numfmt_format_currency($currency_format, -$quote_discount, $quote_currency_code)) ?>,
style: 'itemsFooterSubValue'
}
],
<?php } ?>
<?php if ($total_tax > 0) { ?>
[
{},
{
text: 'Tax',
style: 'itemsFooterSubTitle'
},
{
text: <?php echo json_encode(numfmt_format_currency($currency_format, $total_tax, $quote_currency_code)) ?>,
style: 'itemsFooterSubValue'
}
],
<?php } ?>
[
{},
{
text: 'Total',
style: 'itemsFooterTotalTitle'
},
{
text: <?php echo json_encode(numfmt_format_currency($currency_format, $quote_amount, $quote_currency_code)) ?>,
style: 'itemsFooterTotalValue'
}
],
]
}, // table
layout: 'lightHorizontalLines'
},
// TERMS / FOOTER
{
text: <?php echo json_encode("$config_quote_footer"); ?>,
style: 'documentFooterCenter'
}
], //End Content,
styles: {
// Document Footer
documentFooterCenter: {
fontSize: 9,
margin: [10,50,10,10],
alignment: 'center'
},
// Invoice Title
invoiceTitle: {
fontSize: 18,
bold: true,
alignment: 'right',
margin: [0,0,0,3]
},
// Invoice Number
invoiceNumber: {
fontSize: 14,
alignment: 'right'
},
// Billing Headers
invoiceBillingTitle: {
fontSize: 14,
bold: true,
alignment: 'left',
margin: [0,20,0,5]
},
invoiceBillingTitleClient: {
fontSize: 14,
bold: true,
alignment: 'right',
margin: [0,20,0,5]
},
// Billing Details
invoiceBillingAddress: {
fontSize: 10,
lineHeight: 1.2
},
invoiceBillingAddressClient: {
fontSize: 10,
lineHeight: 1.2,
alignment: 'right',
margin: [0,0,0,30]
},
// Invoice Dates
invoiceDateTitle: {
fontSize: 10,
alignment: 'left',
margin: [0,5,0,5]
},
invoiceDateValue: {
fontSize: 10,
alignment: 'right',
margin: [0,5,0,5]
},
// Invoice Due Dates
invoiceDueDateTitle: {
fontSize: 10,
bold: true,
alignment: 'left',
margin: [0,5,0,5]
},
invoiceDueDateValue: {
fontSize: 10,
bold: true,
alignment: 'right',
margin: [0,5,0,5]
},
// Items Header
itemsHeader: {
fontSize: 10,
margin: [0,5,0,5],
bold: true,
alignment: 'right'
},
// Item Title
itemTitle: {
fontSize: 10,
bold: true,
margin: [0,5,0,3]
},
itemDescription: {
italics: true,
fontSize: 9,
lineHeight: 1.1,
margin: [0,3,0,5]
},
itemQty: {
fontSize: 10,
margin: [0,5,0,5],
alignment: 'center'
},
itemNumber: {
fontSize: 10,
margin: [0,5,0,5],
alignment: 'right'
},
itemTotal: {
fontSize: 10,
margin: [0,5,0,5],
bold: true,
alignment: 'right'
},
// Items Footer (Subtotal, Total, Tax, etc)
itemsFooterSubTitle: {
fontSize: 10,
margin: [0,5,0,5],
alignment: 'right'
},
itemsFooterSubValue: {
fontSize: 10,
margin: [0,5,0,5],
bold: false,
alignment: 'right'
},
itemsFooterTotalTitle: {
fontSize: 10,
margin: [0,5,0,5],
bold: true,
alignment: 'right'
},
itemsFooterTotalValue: {
fontSize: 10,
margin: [0,5,0,5],
bold: true,
alignment: 'right'
},
notesTitle: {
fontSize: 10,
bold: true,
margin: [0,5,0,5]
},
notesText: {
fontSize: 9,
margin: [0,5,50,5]
},
left: {
alignment: 'left'
},
center: {
alignment: 'center'
},
},
defaultStyle: {
columnGap: 20,
}
}
</script>
<?php <?php
require_once "guest_quote_upload_file_modal.php"; require_once "guest_quote_upload_file_modal.php";
require_once "includes/guest_footer.php"; require_once "includes/guest_footer.php";

View File

@@ -2,6 +2,7 @@
require_once "../config.php"; require_once "../config.php";
require_once "../functions.php"; require_once "../functions.php";
require_once "../includes/get_settings.php";
session_start(); session_start();

View File

@@ -5,4 +5,4 @@
* Update this file each time we merge develop into master. Format is YY.MM (add a .v if there is more than one release a month. * Update this file each time we merge develop into master. Format is YY.MM (add a .v if there is more than one release a month.
*/ */
DEFINE("APP_VERSION", "25.05"); DEFINE("APP_VERSION", "25.06");

View File

@@ -1,3 +1,35 @@
<?php
// Badge Counts
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('contact_id') AS num FROM contacts WHERE contact_archived_at IS NULL"));
$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"));
$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"));
$num_assets = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('service_id') AS num FROM services"));
$num_services = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('credential_id') AS num FROM credentials WHERE credential_archived_at IS NULL"));
$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"));
$num_networks = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('domain_id') AS num FROM domains WHERE domain_archived_at IS NULL"));
$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"));
$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"));
$num_software = $row['num'];
?>
<!-- Main Sidebar Container --> <!-- Main Sidebar Container -->
<aside class="main-sidebar sidebar-dark-primary d-print-none"> <aside class="main-sidebar sidebar-dark-primary d-print-none">
@@ -19,55 +51,109 @@
<li class="nav-item"> <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"; } ?>"> <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> <i class="nav-icon fas fa-address-book"></i>
<p>Contacts</p> <p>
Contacts
<?php
if ($num_contacts > 0) { ?>
<span class="right badge text-light"><?php echo $num_contacts; ?></span>
<?php } ?>
</p>
</a> </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="locations.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "locations.php") { echo "active"; } ?>"> <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> <i class="nav-icon fas fa-map-marker-alt"></i>
<p>Locations</p> <p>
Locations
<?php
if ($num_locations > 0) { ?>
<span class="right badge text-light"><?php echo $num_locations; ?></span>
<?php } ?>
</p>
</a> </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="assets.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "assets.php") { echo "active"; } ?>"> <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> <i class="nav-icon fas fa-desktop"></i>
<p>Assets</p> <p>
Assets
<?php
if ($num_assets > 0) { ?>
<span class="right badge text-light"><?php echo $num_assets; ?></span>
<?php } ?>
</p>
</a> </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="software.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "software.php") { echo "active"; } ?>"> <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> <i class="nav-icon fas fa-cube"></i>
<p>Licenses</p> <p>
Licenses
<?php
if ($num_software > 0) { ?>
<span class="right badge text-light"><?php echo $num_software; ?></span>
<?php } ?>
</p>
</a> </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="credentials.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "credentials.php") { echo "active"; } ?>"> <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> <i class="nav-icon fas fa-key"></i>
<p>Credentials</p> <p>
Credentials
<?php
if ($num_credentials > 0) { ?>
<span class="right badge text-light"><?php echo $num_credentials; ?></span>
<?php } ?>
</p>
</a> </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="networks.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "networks.php") { echo "active"; } ?>"> <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> <i class="nav-icon fas fa-network-wired"></i>
<p>Networks</p> <p>
Networks
<?php
if ($num_networks > 0) { ?>
<span class="right badge text-light"><?php echo $num_networks; ?></span>
<?php } ?>
</p>
</a> </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="certificates.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "certificates.php") { echo "active"; } ?>"> <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> <i class="nav-icon fas fa-lock"></i>
<p>Certificates</p> <p>
Certificates
<?php
if ($num_certificates > 0) { ?>
<span class="right badge text-light"><?php echo $num_certificates; ?></span>
<?php } ?>
</p>
</a> </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="domains.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "domains.php") { echo "active"; } ?>"> <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> <i class="nav-icon fas fa-globe"></i>
<p>Domains</p> <p>
Domains
<?php
if ($num_domains > 0) { ?>
<span class="right badge text-light"><?php echo $num_domains; ?></span>
<?php } ?>
</p>
</a> </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="services.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "services.php") { echo "active"; } ?>"> <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> <i class="nav-icon fas fa-stream"></i>
<p>Services</p> <p>
Services
<?php
if ($num_services > 0) { ?>
<span class="right badge text-light"><?php echo $num_services; ?></span>
<?php } ?>
</p>
</a> </a>
</li> </li>
<?php } ?> <?php } ?>

View File

@@ -1,5 +1,5 @@
<!-- Main Sidebar Container --> <!-- Main Sidebar Container -->
<aside class="main-sidebar sidebar-dark-<?php echo nullable_htmlentities($config_theme); ?> d-print-none"> <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"> <a class="brand-link pb-1 mt-1" href="clients.php">
<p class="h5"> <p class="h5">

View File

@@ -5,4 +5,4 @@
* It is used in conjunction with database_updates.php * It is used in conjunction with database_updates.php
*/ */
DEFINE("LATEST_DATABASE_VERSION", "2.1.4"); DEFINE("LATEST_DATABASE_VERSION", "2.1.9");

View File

@@ -14,7 +14,7 @@ if (str_contains(basename($_SERVER["PHP_SELF"]), "admin_")) { ?>
</div> <!-- ./wrapper --> </div> <!-- ./wrapper -->
<!-- Set the browser window title to the clients name --> <!-- Set the browser window title to the clients name -->
<script>document.title = "<?php echo "$tab_title - $page_title"; ?>"</script> <script>document.title = <?php echo json_encode("$tab_title - $page_title"); ?>;</script>
<!-- REQUIRED SCRIPTS --> <!-- REQUIRED SCRIPTS -->

View File

@@ -47,6 +47,7 @@ $config_invoice_from_email = $row['config_invoice_from_email'];
$config_invoice_late_fee_enable = intval($row['config_invoice_late_fee_enable']); $config_invoice_late_fee_enable = intval($row['config_invoice_late_fee_enable']);
$config_invoice_late_fee_percent = floatval($row['config_invoice_late_fee_percent']); $config_invoice_late_fee_percent = floatval($row['config_invoice_late_fee_percent']);
$config_invoice_paid_notification_email = $row['config_invoice_paid_notification_email']; $config_invoice_paid_notification_email = $row['config_invoice_paid_notification_email'];
$config_invoice_show_tax_id = intval($row['config_invoice_show_tax_id']);
// Recurring Invoices // Recurring Invoices
$config_recurring_invoice_prefix = $row['config_recurring_invoice_prefix']; $config_recurring_invoice_prefix = $row['config_recurring_invoice_prefix'];
@@ -78,6 +79,7 @@ $config_ticket_default_billable = intval($row['config_ticket_default_billable'])
$config_ticket_default_view = intval($row['config_ticket_default_view']); $config_ticket_default_view = intval($row['config_ticket_default_view']);
$config_ticket_moving_columns = intval($row['config_ticket_moving_columns']); $config_ticket_moving_columns = intval($row['config_ticket_moving_columns']);
$config_ticket_ordering = intval($row['config_ticket_ordering']); $config_ticket_ordering = intval($row['config_ticket_ordering']);
$config_ticket_timer_autostart = intval($row['config_ticket_timer_autostart']);
// Cron // Cron
$config_enable_cron = intval($row['config_enable_cron']); $config_enable_cron = intval($row['config_enable_cron']);

View File

@@ -48,5 +48,5 @@ header("X-Frame-Options: DENY");
<script src="plugins/toastr/toastr.min.js"></script> <script src="plugins/toastr/toastr.min.js"></script>
</head> </head>
<body class="hold-transition sidebar-mini layout-fixed layout-navbar-fixed accent-<?php echo nullable_htmlentities($config_theme); ?>"> <body class="hold-transition sidebar-mini layout-fixed layout-navbar-fixed accent-<?php if (isset($_GET['client_id'])) { echo "blue"; } else { echo nullable_htmlentities($config_theme); } ?>">
<div class="wrapper text-sm"> <div class="wrapper text-sm">

View File

@@ -105,7 +105,7 @@ if (isset($_GET['client_id'])) {
$client_tags_display = implode('', $client_tag_name_display_array); $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 //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 NOT LIKE 'Draft' AND invoice_status NOT LIKE 'Cancelled'"); $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); $row = mysqli_fetch_array($sql_invoice_amounts);
$invoice_amounts = floatval($row['invoice_amounts']); $invoice_amounts = floatval($row['invoice_amounts']);
@@ -158,7 +158,7 @@ if (isset($_GET['client_id'])) {
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('service_id') AS num FROM services WHERE service_client_id = $client_id")); $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']; $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 AND vendor_template = 0")); $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']; $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")); $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"));

View File

@@ -90,22 +90,20 @@
if (!empty($contact_name)) { ?> if (!empty($contact_name)) { ?>
<div> <div>
<i class="fa fa-fw fa-user text-secondary ml-1 mr-2"></i> <?php echo $contact_name; ?> <i class="fa fa-fw fa-user text-secondary ml-1 mr-2"></i><?php echo $contact_name; ?>
</div> </div>
<?php } <?php }
if (!empty($contact_email)) { ?> if (!empty($contact_email)) { ?>
<div class="mt-1"> <div class="mt-1">
<i class="fa fa-fw fa-envelope text-secondary ml-1 mr-2"></i> <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>
<a href="mailto:<?php echo $contact_email; ?>"> <?php echo $contact_email; ?></a>
</div> </div>
<?php <?php
} }
if (!empty($contact_phone)) { ?> if (!empty($contact_phone)) { ?>
<div class="mt-1"> <div class="mt-1">
<i class="fa fa-fw fa-phone text-secondary ml-1 mr-2"></i> <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>
<a href="tel:<?php echo $contact_phone; ?>"><?php echo $contact_phone; ?></a>
<?php <?php
if (!empty($contact_extension)) { if (!empty($contact_extension)) {
@@ -118,8 +116,7 @@
if (!empty($contact_mobile)) { ?> if (!empty($contact_mobile)) { ?>
<div class="mt-1"> <div class="mt-1">
<i class="fa fa-fw fa-mobile-alt text-secondary ml-1 mr-2"></i> <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>
<a href="tel:<?php echo $contact_mobile; ?>"><?php echo $contact_mobile; ?></a>
</div> </div>
<?php } ?> <?php } ?>

View File

@@ -211,7 +211,7 @@
while ($row = mysqli_fetch_array($sql_custom_links)) { while ($row = mysqli_fetch_array($sql_custom_links)) {
$custom_link_name = nullable_htmlentities($row['custom_link_name']); $custom_link_name = nullable_htmlentities($row['custom_link_name']);
$custom_link_uri = nullable_htmlentities($row['custom_link_uri']); $custom_link_uri = sanitize_url($row['custom_link_uri']);
$custom_link_icon = nullable_htmlentities($row['custom_link_icon']); $custom_link_icon = nullable_htmlentities($row['custom_link_icon']);
$custom_link_new_tab = intval($row['custom_link_new_tab']); $custom_link_new_tab = intval($row['custom_link_new_tab']);
if ($custom_link_new_tab == 1) { if ($custom_link_new_tab == 1) {

View File

@@ -1,5 +1,5 @@
<!-- Navbar --> <!-- Navbar -->
<nav class="main-header navbar navbar-expand navbar-<?php echo nullable_htmlentities($config_theme); ?> navbar-dark"> <nav class="main-header navbar navbar-expand navbar-<?php if (isset($_GET['client_id'])) { echo "gray"; } else { echo nullable_htmlentities($config_theme); } ?> navbar-dark">
<!-- Left navbar links --> <!-- Left navbar links -->
<ul class="navbar-nav"> <ul class="navbar-nav">
@@ -36,7 +36,7 @@
while ($row = mysqli_fetch_array($sql_custom_links)) { while ($row = mysqli_fetch_array($sql_custom_links)) {
$custom_link_name = nullable_htmlentities($row['custom_link_name']); $custom_link_name = nullable_htmlentities($row['custom_link_name']);
$custom_link_uri = nullable_htmlentities($row['custom_link_uri']); $custom_link_uri = sanitize_url($row['custom_link_uri']);
$custom_link_icon = nullable_htmlentities($row['custom_link_icon']); $custom_link_icon = nullable_htmlentities($row['custom_link_icon']);
$custom_link_new_tab = intval($row['custom_link_new_tab']); $custom_link_new_tab = intval($row['custom_link_new_tab']);
if ($custom_link_new_tab == 1) { if ($custom_link_new_tab == 1) {

View File

@@ -26,7 +26,12 @@ if (isset($_GET['invoice_id'])) {
); );
if (mysqli_num_rows($sql) == 0) { if (mysqli_num_rows($sql) == 0) {
echo '<h1 class="text-secondary mt-5" style="text-align: center">Nothing to see here</h1>'; 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"; require_once "includes/footer.php";
exit(); exit();
@@ -84,10 +89,14 @@ if (isset($_GET['invoice_id'])) {
$company_phone = nullable_htmlentities(formatPhoneNumber($row['company_phone'], $company_phone_country_code)); $company_phone = nullable_htmlentities(formatPhoneNumber($row['company_phone'], $company_phone_country_code));
$company_email = nullable_htmlentities($row['company_email']); $company_email = nullable_htmlentities($row['company_email']);
$company_website = nullable_htmlentities($row['company_website']); $company_website = nullable_htmlentities($row['company_website']);
$company_logo = nullable_htmlentities($row['company_logo']); $company_tax_id = nullable_htmlentities($row['company_tax_id']);
if (!empty($company_logo)) { if ($config_invoice_show_tax_id && !empty($company_tax_id)) {
$company_logo_base64 = base64_encode(file_get_contents("uploads/settings/$company_logo")); $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_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_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");
@@ -134,7 +143,7 @@ if (isset($_GET['invoice_id'])) {
$balance = $invoice_amount - $amount_paid; $balance = $invoice_amount - $amount_paid;
//check to see if overdue //check to see if overdue
if ($invoice_status !== "Paid" && $invoice_status !== "Draft" && $invoice_status !== "Cancelled") { if ($invoice_status !== "Paid" && $invoice_status !== "Draft" && $invoice_status !== "Cancelled" && $invoice_status !== "Non-Billable") {
$unixtime_invoice_due = strtotime($invoice_due) + 86400; $unixtime_invoice_due = strtotime($invoice_due) + 86400;
if ($unixtime_invoice_due < time()) { if ($unixtime_invoice_due < time()) {
$invoice_overdue = "Overdue"; $invoice_overdue = "Overdue";
@@ -191,176 +200,183 @@ if (isset($_GET['invoice_id'])) {
<div class="card"> <div class="card">
<div class="card-header d-print-none"> <div class="card-header d-print-none">
<div class="row">
<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) { ?>
<a class="btn btn-success" href="#"
data-toggle = "ajax-modal"
data-ajax-url = "ajax/ajax_invoice_pay.php"
data-ajax-id = "<?php echo $invoice_id; ?>"
>
<i class="fa fa-fw fa-credit-card mr-2"></i>Add Payment
</a>
<?php if ($invoice_status !== 'Partial' && $config_stripe_enable && $stripe_id && $stripe_pm) { ?>
<a class="btn btn-primary 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>
<?php } ?>
<?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 } ?>
<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 } ?> <?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> </div>
<?php if ($invoice_status !== 'Paid' && $invoice_status !== 'Cancelled' && $invoice_status !== 'Draft' && $invoice_amount != 0) { ?> <div class="col-4">
<a class="btn btn-success" href="#" data-toggle="modal" data-target="#addPaymentModal">
<i class="fa fa-fw fa-credit-card mr-2"></i>Add Payment
</a>
<?php if ($invoice_status !== 'Partial' && $config_stripe_enable && $stripe_id && $stripe_pm) { ?>
<a class="btn btn-primary 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>
<?php } ?>
<?php } ?>
<?php if (($invoice_status == 'Sent' || $invoice_status == 'Viewed') && $invoice_amount == 0 && $invoice_status !== 'Non-Billable') { ?> <div class="dropdown dropleft text-center float-right">
<a class="btn btn-dark" href="post.php?mark_invoice_non-billable=<?php echo $invoice_id; ?>"> <button class="btn btn-secondary" type="button" data-toggle="dropdown">
Mark Non-Billable <i class="fas fa-ellipsis-v"></i>
</a> </button>
<?php } ?> <div class="dropdown-menu">
<?php } // End lookup Perm ?> <a class="dropdown-item" href="#"
</div> data-toggle = "ajax-modal"
data-ajax-url = "ajax/ajax_invoice_edit.php"
<div class="col-4"> data-ajax-id = "<?php echo $invoice_id; ?>"
>
<div class="dropdown dropleft text-center float-right"> <i class="fa fa-fw fa-edit text-secondary mr-2"></i>Edit
<button class="btn btn-secondary" type="button" data-toggle="dropdown"> </a>
<i class="fas fa-ellipsis-v"></i> <a class="dropdown-item" href="#"
</button> data-toggle = "ajax-modal"
<div class="dropdown-menu"> data-ajax-url = "ajax/ajax_invoice_copy.php"
<a class="dropdown-item" href="#" data-ajax-id = "<?php echo $invoice_id; ?>"
data-toggle = "ajax-modal" >
data-ajax-url = "ajax/ajax_invoice_edit.php" <i class="fa fa-fw fa-copy text-secondary mr-2"></i>Copy
data-ajax-id = "<?php echo $invoice_id; ?>" </a>
> <a class="dropdown-item" href="#" data-toggle="modal" data-target="#addInvoiceRecurringModal<?php echo $invoice_id; ?>">
<i class="fa fa-fw fa-edit text-secondary mr-2"></i>Edit <i class="fa fa-fw fa-sync-alt text-secondary mr-2"></i>Recurring
</a>
<a class="dropdown-item" href="#"
data-toggle = "ajax-modal"
data-ajax-url = "ajax/ajax_invoice_copy.php"
data-ajax-id = "<?php echo $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="#" onclick="pdfMake.createPdf(docDefinition).download('<?php echo strtoAZaz09(html_entity_decode("$invoice_date-$company_name-$client_name-Invoice-$invoice_prefix$invoice_number")); ?>');">
<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> </a>
<?php } ?>
<a class="dropdown-item" target="_blank" href="guest/guest_view_invoice.php?invoice_id=<?php echo "$invoice_id&url_key=$invoice_url_key"; ?>">
<i class="fa fa-fw fa-link text-secondary mr-2"></i>Guest URL
</a>
<?php if ($invoice_status !== 'Cancelled' && $invoice_status !== 'Paid') { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?cancel_invoice=<?php echo $invoice_id; ?>"> <a class="dropdown-item" href="#" onclick="window.print();">
<i class="fa fa-fw fa-times mr-2"></i>Cancel <i class="fa fa-fw fa-print text-secondary mr-2"></i>Print
</a> </a>
<?php } ?> <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" target="_blank" href="guest/guest_view_invoice.php?invoice_id=<?php echo "$invoice_id&url_key=$invoice_url_key"; ?>">
<i class="fa fa-fw fa-link text-secondary mr-2"></i>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> </div>
</div> </div>
<?php } ?>
</div>
<div class="card-body"> <div class="card-body">
<div class="row mb-4"> <div class="row mb-3">
<?php if (file_exists("uploads/settings/$company_logo")) { ?>
<div class="col-sm-2"> <div class="col-sm-2">
<img class="img-fluid" src="<?php echo "uploads/settings/$company_logo"; ?>" alt="Company logo"> <img class="img-fluid" src="<?php echo "uploads/settings/$company_logo"; ?>" alt="Company logo">
</div> </div>
<div class="col-sm-10"> <?php } ?>
<div class="ribbon-wrapper"> <div class="col-sm-6 <?php if (!file_exists("uploads/settings/$company_logo")) { echo "col-sm-8"; } ?>">
<div class="ribbon bg-<?php echo $invoice_badge_color; ?>">
<?php echo "$invoice_status"; ?>
</div>
</div>
<h3 class="text-right mt-5"><strong>Invoice</strong><br><small class="text-secondary"><?php echo "$invoice_prefix$invoice_number"; ?></small></h3>
</div>
</div>
<div class="row mb-4">
<div class="col">
<ul class="list-unstyled"> <ul class="list-unstyled">
<li><h4><strong><?php echo $company_name; ?></strong></h4></li> <li><h4><strong><?php echo $company_name; ?></strong></h4></li>
<li><?php echo $company_address; ?></li> <li><?php echo $company_address; ?></li>
<li><?php echo "$company_city $company_state $company_zip"; ?></li> <li><?php echo "$company_city $company_state $company_zip, $company_country"; ?></li>
<li><small><?php echo $company_country; ?></small></li> <li><?php echo "$company_email | $company_phone"; ?></li>
<li><?php echo $company_phone; ?></li>
<li><?php echo $company_email; ?></li>
<li><?php echo $company_website; ?></li> <li><?php echo $company_website; ?></li>
<?php if ($company_tax_id_display) { ?>
<li><?php echo $company_tax_id_display; ?></li>
<?php } ?>
</ul> </ul>
</div> </div>
<div class="col">
<ul class="list-unstyled text-right">
<li><h4><strong><?php echo $client_name; ?></strong></h4></li>
<li><?php echo $location_address; ?></li>
<li><?php echo "$location_city $location_state $location_zip"; ?></li>
<li><small><?php echo $location_country; ?></small></li>
<li><?php echo "$contact_phone $contact_extension"; ?></li>
<li><?php echo $contact_mobile; ?></li>
<li><?php echo $contact_email; ?></li>
</ul>
</div>
</div>
<div class="row mb-4">
<div class="col-sm-8">
</div>
<div class="col-sm-4"> <div class="col-sm-4">
<table class="table"> <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> <tr>
<td>Date</td> <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> <td class="text-right"><?php echo $invoice_date; ?></td>
</tr> </tr>
<tr class="text-bold"> <tr>
<td>Due</td> <th>Due:</th>
<td class="text-right"><?php echo $invoice_due; ?></td> <td class="text-right"><?php echo $invoice_due; ?></td>
</tr> </tr>
</table> </table>
</div> </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> </div>
<?php $sql_invoice_items = mysqli_query($mysqli, "SELECT * FROM invoice_items WHERE item_invoice_id = $invoice_id ORDER BY item_order ASC"); ?> <?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-4"> <div class="row mb-3">
<div class="col-md-12"> <div class="col-md-12">
<div class="card"> <div class="card">
<div class="table-responsive"> <div class="table-responsive">
<table class="table" id="items"> <table class="table table-borderless" id="items">
<thead> <thead class="bg-light">
<tr> <tr>
<th class="d-print-none"></th> <th class="d-print-none"></th>
<th>Item</th> <th>Item</th>
<th>Description</th> <th>Description</th>
<th class="text-center">Quantity</th> <th class="text-center">Qty</th>
<th class="text-right">Price</th> <th class="text-right">Unit Price</th>
<th class="text-right">Tax</th> <th class="text-right">Tax</th>
<th class="text-right">Total</th> <th class="text-right">Amount</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -433,7 +449,7 @@ if (isset($_GET['invoice_id'])) {
<textarea class="form-control" rows="2" id="desc" name="description" placeholder="Enter a Description"></textarea> <textarea class="form-control" rows="2" id="desc" name="description" placeholder="Enter a Description"></textarea>
</td> </td>
<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="Quantity"> <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>
<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; ?>)"> <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; ?>)">
@@ -467,11 +483,11 @@ if (isset($_GET['invoice_id'])) {
</div> </div>
</div> </div>
</div> </div>
<div class="row mb-4"> <div class="row mb-3">
<div class="col-sm-7"> <div class="col-sm-7">
<div class="card"> <div class="card">
<div class="card-header text-bold"> <div class="card-header text-bold">
Notes Notes:
<div class="card-tools d-print-none"> <div class="card-tools d-print-none">
<a href="#" class="btn btn-light btn-tool" data-toggle="modal" data-target="#invoiceNoteModal"> <a href="#" class="btn btn-light btn-tool" data-toggle="modal" data-target="#invoiceNoteModal">
<i class="fas fa-edit"></i> <i class="fas fa-edit"></i>
@@ -487,48 +503,48 @@ if (isset($_GET['invoice_id'])) {
<table class="table table-borderless"> <table class="table table-borderless">
<tbody> <tbody>
<tr class="border-bottom"> <tr>
<td>Subtotal</td> <td>Subtotal:</td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $sub_total, $invoice_currency_code); ?></td> <td class="text-right"><?php echo numfmt_format_currency($currency_format, $sub_total, $invoice_currency_code); ?></td>
</tr> </tr>
<?php <?php
if ($invoice_discount > 0) { if ($invoice_discount > 0) {
?> ?>
<tr class="border-bottom"> <tr>
<td>Discount</td> <td>Discount:</td>
<td class="text-right">-<?php echo numfmt_format_currency($currency_format, $invoice_discount, $invoice_currency_code); ?></td> <td class="text-right">-<?php echo numfmt_format_currency($currency_format, $invoice_discount, $invoice_currency_code); ?></td>
</tr> </tr>
<?php <?php
} }
?> ?>
<?php if ($total_tax > 0) { ?> <?php if ($total_tax > 0) { ?>
<tr class="border-bottom"> <tr>
<td>Tax</td> <td>Tax:</td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $total_tax, $invoice_currency_code); ?></td> <td class="text-right"><?php echo numfmt_format_currency($currency_format, $total_tax, $invoice_currency_code); ?></td>
</tr> </tr>
<?php } ?> <?php } ?>
<tr class="border-bottom"> <tr>
<td>Total</td> <td>Total:</td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $invoice_amount, $invoice_currency_code); ?></td> <td class="text-right"><?php echo numfmt_format_currency($currency_format, $invoice_amount, $invoice_currency_code); ?></td>
</tr> </tr>
<?php <?php
if ($amount_paid > 0) { ?> if ($amount_paid > 0) { ?>
<tr class="border-bottom"> <tr>
<td><div class="text-success">Paid</div></td> <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> <td class="text-right text-success"><?php echo numfmt_format_currency($currency_format, $amount_paid, $invoice_currency_code); ?></td>
</tr> </tr>
<?php } ?> <?php } ?>
<tr class="border-bottom"> <tr class="h5 text-bold border-top">
<td><strong>Balance</strong></td> <td>Balance:</td>
<td class="text-right"><strong><?php echo numfmt_format_currency($currency_format, $balance, $invoice_currency_code); ?></strong></td> <td class="text-right"><?php echo numfmt_format_currency($currency_format, $balance, $invoice_currency_code); ?></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
<hr class="d-none d-print-block mt-5"> <hr class="d-none d-print-block mt-5">
<div class="d-none d-print-block text-center"><?php echo nl2br(nullable_htmlentities($config_invoice_footer)); ?></div> <div class="d-none d-print-block text-center text-secondary"><?php echo nl2br(nullable_htmlentities($config_invoice_footer)); ?></div>
</div> </div>
</div> </div>
<div class="row d-print-none mb-3"> <div class="row d-print-none mb-3">
@@ -577,7 +593,7 @@ if (isset($_GET['invoice_id'])) {
</div> </div>
</div> </div>
</div> </div>
<div class="col-sm d-print-none"> <div class="col-sm d-print-none <?php if (mysqli_num_rows($sql_payments) == 0) { echo "d-none"; } ?>">
<div class="card"> <div class="card">
<div class="card-header text-bold"> <div class="card-header text-bold">
<i class="fa fa-credit-card mr-2"></i>Payments <i class="fa fa-credit-card mr-2"></i>Payments
@@ -593,7 +609,7 @@ if (isset($_GET['invoice_id'])) {
<div class="card-body"> <div class="card-body">
<div class="table-responsive"> <div class="table-responsive">
<table class="table"> <table class="table">
<thead class="<?php if (mysqli_num_rows($sql_payments) == 0) { echo "d-none"; } ?>"> <thead>
<tr> <tr>
<th>Date</th> <th>Date</th>
<th class="text-right">Amount</th> <th class="text-right">Amount</th>
@@ -630,7 +646,7 @@ if (isset($_GET['invoice_id'])) {
</div> </div>
</div> </div>
</div> </div>
<div class="col-sm d-print-none"> <div class="col-sm d-print-none <?php if (mysqli_num_rows($sql_tickets) == 0) { echo "d-none"; } ?>">
<div class="card"> <div class="card">
<div class="card-header text-bold"> <div class="card-header text-bold">
<i class="fa fa-life-ring mr-2"></i>Tickets <i class="fa fa-life-ring mr-2"></i>Tickets
@@ -659,7 +675,7 @@ if (isset($_GET['invoice_id'])) {
<div class="card-body"> <div class="card-body">
<div class="table-responsive"> <div class="table-responsive">
<table class="table"> <table class="table">
<thead class="<?php if (mysqli_num_rows($sql_tickets) == 0) { echo "d-none"; } ?>"> <thead>
<tr> <tr>
<th>Date</th> <th>Date</th>
<th>Subject</th> <th>Subject</th>
@@ -689,9 +705,9 @@ if (isset($_GET['invoice_id'])) {
</div> </div>
</div> </div>
</div> </div>
</div>
<?php <?php
include_once "modals/invoice_add_ticket_modal.php"; include_once "modals/invoice_add_ticket_modal.php";
include_once "modals/invoice_payment_add_modal.php";
include_once "modals/invoice_recurring_add_modal.php"; include_once "modals/invoice_recurring_add_modal.php";
include_once "modals/invoice_note_modal.php"; include_once "modals/invoice_note_modal.php";
@@ -722,473 +738,6 @@ require_once "includes/footer.php";
}); });
</script> </script>
<script src='plugins/pdfmake/pdfmake.min.js'></script>
<script src='plugins/pdfmake/vfs_fonts.js'></script>
<script>
var docDefinition = {
info: {
title: <?php echo json_encode(html_entity_decode($company_name) . "- Invoice") ?>,
author: <?php echo json_encode(html_entity_decode($company_name)) ?>
},
//watermark: {text: '<?php echo $invoice_status; ?>', color: 'lightgrey', opacity: 0.3, bold: true, italics: false},
content: [
// Header
{
columns: [
<?php if (!empty($company_logo_base64)) { ?>
{
image: <?php echo json_encode("data:image;base64,$company_logo_base64") ?>,
width: 120
},
<?php } ?>
[
{
text: 'Invoice',
style: 'invoiceTitle',
width: '*'
},
{
text: <?php echo json_encode(html_entity_decode("$invoice_prefix$invoice_number")) ?>,
style: 'invoiceNumber',
width: '*'
},
<?php if ($invoice_status == "Paid") { ?>
{
text: 'PAID',
style: 'invoicePaid',
width: '*'
},
<?php } ?>
],
],
},
// Billing Headers
{
columns: [
{
text: <?php echo json_encode(html_entity_decode($company_name)) ?>,
style: 'invoiceBillingTitle',
},
{
text: <?php echo json_encode(html_entity_decode($client_name)) ?>,
style: 'invoiceBillingTitleClient',
},
]
},
// Billing Address
{
columns: [
{
text: <?php echo json_encode(html_entity_decode("$company_address \n $company_city $company_state $company_zip \n $company_country \n $company_phone \n $company_website")) ?>,
style: 'invoiceBillingAddress'
},
{
text: <?php echo json_encode(html_entity_decode("$location_address \n $location_city $location_state $location_zip \n $location_country \n $contact_email \n $contact_phone")) ?>,
style: 'invoiceBillingAddressClient'
},
]
},
//Invoice Dates Table
{
table: {
// headers are automatically repeated if the table spans over multiple pages
// you can declare how many rows should be treated as headers
headerRows: 0,
widths: [ '*',80, 80 ],
body: [
// Total
[
{
text: '',
rowSpan: 3
},
{},
{},
],
[
{},
{
text: 'Date',
style: 'invoiceDateTitle'
},
{
text: <?php echo json_encode($invoice_date) ?>,
style: 'invoiceDateValue'
},
],
[
{},
{
text: 'Due',
style: 'invoiceDueDateTitle'
},
{
text: <?php echo json_encode($invoice_due) ?>,
style: 'invoiceDueDateValue'
},
],
]
}, // table
layout: 'lightHorizontalLines'
},
// Line breaks
'\n\n',
// Items
{
table: {
// headers are automatically repeated if the table spans over multiple pages
// you can declare how many rows should be treated as headers
headerRows: 1,
widths: [ '*', 40, 'auto', 'auto', 80 ],
body: [
// Table Header
[
{
text: 'Product',
style: [ 'itemsHeader', 'left']
},
{
text: 'Qty',
style: [ 'itemsHeader', 'center']
},
{
text: 'Price',
style: [ 'itemsHeader', 'right']
},
{
text: 'Tax',
style: [ 'itemsHeader', 'right']
},
{
text: 'Total',
style: [ 'itemsHeader', 'right']
}
],
// Items
<?php
$total_tax = 0.00;
$sub_total = 0.00;
$sql_invoice_items = mysqli_query($mysqli, "SELECT * FROM invoice_items WHERE item_invoice_id = $invoice_id ORDER BY item_order ASC");
while ($row = mysqli_fetch_array($sql_invoice_items)) {
$item_name = $row['item_name'];
$item_description = $row['item_description'];
$item_quantity = $row['item_quantity'];
$item_price = $row['item_price'];
$item_subtotal = $row['item_price'];
$item_tax = $row['item_tax'];
$item_total = $row['item_total'];
$tax_id = $row['item_tax_id'];
$total_tax = $item_tax + $total_tax;
$sub_total = $item_price * $item_quantity + $sub_total;
?>
// Item
[
[
{
text: <?php echo json_encode($item_name) ?>,
style: 'itemTitle'
},
{
text: <?php echo json_encode($item_description) ?>,
style: 'itemDescription'
}
],
{
text: <?php echo json_encode($item_quantity) ?>,
style: 'itemQty'
},
{
text: <?php echo json_encode(numfmt_format_currency($currency_format, $item_price, $invoice_currency_code)) ?>,
style: 'itemNumber'
},
{
text: <?php echo json_encode(numfmt_format_currency($currency_format, $item_tax, $invoice_currency_code)) ?>,
style: 'itemNumber'
},
{
text: <?php echo json_encode(numfmt_format_currency($currency_format, $item_total, $invoice_currency_code)) ?>,
style: 'itemNumber'
}
],
<?php
}
?>
// END Items
]
}, // table
layout: 'lightHorizontalLines'
},
// TOTAL
{
table: {
// headers are automatically repeated if the table spans over multiple pages
// you can declare how many rows should be treated as headers
headerRows: 0,
widths: [ '*','auto', 80 ],
body: [
// Total
[
{
text: 'Notes',
style: 'notesTitle'
},
{},
{}
],
[
{
rowSpan: '*',
text: <?php echo json_encode(html_entity_decode($invoice_note)) ?>,
style: 'notesText'
},
{
text: 'Subtotal',
style: 'itemsFooterSubTitle'
},
{
text: <?php echo json_encode(numfmt_format_currency($currency_format, $sub_total, $invoice_currency_code)) ?>,
style: 'itemsFooterSubValue'
}
],
<?php if ($invoice_discount > 0) { ?>
[
{},
{
text: 'Discount',
style: 'itemsFooterSubTitle'
},
{
text: <?php echo json_encode(numfmt_format_currency($currency_format, -$invoice_discount, $invoice_currency_code)) ?>,
style: 'itemsFooterSubValue'
}
],
<?php } ?>
<?php if ($total_tax > 0) { ?>
[
{},
{
text: 'Tax',
style: 'itemsFooterSubTitle'
},
{
text: <?php echo json_encode(numfmt_format_currency($currency_format, $total_tax, $invoice_currency_code)) ?>,
style: 'itemsFooterSubValue'
}
],
<?php } ?>
[
{},
{
text: 'Total',
style: 'itemsFooterSubTitle'
},
{
text: <?php echo json_encode(numfmt_format_currency($currency_format, $invoice_amount, $invoice_currency_code)) ?>,
style: 'itemsFooterSubValue'
}
],
<?php if ($amount_paid > 0) { ?>
[
{},
{
text: 'Paid',
style: 'itemsFooterSubTitle'
},
{
text: <?php echo json_encode(numfmt_format_currency($currency_format, $amount_paid, $invoice_currency_code)) ?>,
style: 'itemsFooterSubValue'
}
],
<?php } ?>
[
{},
{
text: 'Balance',
style: 'itemsFooterTotalTitle'
},
{
text: <?php echo json_encode(numfmt_format_currency($currency_format, $balance, $invoice_currency_code)) ?>,
style: 'itemsFooterTotalValue'
}
],
]
}, // table
layout: 'lightHorizontalLines'
},
// TERMS / FOOTER
{
text: <?php echo json_encode($config_invoice_footer) ?>,
style: 'documentFooterCenter'
}
], //End Content,
styles: {
// Document Footer
documentFooterCenter: {
fontSize: 9,
margin: [10,50,10,10],
alignment: 'center',
},
// Invoice Title
invoiceTitle: {
fontSize: 18,
bold: true,
alignment: 'right',
margin: [0,0,0,3]
},
// Invoice Number
invoiceNumber: {
fontSize: 14,
alignment: 'right'
},
// Invoice Paid
invoicePaid: {
fontSize: 13,
bold: true,
margin: [0,5,0,0],
alignment: 'right',
color: 'green'
},
// Billing Headers
invoiceBillingTitle: {
fontSize: 14,
bold: true,
alignment: 'left',
margin: [0,20,0,5]
},
invoiceBillingTitleClient: {
fontSize: 14,
bold: true,
alignment: 'right',
margin: [0,20,0,5]
},
// Billing Details
invoiceBillingAddress: {
fontSize: 10,
lineHeight: 1.2
},
invoiceBillingAddressClient: {
fontSize: 10,
lineHeight: 1.2,
alignment: 'right',
margin: [0,0,0,30]
},
// Invoice Date
invoiceDateTitle: {
fontSize: 10,
alignment: 'left',
margin: [0,5,0,5]
},
invoiceDateValue: {
fontSize: 10,
alignment: 'right',
margin: [0,5,0,5]
},
// Invoice Due Date
invoiceDueDateTitle: {
fontSize: 10,
bold: true,
alignment: 'left',
margin: [0,5,0,5]
},
invoiceDueDateValue: {
fontSize: 10,
bold: true,
alignment: 'right',
margin: [0,5,0,5]
},
// Items Header
itemsHeader: {
fontSize: 10,
margin: [0,5,0,5],
bold: true,
alignment: 'right'
},
// Item Title
itemTitle: {
fontSize: 10,
bold: true,
margin: [0,5,0,3]
},
itemDescription: {
italics: true,
fontSize: 9,
lineHeight: 1.1,
margin: [0,3,0,5]
},
itemQty: {
fontSize: 10,
margin: [0,5,0,5],
alignment: 'center'
},
itemNumber: {
fontSize: 10,
margin: [0,5,0,5],
alignment: 'right'
},
itemTotal: {
fontSize: 10,
margin: [0,5,0,5],
bold: true,
alignment: 'right'
},
// Items Footer (Subtotal, Total, Tax, etc)
itemsFooterSubTitle: {
fontSize: 10,
margin: [0,5,0,5],
alignment:'right'
},
itemsFooterSubValue: {
fontSize: 10,
margin: [0,5,0,5],
bold: false,
alignment: 'right'
},
itemsFooterTotalTitle: {
fontSize: 10,
margin: [0,5,0,5],
bold: true,
alignment: 'right'
},
itemsFooterTotalValue: {
fontSize: 10,
margin: [0,5,0,5],
bold: true,
alignment: 'right'
},
notesTitle: {
fontSize: 10,
bold: true,
margin: [0,5,0,5]
},
notesText: {
fontSize: 9,
margin: [0,5,50,5]
},
left: {
alignment: 'left'
},
center: {
alignment: 'center'
},
},
defaultStyle: {
columnGap: 20
}
}
</script>
<script src="plugins/SortableJS/Sortable.min.js"></script> <script src="plugins/SortableJS/Sortable.min.js"></script>
<script> <script>
new Sortable(document.querySelector('table#items tbody'), { new Sortable(document.querySelector('table#items tbody'), {

View File

@@ -61,7 +61,7 @@ $sql_total_overdue_partial_amount = mysqli_query($mysqli, "SELECT SUM(payment_am
$row = mysqli_fetch_array($sql_total_overdue_partial_amount); $row = mysqli_fetch_array($sql_total_overdue_partial_amount);
$total_overdue_partial_amount = floatval($row['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 NOT LIKE 'Draft' AND invoice_status NOT LIKE 'Paid' AND invoice_status NOT LIKE 'Cancelled' AND invoice_due < CURDATE() $client_query"); $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); $row = mysqli_fetch_array($sql_total_overdue_amount);
$total_overdue_amount = floatval($row['total_overdue_amount']); $total_overdue_amount = floatval($row['total_overdue_amount']);
@@ -342,6 +342,22 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<i class="fas fa-ellipsis-h"></i> <i class="fas fa-ellipsis-h"></i>
</button> </button>
<div class="dropdown-menu"> <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" href="#"
data-toggle = "ajax-modal"
data-ajax-url = "ajax/ajax_invoice_pay.php"
data-ajax-id = "<?php echo $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" href="#" <a class="dropdown-item" href="#"
data-toggle = "ajax-modal" data-toggle = "ajax-modal"
data-ajax-url = "ajax/ajax_invoice_edit.php" data-ajax-url = "ajax/ajax_invoice_edit.php"
@@ -359,10 +375,16 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<?php if (!empty($config_smtp_host)) { ?> <?php if (!empty($config_smtp_host)) { ?>
<a class="dropdown-item" href="post.php?email_invoice=<?php echo $invoice_id; ?>"> <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 <i class="fas fa-fw fa-paper-plane mr-2"></i>Send Email
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<?php } ?> <?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; ?>"> <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 <i class="fas fa-fw fa-trash mr-2"></i>Delete
</a> </a>

View File

@@ -1,10 +1,7 @@
// Description: This file contains the JavaScript for the ticket time tracking feature
(function() { (function() {
document.addEventListener("DOMContentLoaded", function() { document.addEventListener("DOMContentLoaded", function() {
// Initialize variables // Initialize variables
var timerInterval = null; var timerInterval = null;
var isPaused = false;
var ticketID = getCurrentTicketID(); var ticketID = getCurrentTicketID();
var elapsedSecs = getElapsedSeconds(); var elapsedSecs = getElapsedSeconds();
@@ -51,10 +48,8 @@
localStorage.setItem(getLocalStorageKey("startTime"), Date.now().toString()); localStorage.setItem(getLocalStorageKey("startTime"), Date.now().toString());
} }
timerInterval = setInterval(countTime, 1000); timerInterval = setInterval(countTime, 1000);
isPaused = false;
document.getElementById("startStopTimer").innerHTML = "<i class='fas fa-pause'></i>"; document.getElementById("startStopTimer").innerHTML = "<i class='fas fa-pause'></i>";
localStorage.setItem("ticket-timer-running-" + ticketID, "true"); localStorage.setItem("ticket-timer-running-" + ticketID, "true");
} }
function pauseTimer() { function pauseTimer() {
@@ -65,10 +60,8 @@
let currentElapsed = getElapsedSeconds(); let currentElapsed = getElapsedSeconds();
localStorage.setItem(getLocalStorageKey("pausedTime"), currentElapsed.toString()); localStorage.setItem(getLocalStorageKey("pausedTime"), currentElapsed.toString());
localStorage.removeItem(getLocalStorageKey("startTime")); localStorage.removeItem(getLocalStorageKey("startTime"));
isPaused = true;
document.getElementById("startStopTimer").innerHTML = "<i class='fas fa-play'></i>"; document.getElementById("startStopTimer").innerHTML = "<i class='fas fa-play'></i>";
localStorage.setItem("ticket-timer-running-" + ticketID, "false"); localStorage.setItem("ticket-timer-running-" + ticketID, "false");
} }
function clearTimeStorage() { function clearTimeStorage() {
@@ -99,9 +92,7 @@
} }
function handleInputFocus() { function handleInputFocus() {
if (!isPaused) { pauseTimer();
pauseTimer();
}
} }
function updateTimeFromInput() { function updateTimeFromInput() {
@@ -110,7 +101,6 @@
const seconds = parseInt(document.getElementById("seconds").value, 10) || 0; const seconds = parseInt(document.getElementById("seconds").value, 10) || 0;
elapsedSecs = (hours * 3600) + (minutes * 60) + seconds; elapsedSecs = (hours * 3600) + (minutes * 60) + seconds;
// Update local storage so the manually entered time is retained even if the page is reloaded.
if (!timerInterval) { if (!timerInterval) {
localStorage.setItem(getLocalStorageKey("pausedTime"), elapsedSecs.toString()); localStorage.setItem(getLocalStorageKey("pausedTime"), elapsedSecs.toString());
} else { } else {
@@ -120,7 +110,6 @@
} }
} }
// Function to check status and pause timer
function checkStatusAndPauseTimer() { function checkStatusAndPauseTimer() {
var status = document.querySelector('select[name="status"]').value; var status = document.querySelector('select[name="status"]').value;
if (status.includes("Pending") || status.includes("Close")) { if (status.includes("Pending") || status.includes("Close")) {
@@ -128,6 +117,7 @@
} }
} }
// Attach input listeners
document.getElementById("hours").addEventListener('change', updateTimeFromInput); document.getElementById("hours").addEventListener('change', updateTimeFromInput);
document.getElementById("minutes").addEventListener('change', updateTimeFromInput); document.getElementById("minutes").addEventListener('change', updateTimeFromInput);
document.getElementById("seconds").addEventListener('change', updateTimeFromInput); document.getElementById("seconds").addEventListener('change', updateTimeFromInput);
@@ -151,25 +141,33 @@
}); });
document.getElementById("ticket_add_reply").addEventListener('click', function() { document.getElementById("ticket_add_reply").addEventListener('click', function() {
// Wait for other synchronous actions (if any) to complete before resetting the timer. setTimeout(forceResetTimer, 100);
setTimeout(forceResetTimer, 100); // 100ms delay should suffice, but you can adjust as needed.
}); });
document.getElementById("ticket_close").addEventListener('click', function() { document.getElementById("ticket_close").addEventListener('click', function() {
// Wait for other synchronous actions (if any) to complete before resetting the timer. setTimeout(clearTimeStorage, 100);
setTimeout(clearTimeStorage, 100); // 100ms delay should suffice, but you can adjust as needed.
}); });
// Final initialization logic
try { try {
displayTime(); displayTime();
// If no timer state, respect ticketAutoStart
if (!localStorage.getItem(getLocalStorageKey("startTime")) && !localStorage.getItem(getLocalStorageKey("pausedTime"))) { if (!localStorage.getItem(getLocalStorageKey("startTime")) && !localStorage.getItem(getLocalStorageKey("pausedTime"))) {
startTimer(); if (ticketAutoStart === 1) {
} else if (localStorage.getItem(getLocalStorageKey("startTime"))) { startTimer();
} else {
pauseTimer();
}
}
// If timer already running, resume it
else if (localStorage.getItem(getLocalStorageKey("startTime"))) {
startTimer(); startTimer();
} }
// Check and pause timer if status is pending // Check and pause timer if status is pending
checkStatusAndPauseTimer(); checkStatusAndPauseTimer();
} catch (error) { } catch (error) {
console.error("There was an issue initializing the timer:", error); console.error("There was an issue initializing the timer:", error);
} }

View File

@@ -9,6 +9,14 @@ if (isset($_GET['client_id'])) {
require_once "includes/inc_all_client.php"; require_once "includes/inc_all_client.php";
$client_query = "AND location_client_id = $client_id"; $client_query = "AND location_client_id = $client_id";
$client_url = "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 { } else {
require_once "includes/inc_client_overview_all.php"; require_once "includes/inc_client_overview_all.php";
$client_query = ''; $client_query = '';
@@ -25,6 +33,14 @@ if (!$client_url) {
$client_query = ''; $client_query = '';
$client = ''; $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 // Tags Filter
@@ -45,7 +61,7 @@ $sql = mysqli_query(
LEFT JOIN clients ON client_id = location_client_id LEFT JOIN clients ON client_id = location_client_id
LEFT JOIN location_tags ON location_tags.location_id = locations.location_id LEFT JOIN location_tags ON location_tags.location_id = locations.location_id
LEFT JOIN tags ON tags.tag_id = location_tags.tag_id LEFT JOIN tags ON tags.tag_id = location_tags.tag_id
WHERE location_$archive_query WHERE $archive_query
$tag_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%') 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 $access_permission_query

View File

@@ -337,7 +337,7 @@
<option value="">- Select Vendor -</option> <option value="">- Select Vendor -</option>
<?php <?php
$sql = mysqli_query($mysqli, "SELECT * FROM vendors WHERE vendor_archived_at IS NULL AND vendor_client_id = $client_id AND vendor_template = 0 ORDER BY vendor_name ASC"); $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)) { while ($row = mysqli_fetch_array($sql)) {
$vendor_id = intval($row['vendor_id']); $vendor_id = intval($row['vendor_id']);
$vendor_name = nullable_htmlentities($row['vendor_name']); $vendor_name = nullable_htmlentities($row['vendor_name']);

View File

@@ -14,13 +14,14 @@
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>"> <input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<?php } ?> <?php } ?>
<div class="modal-body bg-white"> <div class="modal-body bg-white">
<p><strong>Format csv file with headings & data:</strong><br>Name, Description, Type, Make, Model, Serial, OS, Assigned To, Location, Physical Location</p> <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> <hr>
<div class="form-group my-4"> <div class="form-group my-4">
<input type="file" class="form-control-file" name="file" accept=".csv" required> <input type="file" class="form-control-file" name="file" accept=".csv" required>
</div> </div>
<hr> <hr>
<div>Download <a href="post.php?download_assets_csv_template=<?php echo $client_id; ?>">sample csv template</a></div> <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>
<div class="modal-footer bg-white"> <div class="modal-footer bg-white">
<button type="submit" name="import_assets_csv" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Import</button> <button type="submit" name="import_assets_csv" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Import</button>

View File

@@ -20,10 +20,10 @@
<select class="form-control" name="document_template_id" required> <select class="form-control" name="document_template_id" required>
<option value="">- Select Template -</option> <option value="">- Select Template -</option>
<?php <?php
$sql_document_templates = mysqli_query($mysqli, "SELECT * FROM documents WHERE document_template = 1 AND document_archived_at IS NULL ORDER BY document_name ASC"); $sql_document_templates = mysqli_query($mysqli, "SELECT * FROM document_templates WHERE document_template_archived_at IS NULL ORDER BY document_template_name ASC");
while ($row = mysqli_fetch_array($sql_document_templates)) { while ($row = mysqli_fetch_array($sql_document_templates)) {
$document_template_id = intval($row['document_id']); $document_template_id = intval($row['document_template_id']);
$document_template_name = nullable_htmlentities($row['document_name']); $document_template_name = nullable_htmlentities($row['document_template_name']);
?> ?>
<option value="<?php echo $document_template_id ?>"><?php echo $document_template_name; ?></option> <option value="<?php echo $document_template_id ?>"><?php echo $document_template_name; ?></option>

View File

@@ -44,7 +44,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<input type="file" class="form-control-file" name="file[]" multiple id="fileInput" accept=".jpg, .jpeg, .gif, .png, .webp, .pdf, .txt, .md, .doc, .docx, .odt, .csv, .xls, .xlsx, .ods, .pptx, .odp, .zip, .tar, .gz, .xml, .msg, .json, .wav, .mp3, .ogg, .mov, .mp4, .av1, .ovpn, .cfg, .ps1, .vsdx, .drawio, .pfx, .unf, .key, .stk, .bat"> <input type="file" class="form-control-file" name="file[]" multiple id="fileInput" accept=".jpg, .jpeg, .gif, .png, .webp, .pdf, .txt, .md, .doc, .docx, .odt, .csv, .xls, .xlsx, .ods, .pptx, .odp, .zip, .tar, .gz, .msg, .json, .wav, .mp3, .ogg, .mov, .mp4, .av1, .ovpn, .cfg, .ps1, .vsdx, .drawio, .pfx, .unf, .key, .stk, .bat">
</div> </div>
<small class="text-secondary">Up to 20 files can be uploaded at once by holding down CTRL and selecting files</small> <small class="text-secondary">Up to 20 files can be uploaded at once by holding down CTRL and selecting files</small>

View File

@@ -83,7 +83,7 @@
<option value="">- Vendor -</option> <option value="">- Vendor -</option>
<?php <?php
$sql = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = 0 AND vendor_template = 0 AND vendor_archived_at IS NULL ORDER BY vendor_name ASC"); $sql = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = 0 AND vendor_archived_at IS NULL ORDER BY vendor_name ASC");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_array($sql)) {
$vendor_id = intval($row['vendor_id']); $vendor_id = intval($row['vendor_id']);
$vendor_name = nullable_htmlentities($row['vendor_name']); $vendor_name = nullable_htmlentities($row['vendor_name']);

View File

@@ -45,7 +45,7 @@
<option value="">- All Vendors -</option> <option value="">- All Vendors -</option>
<?php <?php
$sql_vendors_filter = mysqli_query($mysqli, "SELECT * FROM vendors WHERE vendor_client_id = 0 AND vendor_template = 0 ORDER BY vendor_name ASC"); $sql_vendors_filter = mysqli_query($mysqli, "SELECT * FROM vendors WHERE vendor_client_id = 0 ORDER BY vendor_name ASC");
while ($row = mysqli_fetch_array($sql_vendors_filter)) { while ($row = mysqli_fetch_array($sql_vendors_filter)) {
$vendor_id = intval($row['vendor_id']); $vendor_id = intval($row['vendor_id']);
$vendor_name = nullable_htmlentities($row['vendor_name']); $vendor_name = nullable_htmlentities($row['vendor_name']);

View File

@@ -1,146 +0,0 @@
<div class="modal" id="addPaymentModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content bg-dark">
<div class="modal-header">
<h5 class="modal-title"><i class="fa fa-fw fa-credit-card mr-2"></i><?php echo "$invoice_prefix$invoice_number"; ?>: Make Payment</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="invoice_id" value="<?php echo $invoice_id; ?>">
<input type="hidden" name="balance" value="<?php echo $balance; ?>">
<input type="hidden" name="currency_code" value="<?php echo $client_currency_code; ?>">
<div class="modal-body bg-white">
<div class="form-row">
<div class="col-md">
<div class="form-group">
<label>Date <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>
<input type="date" class="form-control" name="date" max="2999-12-31" value="<?php echo date("Y-m-d"); ?>" required>
</div>
</div>
</div>
<div class="col-md">
<div class="form-group">
<label>Amount <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="amount" value="<?php echo number_format($balance, 2, '.', ''); ?>" placeholder="0.00" required>
</div>
</div>
</div>
</div>
<div class="form-group">
<label>Account <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>
<select class="form-control select2" name="account" required>
<option value="">- Select an Account -</option>
<?php
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
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']);
$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']);
$account_balance = $opening_balance + $total_payments + $total_revenues - $total_expenses;
?>
<option <?php if ($config_default_payment_account == $account_id) { echo "selected"; } ?>
value="<?php echo $account_id; ?>">
<?php echo $account_name; ?> [$<?php echo number_format($account_balance, 2); ?>]
</option>
<?php
}
?>
</select>
</div>
</div>
<div class="form-group">
<label>Payment Method <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-check-alt"></i></span>
</div>
<select class="form-control select2" name="payment_method" required>
<option value="">- Method of Payment -</option>
<?php
$sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Payment Method' AND category_archived_at IS NULL ORDER BY category_name ASC");
while ($row = mysqli_fetch_array($sql)) {
$category_name = nullable_htmlentities($row['category_name']);
?>
<option <?php if ($config_default_payment_method == $category_name) {
echo "selected";
} ?>><?php echo $category_name; ?></option>
<?php
}
?>
</select>
</div>
</div>
<div class="form-group">
<label>Reference</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="reference" placeholder="Check #, Trans #, etc" maxlength="200">
</div>
</div>
<?php if (!empty($config_smtp_host) && !empty($contact_email)) { ?>
<div class="form-group">
<label>Email Receipt</label>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="customControlAutosizing" name="email_receipt" value="1" checked>
<label class="custom-control-label" for="customControlAutosizing"><?php echo $contact_email; ?></label>
</div>
</div>
<?php } ?>
</div>
<div class="modal-footer bg-white">
<button type="submit" name="add_payment" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Pay</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

@@ -125,7 +125,7 @@
<option value="">- Vendor -</option> <option value="">- Vendor -</option>
<?php <?php
$sql = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = 0 AND vendor_template = 0 AND vendor_archived_at IS NULL ORDER BY vendor_name ASC"); $sql = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = 0 AND vendor_archived_at IS NULL ORDER BY vendor_name ASC");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_array($sql)) {
$vendor_id = intval($row['vendor_id']); $vendor_id = intval($row['vendor_id']);
$vendor_name = nullable_htmlentities($row['vendor_name']); $vendor_name = nullable_htmlentities($row['vendor_name']);

View File

@@ -11,7 +11,7 @@
<input type="hidden" name="recurring_invoice_id" value="<?php echo $recurring_invoice_id; ?>"> <input type="hidden" name="recurring_invoice_id" value="<?php echo $recurring_invoice_id; ?>">
<div class="modal-body bg-white"> <div class="modal-body bg-white">
<div class="form-group"> <div class="form-group">
<textarea class="form-control" rows="8" name="note" placeholder="Enter some notes"><?php echo $recurring_note; ?></textarea> <textarea class="form-control" rows="8" name="note" placeholder="Enter some notes"><?php echo $recurring_invoice_note; ?></textarea>
</div> </div>
</div> </div>
<div class="modal-footer bg-white"> <div class="modal-footer bg-white">

View File

@@ -50,18 +50,56 @@
<textarea class="form-control tinymceTicket<?php if($config_ai_enable) { echo "AI"; } ?>" name="details"></textarea> <textarea class="form-control tinymceTicket<?php if($config_ai_enable) { echo "AI"; } ?>" name="details"></textarea>
</div> </div>
<div class="form-group"> <div class="row">
<label>Priority <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="col">
<div class="input-group-prepend"> <div class="form-group">
<span class="input-group-text"><i class="fa fa-fw fa-thermometer-half"></i></span> <label>Priority <strong class="text-danger">*</strong></label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-thermometer-half"></i></span>
</div>
<select class="form-control select2" name="priority" required>
<option>Low</option>
<option>Medium</option>
<option>High</option>
</select>
</div>
</div> </div>
<select class="form-control select2" name="priority" required>
<option>Low</option>
<option>Medium</option>
<option>High</option>
</select>
</div> </div>
<div class="col">
<div class="form-group">
<label>Category</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-layer-group"></i></span>
</div>
<select class="form-control select2" name="category">
<option value="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 ORDER BY category_name ASC");
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 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=Ticket">
<i class="fas fa-fw fa-plus"></i>
</button>
</div>
</div>
</div>
</div>
</div> </div>
<div class="form-group"> <div class="form-group">

View File

@@ -145,7 +145,7 @@
<label for="vendors">Select related vendors</label> <label for="vendors">Select related vendors</label>
<select class="form-control select2" id="vendors" name="vendors[]" multiple> <select class="form-control select2" id="vendors" name="vendors[]" multiple>
<?php <?php
$sql = mysqli_query($mysqli, "SELECT * FROM vendors WHERE vendor_template = 0 AND vendor_archived_at IS NULL AND vendor_client_id = $client_id"); $sql = mysqli_query($mysqli, "SELECT * FROM vendors WHERE vendor_archived_at IS NULL AND vendor_client_id = $client_id");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_array($sql)) {
$vendor_id = intval($row['vendor_id']); $vendor_id = intval($row['vendor_id']);
$vendor_name = nullable_htmlentities($row['vendor_name']); $vendor_name = nullable_htmlentities($row['vendor_name']);

View File

@@ -20,10 +20,10 @@
<select class="form-control" name="software_template_id" required> <select class="form-control" name="software_template_id" required>
<option value="">- Select Template -</option> <option value="">- Select Template -</option>
<?php <?php
$sql_software_templates = mysqli_query($mysqli, "SELECT * FROM software WHERE software_template = 1 AND software_archived_at IS NULL ORDER BY software_name ASC"); $sql_software_templates = mysqli_query($mysqli, "SELECT * FROM software_templates WHERE software_template_archived_at IS NULL ORDER BY software_template_name ASC");
while ($row = mysqli_fetch_array($sql_software_templates)) { while ($row = mysqli_fetch_array($sql_software_templates)) {
$software_template_id = intval($row['software_id']); $software_template_id = intval($row['software_template_id']);
$software_template_name = nullable_htmlentities($row['software_name']); $software_template_name = nullable_htmlentities($row['software_template_name']);
?> ?>
<option value="<?php echo $software_template_id ?>"><?php echo $software_template_name; ?></option> <option value="<?php echo $software_template_id ?>"><?php echo $software_template_name; ?></option>

View File

@@ -148,7 +148,7 @@
<select class="form-control select2" name="category"> <select class="form-control select2" name="category">
<option value="0">- Not Categorized -</option> <option value="0">- Not Categorized -</option>
<?php <?php
$sql_categories = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Ticket' AND category_archived_at IS NULL"); $sql_categories = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Ticket' AND category_archived_at IS NULL ORDER BY category_name ASC");
while ($row = mysqli_fetch_array($sql_categories)) { while ($row = mysqli_fetch_array($sql_categories)) {
$category_id = intval($row['category_id']); $category_id = intval($row['category_id']);
$category_name = nullable_htmlentities($row['category_name']); $category_name = nullable_htmlentities($row['category_name']);
@@ -172,31 +172,46 @@
</div> </div>
<div class="form-group"> <div class="row">
<label>Assign to</label> <div class="col">
<div class="input-group"> <div class="form-group">
<div class="input-group-prepend"> <label>Assign to</label>
<span class="input-group-text"><i class="fa fa-fw fa-user-check"></i></span> <div class="input-group">
</div> <div class="input-group-prepend">
<select class="form-control select2" name="assigned_to"> <span class="input-group-text"><i class="fa fa-fw fa-user-check"></i></span>
<option value="0">Not Assigned</option> </div>
<?php <select class="form-control select2" name="assigned_to">
<option value="0">Not Assigned</option>
<?php
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT user_id, user_name FROM users "SELECT user_id, user_name FROM users
WHERE user_role_id > 1 WHERE user_role_id > 1
AND user_type = 1 AND user_type = 1
AND user_status = 1 AND user_status = 1
AND user_archived_at IS NULL AND user_archived_at IS NULL
ORDER BY user_name ASC" ORDER BY user_name ASC"
); );
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_array($sql)) {
$user_id = intval($row['user_id']); $user_id = intval($row['user_id']);
$user_name = nullable_htmlentities($row['user_name']); ?> $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> <option <?php if ($session_user_id == $user_id) { echo "selected"; } ?> value="<?php echo $user_id; ?>"><?php echo $user_name; ?></option>
<?php } ?> <?php } ?>
</select> </select>
</div>
</div>
</div>
<div class="col">
<div class="form-group">
<label>Due</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="due">
</div>
</div>
</div> </div>
</div> </div>
@@ -378,7 +393,7 @@
<option value="0">- None -</option> <option value="0">- None -</option>
<?php <?php
$sql_vendors = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = $client_id AND vendor_template = 0 AND vendor_archived_at IS NULL ORDER BY vendor_name ASC"); $sql_vendors = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = $client_id AND vendor_archived_at IS NULL ORDER BY vendor_name ASC");
while ($row = mysqli_fetch_array($sql_vendors)) { while ($row = mysqli_fetch_array($sql_vendors)) {
$vendor_id_select = intval($row['vendor_id']); $vendor_id_select = intval($row['vendor_id']);
$vendor_name_select = nullable_htmlentities($row['vendor_name']); ?> $vendor_name_select = nullable_htmlentities($row['vendor_name']); ?>

View File

@@ -18,7 +18,7 @@
<select class="form-control select2" name="bulk_category"> <select class="form-control select2" name="bulk_category">
<option value="0">- Uncategorized -</option> <option value="0">- Uncategorized -</option>
<?php <?php
$sql_categories = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Ticket' AND category_archived_at IS NULL"); $sql_categories = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Ticket' AND category_archived_at IS NULL ORDER BY category_name ASC");
while ($row = mysqli_fetch_array($sql_categories)) { while ($row = mysqli_fetch_array($sql_categories)) {
$category_id = intval($row['category_id']); $category_id = intval($row['category_id']);
$category_name = nullable_htmlentities($row['category_name']); $category_name = nullable_htmlentities($row['category_name']);

View File

@@ -21,7 +21,7 @@
<option value="0">- None -</option> <option value="0">- None -</option>
<?php <?php
$sql_vendors = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = $client_id AND vendor_template = 0 AND vendor_archived_at IS NULL ORDER BY vendor_name ASC"); $sql_vendors = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = $client_id AND vendor_archived_at IS NULL ORDER BY vendor_name ASC");
while ($row = mysqli_fetch_array($sql_vendors)) { while ($row = mysqli_fetch_array($sql_vendors)) {
$vendor_id_select = intval($row['vendor_id']); $vendor_id_select = intval($row['vendor_id']);
$vendor_name_select = nullable_htmlentities($row['vendor_name']); $vendor_name_select = nullable_htmlentities($row['vendor_name']);

View File

@@ -4,7 +4,7 @@ $sql_invoices = mysqli_query($mysqli, "SELECT * FROM invoices WHERE invoice_stat
?> ?>
<div class="modal" id="addInvoiceFromTicketModal" tabindex="-1"> <div class="modal" id="addInvoiceFromTicketModal" tabindex="-1">
<div class="modal-dialog"> <div class="modal-dialog modal-lg">
<div class="modal-content bg-dark"> <div class="modal-content bg-dark">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title"><i class="fa fa-fw fa-file-invoice-dollar mr-2"></i>Invoice ticket</h5> <h5 class="modal-title"><i class="fa fa-fw fa-file-invoice-dollar mr-2"></i>Invoice ticket</h5>
@@ -24,10 +24,6 @@ $sql_invoices = mysqli_query($mysqli, "SELECT * FROM invoices WHERE invoice_stat
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-add-to-invoice"><i class="fa fa-fw fa-plus mr-2"></i>Add to Existing Invoice</a> <a class="nav-link" data-toggle="pill" href="#pills-add-to-invoice"><i class="fa fa-fw fa-plus mr-2"></i>Add to Existing Invoice</a>
</li> </li>
<?php } else { ?>
<div class="alert alert-warning" role="alert">
<i class="fa fa-fw fa-exclamation-triangle mr-2"></i>No draft invoices found. Please create a new invoice first.
</div>
<?php } ?> <?php } ?>
</ul> </ul>
@@ -37,39 +33,46 @@ $sql_invoices = mysqli_query($mysqli, "SELECT * FROM invoices WHERE invoice_stat
<div class="tab-pane fade show active" id="pills-create-invoice"> <div class="tab-pane fade show active" id="pills-create-invoice">
<div class="form-group"> <div class="row">
<label>Invoice Date <strong class="text-danger">*</strong></label> <div class="col-sm-6">
<div class="input-group">
<div class="input-group-prepend"> <div class="form-group">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span> <label>Invoice Date <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>
<input type="date" class="form-control" name="date" max="2999-12-31" value="<?php echo date("Y-m-d"); ?>">
</div>
</div> </div>
<input type="date" class="form-control" name="date" max="2999-12-31" value="<?php echo date("Y-m-d"); ?>">
</div> </div>
</div> <div class="col-sm-6">
<div class="form-group">
<label>Invoice Category <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-list"></i></span>
</div>
<select class="form-control select2" name="category">
<option value="">- Category -</option>
<?php
<div class="form-group"> $sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Income' AND category_archived_at IS NULL ORDER BY category_name ASC");
<label>Invoice Category <strong class="text-danger">*</strong></label> while ($row = mysqli_fetch_array($sql)) {
<div class="input-group"> $category_id = intval($row['category_id']);
<div class="input-group-prepend"> $category_name = nullable_htmlentities($row['category_name']);
<span class="input-group-text"><i class="fa fa-fw fa-list"></i></span> ?>
</div> <option value="<?php echo $category_id; ?>"><?php echo $category_name; ?></option>
<select class="form-control select2" name="category">
<option value="">- Category -</option>
<?php
$sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Income' AND category_archived_at IS NULL ORDER BY category_name ASC"); <?php
while ($row = mysqli_fetch_array($sql)) { }
$category_id = intval($row['category_id']); ?>
$category_name = nullable_htmlentities($row['category_name']); </select>
?> <div class="input-group-append">
<option value="<?php echo $category_id; ?>"><?php echo $category_name; ?></option> <button type="button" class="btn btn-secondary" data-toggle="modal" data-target="#addQuickCategoryIncomeModal"><i class="fas fa-fw fa-plus"></i></button>
</div>
<?php </div>
}
?>
</select>
<div class="input-group-append">
<button type="button" class="btn btn-secondary" data-toggle="modal" data-target="#addQuickCategoryIncomeModal"><i class="fas fa-fw fa-plus"></i></button>
</div> </div>
</div> </div>
</div> </div>
@@ -91,7 +94,7 @@ $sql_invoices = mysqli_query($mysqli, "SELECT * FROM invoices WHERE invoice_stat
if (mysqli_num_rows($sql_invoices) > 0) { ?> if (mysqli_num_rows($sql_invoices) > 0) { ?>
<div class="tab-pane fade show active" id="pills-add-to-invoice"> <div class="tab-pane fade" id="pills-add-to-invoice">
<div class="form-group"> <div class="form-group">
<label>Invoice</label> <label>Invoice</label>
<div class="input-group"> <div class="input-group">

View File

@@ -22,10 +22,10 @@
<select class="form-control" name="vendor_template_id" required> <select class="form-control" name="vendor_template_id" required>
<option value="">- Select Template -</option> <option value="">- Select Template -</option>
<?php <?php
$sql_vendor_templates = mysqli_query($mysqli, "SELECT * FROM vendors WHERE vendor_template = 1 AND vendor_archived_at IS NULL ORDER BY vendor_name ASC"); $sql_vendor_templates = mysqli_query($mysqli, "SELECT * FROM vendor_templates WHERE vendor_template_archived_at IS NULL ORDER BY vendor_template_name ASC");
while ($row = mysqli_fetch_array($sql_vendor_templates)) { while ($row = mysqli_fetch_array($sql_vendor_templates)) {
$vendor_template_id = intval($row['vendor_id']); $vendor_template_id = intval($row['vendor_template_id']);
$vendor_template_name = nullable_htmlentities($row['vendor_name']); $vendor_template_name = nullable_htmlentities($row['vendor_template_name']);
?> ?>
<option value="<?php echo $vendor_template_id ?>"><?php echo $vendor_template_name; ?></option> <option value="<?php echo $vendor_template_id ?>"><?php echo $vendor_template_name; ?></option>

View File

@@ -9,10 +9,26 @@ if (isset($_GET['client_id'])) {
require_once "includes/inc_all_client.php"; require_once "includes/inc_all_client.php";
$client_query = "AND network_client_id = $client_id"; $client_query = "AND network_client_id = $client_id";
$client_url = "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 = "network_archived_at IS NOT NULL";
} else {
$archived = 0;
$archive_query = "network_archived_at IS NULL";
}
} else { } else {
require_once "includes/inc_client_overview_all.php"; require_once "includes/inc_client_overview_all.php";
$client_query = ''; $client_query = '';
$client_url = ''; $client_url = '';
// Overide Filter Header Archived
if (isset($_GET['archived']) && $_GET['archived'] == 1) {
$archived = 1;
$archive_query = "(client_archived_at IS NOT NULL OR network_archived_at IS NOT NULL)";
} else {
$archived = 0;
$archive_query = "(client_archived_at IS NULL AND network_archived_at IS NULL)";
}
} }
// Perms // Perms
@@ -45,7 +61,7 @@ $sql = mysqli_query(
"SELECT SQL_CALC_FOUND_ROWS * FROM networks "SELECT SQL_CALC_FOUND_ROWS * FROM networks
LEFT JOIN clients ON client_id = network_client_id LEFT JOIN clients ON client_id = network_client_id
LEFT JOIN locations ON location_id = network_location_id LEFT JOIN locations ON location_id = network_location_id
WHERE network_$archive_query WHERE $archive_query
AND (network_name LIKE '%$q%' OR network_description LIKE '%$q%' OR network_vlan LIKE '%$q%' OR network LIKE '%$q%' OR network_gateway LIKE '%$q%' OR network_subnet LIKE '%$q%' OR network_primary_dns LIKE '%$q%' OR network_secondary_dns LIKE '%$q%' OR network_dhcp_range LIKE '%$q%' OR location_name LIKE '%$q%' OR client_name LIKE '%$q%') AND (network_name LIKE '%$q%' OR network_description LIKE '%$q%' OR network_vlan LIKE '%$q%' OR network LIKE '%$q%' OR network_gateway LIKE '%$q%' OR network_subnet LIKE '%$q%' OR network_primary_dns LIKE '%$q%' OR network_secondary_dns LIKE '%$q%' OR network_dhcp_range LIKE '%$q%' OR location_name LIKE '%$q%' OR client_name LIKE '%$q%')
$access_permission_query $access_permission_query
$location_query $location_query
@@ -80,6 +96,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php if ($client_url) { ?> <?php if ($client_url) { ?>
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>"> <input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<?php } ?> <?php } ?>
<input type="hidden" name="archived" value="<?php echo $archived; ?>">
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4">
@@ -150,6 +167,10 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<div class="col-md-6"> <div class="col-md-6">
<div class="btn-group float-right"> <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> <div class="dropdown ml-2" id="bulkActionButton" hidden>
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown"> <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>) <i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>)
@@ -263,6 +284,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
} else { } else {
$location_name_display = $location_name; $location_name_display = $location_name;
} }
$network_archived_at = nullable_htmlentities($row['network_archived_at']);
?> ?>
<tr> <tr>
@@ -312,14 +334,21 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<i class="fas fa-fw fa-edit mr-2"></i>Edit <i class="fas fa-fw fa-edit mr-2"></i>Edit
</a> </a>
<?php if ($session_user_role == 3) { ?> <?php if ($session_user_role == 3) { ?>
<?php if ($network_archived_at) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_network=<?php echo $network_id; ?>"> <a class="dropdown-item text-info confirm-link" href="post.php?unarchive_network=<?php echo $network_id; ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive <i class="fas fa-fw fa-redo mr-2"></i>Restore
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_network=<?php echo $network_id; ?>"> <a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_network=<?php echo $network_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash mr-2"></i>Delete
</a> </a>
<?php } else { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_network=<?php echo $network_id; ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</a>
<?php } ?>
<?php } ?> <?php } ?>
</div> </div>
</div> </div>

View File

@@ -1,3 +1,12 @@
6.10.0 (2025-05-27)
- Embedded files support (Factur-X 1.07 / ZUGFeRD 2.3) #789
6.9.5 (2025-05-27)
- Automatically add destinations from HTML code #804
- Wrong default value when $table_el['old_cell_padding'] is missing #807
- Fixed PHP warning when empty hash link for image exists in HTML #809
- Fix for application of alpha component to SVG RGBA fills #810
6.9.4 (2025-05-13) 6.9.4 (2025-05-13)
- Update donation link. - Update donation link.

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