mirror of
https://github.com/itflow-org/itflow
synced 2026-05-03 01:37:46 +00:00
Compare commits
61 Commits
v25.11
...
duplicate-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
216db04d32 | ||
|
|
13b8f93e17 | ||
|
|
0347382a34 | ||
|
|
840460afe7 | ||
|
|
c851e54e1d | ||
|
|
5ef53b569c | ||
|
|
698b4166e8 | ||
|
|
1a9a36829b | ||
|
|
155b8598ff | ||
|
|
4153c91f84 | ||
|
|
a99b19a1b5 | ||
|
|
18429fda2c | ||
|
|
435da991ec | ||
|
|
ebd9aae924 | ||
|
|
414a84d5ec | ||
|
|
a3b2517603 | ||
|
|
43535082f6 | ||
|
|
e73af9980e | ||
|
|
0bdd5784ee | ||
|
|
48719ce29c | ||
|
|
29839d3b23 | ||
|
|
185ea7d6ac | ||
|
|
ac7623d4f5 | ||
|
|
3d119261cc | ||
|
|
169619c9b9 | ||
|
|
b991f787a2 | ||
|
|
215fc6803e | ||
|
|
a79c1c8246 | ||
|
|
1aa6419b1b | ||
|
|
02694f6720 | ||
|
|
f50aabb570 | ||
|
|
19b8d09bfd | ||
|
|
66fb999a8c | ||
|
|
0c5883b61b | ||
|
|
ef66d5172c | ||
|
|
118f9a34d8 | ||
|
|
b61dfac569 | ||
|
|
79160f9b5c | ||
|
|
d2523cff4a | ||
|
|
1839599769 | ||
|
|
29e1b56e78 | ||
|
|
47e647c712 | ||
|
|
a87b0b0447 | ||
|
|
96b8fcad3a | ||
|
|
cf0fa0024c | ||
|
|
aba5ed9271 | ||
|
|
63141f3578 | ||
|
|
612041635d | ||
|
|
efcc0fd5cb | ||
|
|
b0724f5b66 | ||
|
|
66a2b4b6d2 | ||
|
|
77b4dfa50a | ||
|
|
1e6e7fd6d8 | ||
|
|
46a1b673ba | ||
|
|
7230325e62 | ||
|
|
af8e733cfb | ||
|
|
26ab43c57f | ||
|
|
15ed4ef1ce | ||
|
|
0ac76766bd | ||
|
|
abb97ad99f | ||
|
|
6cdc26b55b |
10
.gitignore
vendored
10
.gitignore
vendored
@@ -4,8 +4,16 @@ config.php
|
||||
uploads/favicon.ico
|
||||
uploads/clients/*
|
||||
!uploads/clients/index.php
|
||||
uploads/custom/*
|
||||
!uploads/custom/index.php
|
||||
uploads/documents/*
|
||||
!uploads/documents/index.php
|
||||
uploads/document_templates/*
|
||||
!uploads/document_templates/index.php
|
||||
uploads/expenses/*
|
||||
!uploads/expenses/index.php
|
||||
uploads/recurring_tickets/*
|
||||
!uploads/recurring_tickets/index.php
|
||||
uploads/settings/*
|
||||
!uploads/settings/index.php
|
||||
uploads/users/*
|
||||
@@ -14,6 +22,8 @@ uploads/tmp/*
|
||||
!uploads/tmp/index.php
|
||||
uploads/tickets/*
|
||||
!uploads/tickets/index.php
|
||||
uploads/ticket_templates/*
|
||||
!uploads/ticket_templates/index.php
|
||||
.idea/*
|
||||
plugins/htmlpurifier/standalone/HTMLPurifier/DefinitionCache/Serializer/HTML/*
|
||||
!plugins/htmlpurifier/standalone/HTMLPurifier/DefinitionCache/Serializer/HTML/.gitkeep
|
||||
|
||||
32
CHANGELOG.md
32
CHANGELOG.md
@@ -2,7 +2,37 @@
|
||||
|
||||
This file documents all notable changes made to ITFlow.
|
||||
|
||||
## [25.11] Changelog
|
||||
## [25.11.1] Maint Release
|
||||
|
||||
### Fixes
|
||||
- Fix broken edit Payment Method.
|
||||
- Fix unable to delete Vendor Template.
|
||||
- Fix Mail Queue link in flash alert for testing email and sending a quote.
|
||||
- Add Show Category Type select if not defined.
|
||||
- Add Show Product Type select if not defined.
|
||||
- Fix add ticket watcher.
|
||||
- Fix if Client isn't assigned to a ticket dont show client view.
|
||||
- Fix missing session client id check when paying an invoice from client portal.
|
||||
- Update Composer Webklex-IMAP library dependency symfony/http-foundation from 7.3.3 to 7.3.7 to fix security related issues.
|
||||
- Add back delete Payment provider the database will handle cascade deletes to saved cards, recurring payments and client payment provider reference.
|
||||
- Don't show Client Tickets Breadcrumb if no client is assigned to a ticket.
|
||||
- Don't Show Contact or Assignment Tab in edit ticket if no Client is Assigned.
|
||||
- Don't Show add contact, asset, vendor, watcher if not client is assigned to a ticket.
|
||||
- Don't Show Public Comment & Email if contact email doesn't exist.
|
||||
- Fixed IMAP Test whicn now uses RAW TCP Connection instead of the depracated php-imap extension.
|
||||
- Fix Broken Link in Ticket Updates via Client Portal to agent.
|
||||
|
||||
### Added / Changed
|
||||
- [Feature] Added Asset Tags.
|
||||
- [Feature] Added Quick Add Links to most side bar navs example quickly add a client from sidebar.
|
||||
- Migrate ticket template add to ajax modal.
|
||||
- Add TOTP secret to Client Export PDF in Credential section.
|
||||
- Add UserID on hover in users listing.
|
||||
- Merge ticket now redirects to the new ticket details page.
|
||||
- [Feature] Add Pay via saved card under invoice Listings.
|
||||
- Ticket Related Side Items UI Cleanup to use btn-tool class.
|
||||
|
||||
## [25.11] Stable
|
||||
|
||||
### Deprecation Notice:
|
||||
- **Outdated CRON Scripts**: The following scripts are removed.
|
||||
|
||||
@@ -4059,9 +4059,7 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
|
||||
|
||||
`contract_template_created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
`contract_template_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
|
||||
`contract_template_archived_at` DATETIME NULL DEFAULT NULL,
|
||||
|
||||
`company_id` INT(11) NOT NULL
|
||||
`contract_template_archived_at` DATETIME NULL DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||
|
||||
|
||||
@@ -4115,10 +4113,31 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
|
||||
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.3.7'");
|
||||
}
|
||||
|
||||
// if (CURRENT_DATABASE_VERSION == '2.3.7') {
|
||||
// // Insert queries here required to update to DB version 2.3.8
|
||||
if (CURRENT_DATABASE_VERSION == '2.3.7') {
|
||||
|
||||
mysqli_query($mysqli, "
|
||||
CREATE TABLE `asset_tags` (
|
||||
`asset_tag_asset_id` INT(11) NOT NULL,
|
||||
`asset_tag_tag_id` INT(11) NOT NULL,
|
||||
PRIMARY KEY (`asset_tag_asset_id`, `asset_tag_tag_id`),
|
||||
CONSTRAINT `fk_asset`
|
||||
FOREIGN KEY (`asset_tag_asset_id`)
|
||||
REFERENCES `assets`(`asset_id`)
|
||||
ON DELETE CASCADE,
|
||||
CONSTRAINT `fk_tag`
|
||||
FOREIGN KEY (`asset_tag_tag_id`)
|
||||
REFERENCES `tags`(`tag_id`)
|
||||
ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
");
|
||||
|
||||
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.3.8'");
|
||||
}
|
||||
|
||||
// if (CURRENT_DATABASE_VERSION == '2.3.8') {
|
||||
// // Insert queries here required to update to DB version 2.3.9
|
||||
// // Then, update the database to the next sequential version
|
||||
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.3.8'");
|
||||
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.3.9'");
|
||||
// }
|
||||
|
||||
} else {
|
||||
|
||||
@@ -502,6 +502,12 @@ if (file_exists($dbSqlFile)) {
|
||||
];
|
||||
}
|
||||
|
||||
// Duplicate checks
|
||||
$duplicate_tickets_sql = mysqli_query($mysqli, "SELECT ticket_number, COUNT(*) AS count FROM tickets GROUP BY ticket_number HAVING count > 1");
|
||||
$duplicate_quotes_sql = mysqli_query($mysqli, "SELECT quote_number, COUNT(*) AS count FROM quotes GROUP BY quote_number HAVING count > 1");
|
||||
$duplicate_invoices_sql = mysqli_query($mysqli, "SELECT invoice_number, COUNT(*) AS count FROM invoices GROUP BY invoice_number HAVING count > 1");
|
||||
|
||||
|
||||
$mysqli->close();
|
||||
?>
|
||||
|
||||
@@ -758,6 +764,40 @@ $mysqli->close();
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Duplicated ticket/quote/invoice numbers -->
|
||||
<h3 class="mt-3">Duplicated Numbering</h3>
|
||||
<h4>Tickets</h4>
|
||||
<ul>
|
||||
<?php if (mysqli_num_rows($duplicate_tickets_sql) > 0 ) {
|
||||
while ($row = $duplicate_tickets_sql->fetch_assoc()) {
|
||||
echo "<li>" . $config_ticket_prefix . nullable_htmlentities($row['ticket_number']) . " (" . $row['count'] . ")" . "</li>";
|
||||
}
|
||||
} else {
|
||||
echo "No duplicate ticket numbers.";
|
||||
} ?>
|
||||
</ul>
|
||||
<h4>Quotes</h4>
|
||||
<ul>
|
||||
<?php if (mysqli_num_rows($duplicate_quotes_sql) > 0 ) {
|
||||
while ($row = $duplicate_quotes_sql->fetch_assoc()) {
|
||||
echo "<li>" . $config_quote_prefix . nullable_htmlentities($row['quote_number']) . " (" . $row['count'] . ")" . "</li>";
|
||||
}
|
||||
} else {
|
||||
echo "No duplicate quote numbers.";
|
||||
} ?>
|
||||
</ul>
|
||||
<h4>Invoices</h4>
|
||||
<ul>
|
||||
<?php if (mysqli_num_rows($duplicate_invoices_sql) > 0 ) {
|
||||
while ($row = $duplicate_invoices_sql->fetch_assoc()) {
|
||||
echo "<li>" . $config_invoice_prefix . nullable_htmlentities($row['invoice_number']) . " (" . $row['count'] . ")" . "</li>";
|
||||
}
|
||||
} else {
|
||||
echo "No duplicate invoice numbers.";
|
||||
} ?>
|
||||
</ul>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -110,12 +110,17 @@
|
||||
<?php if ($config_module_enable_itdoc) { ?>
|
||||
<li class="nav-header">TEMPLATES</li>
|
||||
|
||||
<!-- 2025-11-16 JQ - Hide Contracts not yet ready
|
||||
<li class="nav-item">
|
||||
<a href="/admin/contract_templates.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'contract_templates.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/contract_template.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'contract_template.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-file-contract"></i>
|
||||
<p>Contract Templates</p>
|
||||
<p>
|
||||
<span href="#" class="fas fa-plus-circle right ajax-modal" data-modal-url="/admin/modals/contract_template/contract_template_add.php" data-modal-size="lg"></span>
|
||||
Contract Templates
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
-->
|
||||
<li class="nav-item">
|
||||
<a href="/admin/project_template.php" class="nav-link <?php echo (in_array(basename($_SERVER['PHP_SELF']), ['project_template.php', 'project_template_details.php']) ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-project-diagram"></i>
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$category = nullable_htmlentities($_GET['category']);
|
||||
$category = nullable_htmlentities($_GET['category'] ?? '');
|
||||
|
||||
$category_types_array = ['Expense', 'Income', 'Referral', 'Ticket'];
|
||||
|
||||
?>
|
||||
|
||||
@@ -13,10 +15,30 @@ $category = nullable_htmlentities($_GET['category']);
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="type" value="<?php echo ($category); ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<?php if ($category) { ?>
|
||||
<input type="hidden" name="type" value="<?= $category ?>">
|
||||
<?php } else { ?>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Type <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="type" required>
|
||||
<option value="">- Select Type -</option>
|
||||
<?php foreach ($category_types_array as $type_select) { ?>
|
||||
<option><?= $type_select ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Name <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
@@ -39,7 +61,7 @@ $category = nullable_htmlentities($_GET['category']);
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_category" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create</button>
|
||||
<button type="submit" name="add_category" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create Category</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
<?php
|
||||
require_once '../../../includes/modal_header.php';
|
||||
ob_start();
|
||||
|
||||
|
||||
$contract_types_array = ['Fully Managed', 'Partialy Managed', 'Break/Fix'];
|
||||
$update_frequency_array = ['Manual', 'Annually', '2 Year', '3 Year', '5 Year', '7 Year'];
|
||||
$renewal_frequency_array = ['Manual', 'Annually', '2 Year', '3 Year', '5 Year', '7 Year'];
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-file-contract mr-2"></i>New Contract Template</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal"><span>×</span></button>
|
||||
</div>
|
||||
|
||||
<!-- Tabs Navigation -->
|
||||
<ul class="modal-header nav nav-pills nav-justified">
|
||||
<li class="nav-item">
|
||||
@@ -25,37 +28,62 @@ $update_frequency_array = ['Manual', 'Annually', '2 Year', '3 Year', '5 Year', '
|
||||
<a class="nav-link" id="details-tab" data-toggle="tab" href="#details" role="tab">Details</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="tab-content" id="contractTemplateTabContent">
|
||||
|
||||
<!-- General Info Tab -->
|
||||
<div class="tab-pane fade show active" id="general" role="tabpanel">
|
||||
<div class="form-group">
|
||||
<label>Template Name <strong class="text-danger">*</strong></label>
|
||||
<input type="text" class="form-control" name="contract_template_name" placeholder="Contract Template Name" maxlength="200" required autofocus>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-file-contract"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" placeholder="Contract Template Name" maxlength="200" required autofocus>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Template Description <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-align-left"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="description"
|
||||
placeholder="Contract Template Description" maxlength="200" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Contract Type <strong class="text-danger">*</strong></label>
|
||||
<select class="form-control select2" name="contract_template_type" required>
|
||||
<option value="">- Select Type -</option>
|
||||
<?php foreach ($contract_types_array as $type) { ?>
|
||||
<option><?php echo $type; ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
<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="type" required>
|
||||
<option value="">- Select Type -</option>
|
||||
<?php foreach ($contract_types_array as $type) { ?>
|
||||
<option><?= $type ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Update Frequency</label>
|
||||
<select class="form-control select2" name="contract_template_update_frequency">
|
||||
<option value="">- Select Frequency -</option>
|
||||
<?php foreach ($update_frequency_array as $freq) { ?>
|
||||
<option><?php echo $freq; ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
<label>Renewal Frequency</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-sync-alt"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="renewal_frequency">
|
||||
<option value="">- Select Frequency -</option>
|
||||
<?php foreach ($renewal_frequency_array as $renewal_frequency) { ?>
|
||||
<option><?= $renewal_frequency ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -64,33 +92,63 @@ $update_frequency_array = ['Manual', 'Annually', '2 Year', '3 Year', '5 Year', '
|
||||
<div class="form-row">
|
||||
<div class="form-group col-md-6">
|
||||
<label>Low Priority Response (hrs)</label>
|
||||
<input type="number" class="form-control" name="sla_low_response_time" placeholder="e.g., 24">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
|
||||
</div>
|
||||
<input type="number" class="form-control" name="sla_low_response_time" placeholder="e.g., 24">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<label>Low Priority Resolution (hrs)</label>
|
||||
<input type="number" class="form-control" name="sla_low_resolution_time" placeholder="e.g., 48">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-hourglass-half"></i></span>
|
||||
</div>
|
||||
<input type="number" class="form-control" name="sla_low_resolution_time" placeholder="e.g., 48">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group col-md-6">
|
||||
<label>Medium Priority Response (hrs)</label>
|
||||
<input type="number" class="form-control" name="sla_medium_response_time" placeholder="e.g., 12">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
|
||||
</div>
|
||||
<input type="number" class="form-control" name="sla_medium_response_time" placeholder="e.g., 12">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<label>Medium Priority Resolution (hrs)</label>
|
||||
<input type="number" class="form-control" name="sla_medium_resolution_time" placeholder="e.g., 24">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-hourglass-half"></i></span>
|
||||
</div>
|
||||
<input type="number" class="form-control" name="sla_medium_resolution_time" placeholder="e.g., 24">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group col-md-6">
|
||||
<label>High Priority Response (hrs)</label>
|
||||
<input type="number" class="form-control" name="sla_high_response_time" placeholder="e.g., 1">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-bolt"></i></span>
|
||||
</div>
|
||||
<input type="number" class="form-control" name="sla_high_response_time" placeholder="e.g., 1">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<label>High Priority Resolution (hrs)</label>
|
||||
<input type="number" class="form-control" name="sla_high_resolution_time" placeholder="e.g., 4">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-stopwatch"></i></span>
|
||||
</div>
|
||||
<input type="number" class="form-control" name="sla_high_resolution_time" placeholder="e.g., 4">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -99,29 +157,49 @@ $update_frequency_array = ['Manual', 'Annually', '2 Year', '3 Year', '5 Year', '
|
||||
<div class="tab-pane fade" id="rates" role="tabpanel">
|
||||
<div class="form-group">
|
||||
<label>Standard Hourly Rate</label>
|
||||
<input type="text" class="form-control" name="contract_template_hourly_rate" placeholder="e.g., 100">
|
||||
<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" name="rate_standard" placeholder="e.g., 100">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>After Hours Hourly Rate</label>
|
||||
<input type="text" class="form-control" name="contract_template_after_hours_hourly_rate" placeholder="e.g., 150">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-moon"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="rate_after_hours" placeholder="e.g., 150">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Support Hours</label>
|
||||
<input type="text" class="form-control" name="contract_template_support_hours" placeholder="e.g., Mon-Fri 9am-5pm">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="support_hours" placeholder="e.g., Mon-Fri 9am-5pm">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Net Terms</label>
|
||||
<input type="text" class="form-control" name="contract_template_net_terms" placeholder="e.g., Net 30">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-file-invoice-dollar"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="net_terms" placeholder="e.g., Net 30">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Details Tab -->
|
||||
<div class="tab-pane fade" id="details" role="tabpanel">
|
||||
<div class="form-group">
|
||||
<textarea class="form-control tinymce" rows="6" name="contract_template_details" placeholder="Enter Contract Details"></textarea>
|
||||
<textarea class="form-control tinymce" rows="6" name="details" placeholder="Enter Contract Details"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -129,8 +207,12 @@ $update_frequency_array = ['Manual', 'Annually', '2 Year', '3 Year', '5 Year', '
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_contract_template" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create Template</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
<button type="submit" name="add_contract_template" class="btn btn-primary text-bold">
|
||||
<i class="fa fa-check mr-2"></i>Create Template
|
||||
</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal">
|
||||
<i class="fa fa-times mr-2"></i>Cancel
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
265
admin/modals/contract_template/contract_template_edit.php
Normal file
265
admin/modals/contract_template/contract_template_edit.php
Normal file
@@ -0,0 +1,265 @@
|
||||
<?php
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$contract_template_id = intval($_GET['id']);
|
||||
|
||||
$contract_types_array = ['Fully Managed', 'Partialy Managed', 'Break/Fix'];
|
||||
$update_frequency_array = ['Manual', 'Annually', '2 Year', '3 Year', '5 Year', '7 Year'];
|
||||
|
||||
// Fetch existing template
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM contract_templates WHERE contract_template_id = $contract_template_id LIMIT 1");
|
||||
$row = mysqli_fetch_array($sql);
|
||||
|
||||
// Assign locals
|
||||
$name = nullable_htmlentities($row['contract_template_name']);
|
||||
$description = nullable_htmlentities($row['contract_template_description']);
|
||||
$type = nullable_htmlentities($row['contract_template_type']);
|
||||
$renewal_frequency = nullable_htmlentities($row['contract_template_renewal_frequency']);
|
||||
$sla_low_resp = intval($row['contract_template_sla_low_response_time']);
|
||||
$sla_med_resp = intval($row['contract_template_sla_medium_response_time']);
|
||||
$sla_high_resp = intval($row['contract_template_sla_high_response_time']);
|
||||
$sla_low_res = intval($row['contract_template_sla_low_resolution_time']);
|
||||
$sla_med_res = intval($row['contract_template_sla_medium_resolution_time']);
|
||||
$sla_high_res = intval($row['contract_template_sla_high_resolution_time']);
|
||||
$hourly_rate = intval($row['contract_template_rate_standard']);
|
||||
$after_hours = intval($row['contract_template_rate_after_hours']);
|
||||
$support_hours = nullable_htmlentities($row['contract_template_support_hours']);
|
||||
$net_terms = intval($row['contract_template_net_terms']);
|
||||
$details = nullable_htmlentities($row['contract_template_details']);
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-file-contract mr-2"></i>Edit Contract Template</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal"><span>×</span></button>
|
||||
</div>
|
||||
|
||||
<!-- Tabs Navigation -->
|
||||
<ul class="modal-header nav nav-pills nav-justified">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" id="general-tab" data-toggle="tab" href="#general" role="tab">General Info</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="sla-tab" data-toggle="tab" href="#sla" role="tab">SLA</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="rates-tab" data-toggle="tab" href="#rates" role="tab">Rates & Support</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="details-tab" data-toggle="tab" href="#details" role="tab">Details</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="contract_template_id" value="<?php echo $contract_template_id; ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
<div class="tab-content" id="contractTemplateTabContent">
|
||||
|
||||
<!-- General Info Tab -->
|
||||
<div class="tab-pane fade show active" id="general" role="tabpanel">
|
||||
<div class="form-group">
|
||||
<label>Template Name <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-file-contract"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name"
|
||||
placeholder="Contract Template Name" maxlength="200" required autofocus
|
||||
value="<?= $name ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Template Description <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-align-left"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="description"
|
||||
placeholder="Contract Template Description" maxlength="200" required
|
||||
value="<?= $description ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Contract Type <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-list"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="type" required>
|
||||
<option value="">- Select Type -</option>
|
||||
<?php foreach ($contract_types_array as $type_select) { ?>
|
||||
<option <?php if ($type == $type_select) { echo "selected"; } ?>><?= $type_select ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Renewal Frequency</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-sync-alt"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="renewal_frequency">
|
||||
<option value="">- Select Frequency -</option>
|
||||
<?php foreach ($renewal_frequency_array as $renewal_frequency_select) { ?>
|
||||
<option <?php if ($renewal_frequency == $renewal_frequency_select) { echo "selected"; } ?>><?= $renewal_frequency_select ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SLA Tab -->
|
||||
<div class="tab-pane fade" id="sla" role="tabpanel">
|
||||
<div class="form-row">
|
||||
<div class="form-group col-md-6">
|
||||
<label>Low Priority Response (hrs)</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
|
||||
</div>
|
||||
<input type="number" class="form-control" name="sla_low_response_time" placeholder="e.g., 24"
|
||||
value="<?= $sla_low_resp ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<label>Low Priority Resolution (hrs)</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-hourglass-half"></i></span>
|
||||
</div>
|
||||
<input type="number" class="form-control" name="sla_low_resolution_time" placeholder="e.g., 48"
|
||||
value="<?= $sla_low_res ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group col-md-6">
|
||||
<label>Medium Priority Response (hrs)</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
|
||||
</div>
|
||||
<input type="number" class="form-control" name="sla_medium_response_time" placeholder="e.g., 12"
|
||||
value="<?= $sla_med_resp ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<label>Medium Priority Resolution (hrs)</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-hourglass-half"></i></span>
|
||||
</div>
|
||||
<input type="number" class="form-control" name="sla_medium_resolution_time" placeholder="e.g., 24"
|
||||
value="<?= $sla_med_res ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group col-md-6">
|
||||
<label>High Priority Response (hrs)</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-bolt"></i></span>
|
||||
</div>
|
||||
<input type="number" class="form-control" name="sla_high_response_time" placeholder="e.g., 1"
|
||||
value="<?= $sla_high_resp ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<label>High Priority Resolution (hrs)</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-stopwatch"></i></span>
|
||||
</div>
|
||||
<input type="number" class="form-control" name="sla_high_resolution_time" placeholder="e.g., 4"
|
||||
value="<?= $sla_high_res ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Rates & Support Tab -->
|
||||
<div class="tab-pane fade" id="rates" role="tabpanel">
|
||||
<div class="form-group">
|
||||
<label>Standard Hourly Rate</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" name="rate_standard" placeholder="e.g., 100"
|
||||
value="<?= $rate_standard ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>After Hours Hourly Rate</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-moon"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="rate_after_hours" placeholder="e.g., 150"
|
||||
value="<?= $rate_after_hours ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Support Hours</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="support_hours" placeholder="e.g., Mon-Fri 9am-5pm"
|
||||
value="<?= $support_hours ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Net Terms</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-file-invoice-dollar"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="net_terms" placeholder="e.g., Net 30"
|
||||
value="<?= $net_terms ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Details Tab -->
|
||||
<div class="tab-pane fade" id="details" role="tabpanel">
|
||||
<div class="form-group">
|
||||
<label>Contract Details</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-align-left"></i></span>
|
||||
</div>
|
||||
<textarea class="form-control tinymce" rows="6" name="details"
|
||||
placeholder="Enter Contract Details"><?= $details ?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="edit_contract_template" class="btn btn-primary text-bold">
|
||||
<i class="fa fa-check mr-2"></i>Save Changes
|
||||
</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal">
|
||||
<i class="fa fa-times mr-2"></i>Cancel
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
?>
|
||||
@@ -22,7 +22,7 @@ ob_start();
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
|
||||
<input type="hidden" name="payment_method_id" value="<?= $payment_method_id ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
@@ -59,7 +59,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-shopping-cart"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="threshold" placeholder="1000.00">
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="threshold" placeholder="1000.00">
|
||||
</div>
|
||||
<small class="form-text text-muted">Will not show as an option at Checkout if invoice amount is above this number, 0 disables the threshold check.</small>
|
||||
</div>
|
||||
@@ -79,7 +79,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-percent"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="percentage_fee" placeholder="Enter Percentage">
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="percentage_fee" placeholder="Enter Percentage">
|
||||
</div>
|
||||
<small class="form-text text-muted">See <a href="https://stripe.com/pricing" target="_blank">here <i class="fas fa-fw fa-external-link-alt"></i></a> for the latest Stripe Fees.</small>
|
||||
</div>
|
||||
@@ -90,7 +90,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-shopping-cart"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,3}" name="flat_fee" placeholder="0.030">
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,3}" name="flat_fee" placeholder="0.030">
|
||||
</div>
|
||||
<small class="form-text text-muted">See <a href="https://stripe.com/pricing" target="_blank">here <i class="fas fa-fw fa-external-link-alt"></i></a> for the latest Stripe Fees.</small>
|
||||
</div>
|
||||
|
||||
@@ -58,7 +58,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-shopping-cart"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="threshold" placeholder="1000.00" value="<?php echo $threshold; ?>">
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="threshold" placeholder="1000.00" value="<?php echo $threshold; ?>">
|
||||
</div>
|
||||
<small class="form-text text-muted">Will not show as an option at Checkout if above this number</small>
|
||||
</div>
|
||||
@@ -79,7 +79,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-percent"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="percentage_fee" value="<?php echo $percent_fee; ?>" placeholder="Enter Percentage">
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="percentage_fee" value="<?php echo $percent_fee; ?>" placeholder="Enter Percentage">
|
||||
</div>
|
||||
<small class="form-text text-muted">See <a href="https://stripe.com/pricing" target="_blank">here <i class="fas fa-fw fa-external-link-alt"></i></a> for the latest Stripe Fees.</small>
|
||||
</div>
|
||||
@@ -90,7 +90,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-shopping-cart"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,3}" name="flat_fee" value="<?php echo $flat_fee; ?>" placeholder="0.030">
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,3}" name="flat_fee" value="<?php echo $flat_fee; ?>" placeholder="0.030">
|
||||
</div>
|
||||
<small class="form-text text-muted">See <a href="https://stripe.com/pricing" target="_blank">here <i class="fas fa-fw fa-external-link-alt"></i></a> for the latest Stripe Fees.</small>
|
||||
</div>
|
||||
|
||||
@@ -15,6 +15,8 @@ if (isset($_GET['type'])) {
|
||||
$type_display = "Contact";
|
||||
} elseif ($type === 4) {
|
||||
$type_display = "Credential";
|
||||
} elseif ($type === 5) {
|
||||
$type_display = "Asset";
|
||||
}
|
||||
}
|
||||
ob_start();
|
||||
@@ -58,6 +60,7 @@ ob_start();
|
||||
<option value="2">Location Tag</option>
|
||||
<option value="3">Contact Tag</option>
|
||||
<option value="4">Credential Tag</option>
|
||||
<option value="5">Asset Tag</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -86,7 +89,7 @@ ob_start();
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_tag" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</button>
|
||||
<button type="submit" name="add_tag" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create Tag</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -12,11 +12,24 @@ $tag_type = intval($row['tag_type']);
|
||||
$tag_color = nullable_htmlentities($row['tag_color']);
|
||||
$tag_icon = nullable_htmlentities($row['tag_icon']);
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
if ($tag_type == 1) {
|
||||
$tag_type_display = "Client";
|
||||
} elseif ( $tag_type == 2) {
|
||||
$tag_type_display = "Location";
|
||||
} elseif ( $tag_type == 3) {
|
||||
$tag_type_display = "Contact";
|
||||
} elseif ( $tag_type == 4) {
|
||||
$tag_type_display = "Credential";
|
||||
} elseif ( $tag_type == 5) {
|
||||
$tag_type_display = "Asset";
|
||||
} else {
|
||||
$tag_type_display = "Unknown";
|
||||
}
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-tag mr-2"></i>Editing tag: <strong><?php echo $tag_name; ?></strong></h5>
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-tag mr-2"></i><?= $tag_type_display ?> Tag: <strong><?php echo $tag_name; ?></strong></h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
@@ -35,22 +48,6 @@ ob_start();
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Type <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-th"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="type" required>
|
||||
<option value="">- Type -</option>
|
||||
<option value="1" <?php if ($tag_type == 1) { echo "selected"; } ?>>Client Tag</option>
|
||||
<option value="2" <?php if ($tag_type == 2) { echo "selected"; } ?>>Location Tag</option>
|
||||
<option value="3" <?php if ($tag_type == 3) { echo "selected"; } ?>>Contact Tag</option>
|
||||
<option value="4" <?php if ($tag_type == 4) { echo "selected"; } ?>>Credential Tag</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Color <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
@@ -73,7 +70,7 @@ ob_start();
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="edit_tag" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
||||
<button type="submit" name="edit_tag" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save changes</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -1,75 +1,79 @@
|
||||
<div class="modal" id="addTicketTemplateModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-life-ring mr-2"></i>Creating Ticket Template</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-life-ring mr-2"></i>New Ticket Template</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Template Name <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-life-ring"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" placeholder="Template name" maxlength="200" required autofocus>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<div class="modal-body">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Template Name <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-life-ring"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" placeholder="Template name" maxlength="200" required autofocus>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Subject</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="subject" placeholder="Subject" maxlength="500">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<textarea class="form-control tinymceTicket" name="details"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Description</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="description" placeholder="Short description">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Add it to a Project Template?</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-project-diagram"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="project_template">
|
||||
<option value="0">- No -</option>
|
||||
<?php
|
||||
|
||||
$sql_project_templates = mysqli_query($mysqli, "SELECT * FROM project_templates WHERE project_template_archived_at IS NULL ORDER BY project_template_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_project_templates)) {
|
||||
$project_template_id_select = intval($row['project_template_id']);
|
||||
$project_template_name_select = nullable_htmlentities($row['project_template_name']); ?>
|
||||
<option value="<?php echo $project_template_id_select; ?>"><?php echo $project_template_name_select; ?></option>
|
||||
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Subject</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_ticket_template" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
<input type="text" class="form-control" name="subject" placeholder="Subject" maxlength="500">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<textarea class="form-control tinymceTicket" name="details"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Description</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
|
||||
</div>
|
||||
</form>
|
||||
<input type="text" class="form-control" name="description" placeholder="Short description">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Add it to a Project Template?</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-project-diagram"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="project_template">
|
||||
<option value="0">- No -</option>
|
||||
<?php
|
||||
|
||||
$sql_project_templates = mysqli_query($mysqli, "SELECT * FROM project_templates WHERE project_template_archived_at IS NULL ORDER BY project_template_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_project_templates)) {
|
||||
$project_template_id_select = intval($row['project_template_id']);
|
||||
$project_template_name_select = nullable_htmlentities($row['project_template_name']); ?>
|
||||
<option value="<?php echo $project_template_id_select; ?>"><?php echo $project_template_name_select; ?></option>
|
||||
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_ticket_template" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create Template</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -106,12 +106,14 @@ $num_rows = mysqli_num_rows($sql);
|
||||
<i class="fas fa-fw fa-edit mr-2"></i>Edit
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<!-- <a class="dropdown-item text-danger confirm-link" href="post.php?disable_payment_provider=--><?php //echo $provider_id; ?><!--&csrf_token=--><?php //echo $_SESSION['csrf_token'] ?><!--">-->
|
||||
<!-- <i class="fas fa-fw fa-thumbs-down mr-2"></i>Disable-->
|
||||
<!-- </a>-->
|
||||
<!-- <a class="dropdown-item text-danger confirm-link" href="post.php?delete_payment_provider=--><?php //echo $provider_id; ?><!--&csrf_token=--><?php //echo $_SESSION['csrf_token'] ?><!--">-->
|
||||
<!-- <i class="fas fa-fw fa-trash mr-2"></i>Delete-->
|
||||
<!-- </a>-->
|
||||
<a class="dropdown-item text-danger confirm-link" href="post.php?delete_payment_provider=<?= $provider_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
|
||||
<i class="fas fa-fw fa-trash mr-2"></i><strong>Delete Provider and</strong>
|
||||
<ul class="text-xs">
|
||||
<li>Related Recurring Payments</li>
|
||||
<li>Related Saved cards</li>
|
||||
<li>Client Provider Relations</li>
|
||||
</ul>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
@@ -9,11 +9,12 @@ defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
if (isset($_POST['add_contract_template'])) {
|
||||
|
||||
// Sanitize text inputs
|
||||
$name = sanitizeInput($_POST['contract_template_name']);
|
||||
$type = sanitizeInput($_POST['contract_template_type']);
|
||||
$update_frequency = sanitizeInput($_POST['contract_template_update_frequency']);
|
||||
$support_hours = sanitizeInput($_POST['contract_template_support_hours']);
|
||||
$details = mysql_escape_string($mysqli, $_POST['contract_template_details']);
|
||||
$name = sanitizeInput($_POST['name']);
|
||||
$description = sanitizeInput($_POST['description']);
|
||||
$type = sanitizeInput($_POST['type']);
|
||||
$renewal_frequency = sanitizeInput($_POST['renewal_frequency']);
|
||||
$support_hours = sanitizeInput($_POST['support_hours']);
|
||||
$details = mysqli_escape_string($mysqli, $_POST['details']);
|
||||
|
||||
// Numeric fields cast to integer
|
||||
$sla_low_resp = intval($_POST['sla_low_response_time']);
|
||||
@@ -22,9 +23,9 @@ if (isset($_POST['add_contract_template'])) {
|
||||
$sla_low_res = intval($_POST['sla_low_resolution_time']);
|
||||
$sla_med_res = intval($_POST['sla_medium_resolution_time']);
|
||||
$sla_high_res = intval($_POST['sla_high_resolution_time']);
|
||||
$hourly_rate = intval($_POST['contract_template_hourly_rate']);
|
||||
$after_hours_rate = intval($_POST['contract_template_after_hours_hourly_rate']);
|
||||
$net_terms = intval($_POST['contract_template_net_terms']);
|
||||
$rate_standard = intval($_POST['rate_standard']);
|
||||
$rate_after_hours = intval($_POST['hourly_rate_after_hours']);
|
||||
$net_terms = intval($_POST['net_terms']);
|
||||
|
||||
// Insert into database (numbers not quoted)
|
||||
mysqli_query($mysqli, "
|
||||
@@ -33,19 +34,17 @@ if (isset($_POST['add_contract_template'])) {
|
||||
contract_template_description = '$description',
|
||||
contract_template_details = '$details',
|
||||
contract_template_type = '$type',
|
||||
contract_template_update_frequency = '$update_frequency',
|
||||
sla_low_response_time = $sla_low_resp,
|
||||
sla_medium_response_time = $sla_med_resp,
|
||||
sla_high_response_time = $sla_high_resp,
|
||||
sla_low_resolution_time = $sla_low_res,
|
||||
sla_medium_resolution_time = $sla_med_res,
|
||||
sla_high_resolution_time = $sla_high_res,
|
||||
contract_template_hourly_rate = $hourly_rate,
|
||||
contract_template_after_hours_hourly_rate = $after_hours_rate,
|
||||
contract_template_renewal_frequency = '$renewal_frequency',
|
||||
contract_template_sla_low_response_time = $sla_low_resp,
|
||||
contract_template_sla_medium_response_time = $sla_med_resp,
|
||||
contract_template_sla_high_response_time = $sla_high_resp,
|
||||
contract_template_sla_low_resolution_time = $sla_low_res,
|
||||
contract_template_sla_medium_resolution_time = $sla_med_res,
|
||||
contract_template_sla_high_resolution_time = $sla_high_res,
|
||||
contract_template_rate_standard = $rate_standard,
|
||||
contract_template_rate_after_hours = $rate_after_hours,
|
||||
contract_template_support_hours = '$support_hours',
|
||||
contract_template_net_terms = $net_terms,
|
||||
contract_template_created_by = $session_user_id,
|
||||
contract_template_created_at = NOW()
|
||||
contract_template_net_terms = $net_terms
|
||||
");
|
||||
|
||||
$contract_template_id = mysqli_insert_id($mysqli);
|
||||
@@ -60,4 +59,99 @@ if (isset($_POST['add_contract_template'])) {
|
||||
redirect();
|
||||
}
|
||||
|
||||
if (isset($_POST['edit_contract_template'])) {
|
||||
|
||||
$contract_template_id = intval($_POST['contract_template_id']);
|
||||
$name = sanitizeInput($_POST['name']);
|
||||
$description = sanitizeInput($_POST['description']);
|
||||
$type = sanitizeInput($_POST['type']);
|
||||
$renewal_frequency= sanitizeInput($_POST['renewal_frequency']);
|
||||
$support_hours = sanitizeInput($_POST['support_hours']);
|
||||
$details = mysqli_escape_string($mysqli, $_POST['details']);
|
||||
$sla_low_resp = intval($_POST['sla_low_response_time']);
|
||||
$sla_med_resp = intval($_POST['sla_medium_response_time']);
|
||||
$sla_high_resp = intval($_POST['sla_high_response_time']);
|
||||
$sla_low_res = intval($_POST['sla_low_resolution_time']);
|
||||
$sla_med_res = intval($_POST['sla_medium_resolution_time']);
|
||||
$sla_high_res = intval($_POST['sla_high_resolution_time']);
|
||||
$rate_standard = intval($_POST['rate_standard']);
|
||||
$rate_after_hours = intval($_POST['rate_after_hours']);
|
||||
$net_terms = intval($_POST['net_terms']);
|
||||
|
||||
mysqli_query($mysqli, "
|
||||
UPDATE contract_templates SET
|
||||
contract_template_name = '$name',
|
||||
contract_template_description = '$description',
|
||||
contract_template_details = '$details',
|
||||
contract_template_type = '$type',
|
||||
contract_template_renewal_frequency = '$renewal_frequency',
|
||||
contract_template_sla_low_response_time = $sla_low_resp,
|
||||
contract_template_sla_medium_response_time = $sla_med_resp,
|
||||
contract_template_sla_high_response_time = $sla_high_resp,
|
||||
contract_template_sla_low_resolution_time = $sla_low_res,
|
||||
contract_template_sla_medium_resolution_time = $sla_med_res,
|
||||
contract_template_sla_high_resolution_time = $sla_high_res,
|
||||
contract_template_rate_standard = $rate_standard,
|
||||
contract_template_rate_after_hours = $rate_after_hours,
|
||||
contract_template_support_hours = '$support_hours',
|
||||
contract_template_net_terms = $net_terms
|
||||
WHERE contract_template_id = $contract_template_id
|
||||
");
|
||||
|
||||
// Log action
|
||||
logAction("Contract Template", "Update", "$session_name updated contract template $name", 0, $contract_template_id);
|
||||
|
||||
// Flash + redirect
|
||||
flash_alert("Contract Template <strong>$name</strong> updated");
|
||||
redirect();
|
||||
}
|
||||
|
||||
if (isset($_GET['archive_contract_template'])) {
|
||||
$contract_template_id = intval($_GET['archive_contract_template']);
|
||||
|
||||
$name = getFieldById('contract_templates', $contract_template_id, 'contract_template_name');
|
||||
|
||||
mysqli_query($mysqli, "
|
||||
UPDATE contract_templates SET contract_template_archived_at = NOW()
|
||||
WHERE contract_template_id = $contract_template_id
|
||||
LIMIT 1
|
||||
");
|
||||
|
||||
logAction("Contract Template", "Archive", "$session_name archived contract template $name", 0, $contract_template_id);
|
||||
flash_alert("Contract Template <strong>$name</strong> archived", "danger");
|
||||
redirect();
|
||||
}
|
||||
|
||||
if (isset($_GET['restore_contract_template'])) {
|
||||
$contract_template_id = intval($_GET['restore_contract_template']);
|
||||
|
||||
$name = getFieldById('contract_templates', $contract_template_id, 'contract_template_name');
|
||||
|
||||
mysqli_query($mysqli, "
|
||||
UPDATE contract_templates SET contract_template_archived_at = NULL
|
||||
WHERE contract_template_id = $contract_template_id
|
||||
LIMIT 1
|
||||
");
|
||||
|
||||
logAction("Contract Template", "Restore", "$session_name restored contract template $name", 0, $contract_template_id);
|
||||
flash_alert("Contract Template <strong>$name</strong> restored");
|
||||
redirect();
|
||||
}
|
||||
|
||||
if (isset($_GET['delete_contract_template'])) {
|
||||
$contract_template_id = intval($_GET['delete_contract_template']);
|
||||
|
||||
$name = getFieldById('contract_templates', $contract_template_id, 'contract_template_name');
|
||||
|
||||
mysqli_query($mysqli, "
|
||||
DELETE FROM contract_templates
|
||||
WHERE contract_template_id = $contract_template_id
|
||||
LIMIT 1
|
||||
");
|
||||
|
||||
logAction("Contract Template", "Delete", "$session_name deleted contract template $name", 0, $contract_template_id);
|
||||
flash_alert("Contract Template <strong>$name</strong> deleted", "danger");
|
||||
redirect();
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -8,12 +8,24 @@ if (isset($_POST['add_document_template'])) {
|
||||
|
||||
$name = sanitizeInput($_POST['name']);
|
||||
$description = sanitizeInput($_POST['description']);
|
||||
$content = mysqli_real_escape_string($mysqli,$_POST['content']);
|
||||
|
||||
mysqli_query($mysqli,"INSERT INTO document_templates SET document_template_name = '$name', document_template_description = '$description', document_template_content = '$content', document_template_created_by = $session_user_id");
|
||||
mysqli_query($mysqli,"INSERT INTO document_templates SET document_template_name = '$name', document_template_description = '$description', document_template_content = '', document_template_created_by = $session_user_id");
|
||||
|
||||
$document_template_id = mysqli_insert_id($mysqli);
|
||||
|
||||
$processed_content = mysqli_escape_string(
|
||||
$mysqli,
|
||||
saveBase64Images(
|
||||
$_POST['content'],
|
||||
$_SERVER['DOCUMENT_ROOT'] . "/uploads/document_templates/",
|
||||
"uploads/document_templates/",
|
||||
$document_template_id
|
||||
)
|
||||
);
|
||||
|
||||
// Document template update content
|
||||
mysqli_query($mysqli,"UPDATE document_templates SET document_template_content = '$processed_content' WHERE document_template_id = $document_template_id");
|
||||
|
||||
logAction("Document Template", "Create", "$session_name created document template $name", 0, $document_template_id);
|
||||
|
||||
flash_alert("Document template <strong>$name</strong> created");
|
||||
@@ -27,10 +39,25 @@ if (isset($_POST['edit_document_template'])) {
|
||||
$document_template_id = intval($_POST['document_template_id']);
|
||||
$name = sanitizeInput($_POST['name']);
|
||||
$description = sanitizeInput($_POST['description']);
|
||||
$content = mysqli_real_escape_string($mysqli,$_POST['content']);
|
||||
|
||||
$processed_content = saveBase64Images(
|
||||
$_POST['content'],
|
||||
$_SERVER['DOCUMENT_ROOT'] . "/uploads/document_templates/",
|
||||
"uploads/document_templates/",
|
||||
$document_template_id
|
||||
);
|
||||
|
||||
$processed_content_escaped = mysqli_escape_string($mysqli, $processed_content);
|
||||
|
||||
// CLEAN UP unused images
|
||||
cleanupUnusedImages(
|
||||
$processed_content,
|
||||
$_SERVER['DOCUMENT_ROOT'] . "/uploads/document_templates/" . $document_template_id,
|
||||
"/uploads/document_templates/" . $document_template_id
|
||||
);
|
||||
|
||||
// Document edit query
|
||||
mysqli_query($mysqli,"UPDATE document_templates SET document_template_name = '$name', document_template_description = '$description', document_template_content = '$content', document_template_updated_by = $session_user_id WHERE document_template_id = $document_template_id");
|
||||
mysqli_query($mysqli,"UPDATE document_templates SET document_template_name = '$name', document_template_description = '$description', document_template_content = '$processed_content_escaped', document_template_updated_by = $session_user_id WHERE document_template_id = $document_template_id");
|
||||
|
||||
logAction("Document Template", "Edit", "$session_name edited document template $name", 0, $document_template_id);
|
||||
|
||||
@@ -48,6 +75,9 @@ if (isset($_GET['delete_document_template'])) {
|
||||
|
||||
mysqli_query($mysqli,"DELETE FROM document_templates WHERE document_template_id = $document_template_id");
|
||||
|
||||
// Delete uploads/document_templates/$document_template_id if exists
|
||||
removeDirectory($_SERVER['DOCUMENT_ROOT'] . "/uploads/document_templates/" . $document_template_id);
|
||||
|
||||
logAction("Document Template", "Delete", "$session_name deleted document template $document_template_name");
|
||||
|
||||
flash_alert("Document Template <strong>$document_template_name</strong> deleted", 'error');
|
||||
|
||||
@@ -10,10 +10,17 @@ if (isset($_POST['add_payment_method'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$name = sanitizeInput($_POST['name']);
|
||||
$description = sanitizeInput($_POST['description']);
|
||||
$name = cleanInput($_POST['name']);
|
||||
$description = cleanInput($_POST['description']);
|
||||
|
||||
mysqli_query($mysqli,"INSERT INTO payment_methods SET payment_method_name = '$name', payment_method_description = '$description'");
|
||||
$query = mysqli_prepare(
|
||||
$mysqli, "INSERT INTO payment_methods
|
||||
SET payment_method_name = ?, payment_method_description = ?"
|
||||
);
|
||||
|
||||
mysqli_stmt_bind_param($query, "ss", $name, $description);
|
||||
|
||||
mysqli_stmt_execute($query);
|
||||
|
||||
logAction("Payment Method", "Create", "$session_name created Payment Method $name");
|
||||
|
||||
@@ -26,12 +33,21 @@ if (isset($_POST['add_payment_method'])) {
|
||||
if (isset($_POST['edit_payment_method'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
|
||||
$payment_method_id = intval($_POST['payment_method_id']);
|
||||
$name = sanitizeInput($_POST['name']);
|
||||
$description = sanitizeInput($_POST['description']);
|
||||
$name = cleanInput($_POST['name']);
|
||||
$description = cleanInput($_POST['description']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE payment_methods SET payment_method_name = '$name', payment_method_description = '$description' WHERE payment_method_id = $payment_method_id");
|
||||
$query = mysqli_prepare(
|
||||
$mysqli,
|
||||
"UPDATE payment_methods
|
||||
SET payment_method_name = ?, payment_method_description = ?
|
||||
WHERE payment_method_id = ?"
|
||||
);
|
||||
|
||||
mysqli_stmt_bind_param($query, "ssi", $name, $description, $payment_method_id);
|
||||
|
||||
mysqli_stmt_execute($query);
|
||||
|
||||
logAction("Payment Method", "Edit", "$session_name edited Payment Method $name");
|
||||
|
||||
|
||||
@@ -101,6 +101,11 @@ if (isset($_GET['delete_payment_provider'])) {
|
||||
|
||||
$provider_id = intval($_GET['delete_payment_provider']);
|
||||
|
||||
// When deleted it cascades deletes
|
||||
// all Recurring paymentes related to payment provider
|
||||
// Delete all Saved Cards related
|
||||
// Delete Client Payment Provider Releation
|
||||
|
||||
$provider_name = sanitizeInput(getFieldById('payment_providers', $provider_id, 'provider_name'));
|
||||
|
||||
// Delete provider
|
||||
|
||||
@@ -42,7 +42,7 @@ if (isset($_GET['delete_saved_payment'])) {
|
||||
|
||||
try {
|
||||
// Initialize stripe
|
||||
require_once 'plugins/stripe-php/init.php';
|
||||
require_once '../plugins/stripe-php/init.php';
|
||||
$stripe = new \Stripe\StripeClient($private_key);
|
||||
|
||||
// Detach PM
|
||||
@@ -56,7 +56,7 @@ if (isset($_GET['delete_saved_payment'])) {
|
||||
|
||||
}
|
||||
|
||||
// Remove payment method from ITFlow
|
||||
// Remove payment method from ITFlow. This will also cascade delete related recurring payments setup
|
||||
mysqli_query($mysqli, "DELETE FROM client_saved_payment_methods WHERE saved_payment_id = $saved_payment_id");
|
||||
|
||||
// SQL Cascade delete will Remove All Associated Auto Payment Methods on recurring invoices in the recurring payments table.
|
||||
|
||||
@@ -150,7 +150,7 @@ if (isset($_POST['test_email_smtp'])) {
|
||||
$mail = addToMailQueue($data);
|
||||
|
||||
if ($mail === true) {
|
||||
flash_alert("Test email queued! <a class='text-bold text-light' href='admin_mail_queue.php'>Check Admin > Mail queue</a>");
|
||||
flash_alert("Test email queued! <a class='text-bold text-light' href='mail_queue.php'>Check Admin > Mail queue</a>");
|
||||
} else {
|
||||
flash_alert("Failed to add test mail to queue", 'error');
|
||||
}
|
||||
@@ -160,27 +160,128 @@ if (isset($_POST['test_email_smtp'])) {
|
||||
}
|
||||
|
||||
if (isset($_POST['test_email_imap'])) {
|
||||
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
// Setup your IMAP connection parameters
|
||||
$hostname = "{" . $config_imap_host . ":" . $config_imap_port . "/" . $config_imap_encryption . "/novalidate-cert}INBOX";
|
||||
$username = $config_imap_username;
|
||||
$password = $config_imap_password;
|
||||
$host = $config_imap_host;
|
||||
$port = (int) $config_imap_port;
|
||||
$encryption = strtolower(trim($config_imap_encryption)); // e.g. "ssl", "tls", "none"
|
||||
$username = $config_imap_username;
|
||||
$password = $config_imap_password;
|
||||
|
||||
// Build remote socket (implicit SSL vs plain TCP)
|
||||
$transport = 'tcp';
|
||||
if ($encryption === 'ssl') {
|
||||
$transport = 'ssl';
|
||||
}
|
||||
|
||||
$remote_socket = $transport . '://' . $host . ':' . $port;
|
||||
|
||||
// Stream context (you can tighten these if you want strict validation)
|
||||
$contextOptions = [];
|
||||
if (in_array($encryption, ['ssl', 'tls'], true)) {
|
||||
$contextOptions['ssl'] = [
|
||||
'verify_peer' => false,
|
||||
'verify_peer_name' => false,
|
||||
'allow_self_signed' => true,
|
||||
];
|
||||
}
|
||||
|
||||
$context = stream_context_create($contextOptions);
|
||||
|
||||
try {
|
||||
$inbox = @imap_open($hostname, $username, $password);
|
||||
$errno = 0;
|
||||
$errstr = '';
|
||||
|
||||
if ($inbox) {
|
||||
imap_close($inbox);
|
||||
// 10-second timeout, adjust as needed
|
||||
$fp = @stream_socket_client(
|
||||
$remote_socket,
|
||||
$errno,
|
||||
$errstr,
|
||||
10,
|
||||
STREAM_CLIENT_CONNECT,
|
||||
$context
|
||||
);
|
||||
|
||||
if (!$fp) {
|
||||
throw new Exception("Could not connect to IMAP server: [$errno] $errstr");
|
||||
}
|
||||
|
||||
stream_set_timeout($fp, 10);
|
||||
|
||||
// Read server greeting (IMAP servers send something like: * OK Dovecot ready)
|
||||
$greeting = fgets($fp, 1024);
|
||||
if ($greeting === false || strpos($greeting, '* OK') !== 0) {
|
||||
fclose($fp);
|
||||
throw new Exception("Invalid IMAP greeting: " . trim((string) $greeting));
|
||||
}
|
||||
|
||||
// If you really want STARTTLS for "tls" (port 143), you can do it here
|
||||
if ($encryption === 'tls' && stripos($greeting, 'STARTTLS') !== false) {
|
||||
// Request STARTTLS
|
||||
fwrite($fp, "A0001 STARTTLS\r\n");
|
||||
$line = fgets($fp, 1024);
|
||||
if ($line === false || stripos($line, 'A0001 OK') !== 0) {
|
||||
fclose($fp);
|
||||
throw new Exception("STARTTLS failed: " . trim((string) $line));
|
||||
}
|
||||
|
||||
// Enable crypto on the stream
|
||||
if (!stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
|
||||
fclose($fp);
|
||||
throw new Exception("Unable to enable TLS encryption on IMAP connection.");
|
||||
}
|
||||
}
|
||||
|
||||
// --- Do LOGIN command ---
|
||||
$tag = 'A0002';
|
||||
|
||||
// Simple quoting; this may fail with some special chars in username/password.
|
||||
$loginCmd = sprintf(
|
||||
"%s LOGIN \"%s\" \"%s\"\r\n",
|
||||
$tag,
|
||||
addcslashes($username, "\\\""),
|
||||
addcslashes($password, "\\\"")
|
||||
);
|
||||
|
||||
fwrite($fp, $loginCmd);
|
||||
|
||||
$success = false;
|
||||
$errorLine = '';
|
||||
|
||||
while (!feof($fp)) {
|
||||
$line = fgets($fp, 2048);
|
||||
if ($line === false) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Look for tagged response for our LOGIN
|
||||
if (strpos($line, $tag . ' ') === 0) {
|
||||
if (stripos($line, $tag . ' OK') === 0) {
|
||||
$success = true;
|
||||
} else {
|
||||
$errorLine = trim($line);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Always logout / close
|
||||
fwrite($fp, "A0003 LOGOUT\r\n");
|
||||
fclose($fp);
|
||||
|
||||
if ($success) {
|
||||
flash_alert("Connected successfully");
|
||||
} else {
|
||||
throw new Exception(imap_last_error());
|
||||
if (!$errorLine) {
|
||||
$errorLine = 'Unknown IMAP authentication error';
|
||||
}
|
||||
throw new Exception($errorLine);
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
flash_alert("<strong>IMAP connection failed:</strong> " . $e->getMessage(), 'error');
|
||||
flash_alert("<strong>IMAP connection failed:</strong> " . htmlspecialchars($e->getMessage()), 'error');
|
||||
}
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ if (isset($_POST['edit_tag'])) {
|
||||
|
||||
$tag_id = intval($_POST['tag_id']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE tags SET tag_name = '$name', tag_type = $type, tag_color = '$color', tag_icon = '$icon' WHERE tag_id = $tag_id");
|
||||
mysqli_query($mysqli,"UPDATE tags SET tag_name = '$name', tag_color = '$color', tag_icon = '$icon' WHERE tag_id = $tag_id");
|
||||
|
||||
logAction("Tag", "Edit", "$session_name edited tag $name", 0, $tag_id);
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@ require_once "includes/inc_all_admin.php";
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="hourly_rate" value="<?php echo number_format($config_default_hourly_rate, 2, '.', ''); ?>" placeholder="0.00" required>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="hourly_rate" value="<?php echo number_format($config_default_hourly_rate, 2, '.', ''); ?>" placeholder="0.00" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -6,10 +6,31 @@ $order = "ASC";
|
||||
|
||||
require_once "includes/inc_all_admin.php";
|
||||
|
||||
if (isset($_GET['type'])) {
|
||||
$type_filter = intval($_GET['type']);
|
||||
} else {
|
||||
$type_filter = 1;
|
||||
}
|
||||
|
||||
if ($type_filter == 1) {
|
||||
$tag_type_display = "Client";
|
||||
} elseif ( $type_filter == 2) {
|
||||
$tag_type_display = "Location";
|
||||
} elseif ( $type_filter == 3) {
|
||||
$tag_type_display = "Contact";
|
||||
} elseif ( $type_filter == 4) {
|
||||
$tag_type_display = "Credential";
|
||||
} elseif ( $type_filter == 5) {
|
||||
$tag_type_display = "Asset";
|
||||
} else {
|
||||
$tag_type_display = "Unknown";
|
||||
}
|
||||
|
||||
$sql = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT SQL_CALC_FOUND_ROWS * FROM tags
|
||||
WHERE tag_name LIKE '%$q%'
|
||||
AND tag_type = $type_filter
|
||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
||||
);
|
||||
|
||||
@@ -19,9 +40,9 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-tags mr-2"></i>Tags</h3>
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-tags mr-2"></i><?= $tag_type_display ?> Tags</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/tag/tag_add.php"><i class="fas fa-plus mr-2"></i>New Tag</button>
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/tag/tag_add.php?type=<?= $type_filter ?>"><i class="fas fa-plus mr-2"></i>New <?= $tag_type_display ?> Tag</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -30,7 +51,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<div class="col-sm-4 mb-2">
|
||||
<form autocomplete="off">
|
||||
<div class="input-group">
|
||||
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search Tags">
|
||||
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search <?= $tag_type_display ?> Tags">
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-primary"><i class="fa fa-search"></i></button>
|
||||
</div>
|
||||
@@ -38,6 +59,45 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<div class="btn-group float-right">
|
||||
<a href="?type=1"
|
||||
class="btn <?php if ($type_filter == 1) {
|
||||
echo 'btn-primary';
|
||||
} else {
|
||||
echo 'btn-default';
|
||||
} ?>">Client</a>
|
||||
<a href="?type=2"
|
||||
class="btn <?php if ($type_filter == 2) {
|
||||
echo 'btn-primary';
|
||||
} else {
|
||||
echo 'btn-default';
|
||||
} ?>">Location</a>
|
||||
<a href="?type=3"
|
||||
class="btn <?php if ($type_filter == 3) {
|
||||
echo 'btn-primary';
|
||||
} else {
|
||||
echo 'btn-default';
|
||||
} ?>">Contact</a>
|
||||
<a href="?type=4"
|
||||
class="btn <?php if ($type_filter == 4) {
|
||||
echo 'btn-primary';
|
||||
} else {
|
||||
echo 'btn-default';
|
||||
} ?>">Credential</a>
|
||||
<a href="?type=5"
|
||||
class="btn <?php if ($type_filter == 5) {
|
||||
echo 'btn-primary';
|
||||
} else {
|
||||
echo 'btn-default';
|
||||
} ?>">Asset</a>
|
||||
<a href="?<?= $url_query_strings_sort ?>&archived=1"
|
||||
class="btn <?php if (isset($_GET['archived'])) {
|
||||
echo 'btn-primary';
|
||||
} else {
|
||||
echo 'btn-default';
|
||||
} ?>"><i
|
||||
class="fas fa-fw fa-archive mr-2"></i>Archived</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -51,11 +111,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
Name <?php if ($sort == 'tag_name') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=tag_type&order=<?php echo $disp; ?>">
|
||||
Type <?php if ($sort == 'tag_type') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th class="text-center">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -65,18 +120,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
while ($row = mysqli_fetch_array($sql)) {
|
||||
$tag_id = intval($row['tag_id']);
|
||||
$tag_name = nullable_htmlentities($row['tag_name']);
|
||||
$tag_type = intval($row['tag_type']);
|
||||
if ( $tag_type == 1) {
|
||||
$tag_type_display = "Client Tag";
|
||||
} elseif ( $tag_type == 2) {
|
||||
$tag_type_display = "Location Tag";
|
||||
} elseif ( $tag_type == 3) {
|
||||
$tag_type_display = "Contact Tag";
|
||||
} elseif ( $tag_type == 4) {
|
||||
$tag_type_display = "Credential Tag";
|
||||
} else {
|
||||
$tag_type_display = "Unknown Tag";
|
||||
}
|
||||
$tag_color = nullable_htmlentities($row['tag_color']);
|
||||
$tag_icon = nullable_htmlentities($row['tag_icon']);
|
||||
|
||||
@@ -88,7 +131,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<span class='badge text-light p-2 mr-1' style="background-color: <?php echo $tag_color; ?>"><i class="fa fa-fw fa-<?php echo $tag_icon; ?> mr-2"></i><?php echo $tag_name; ?></span>
|
||||
</a>
|
||||
</td>
|
||||
<td><?php echo $tag_type_display; ?></td>
|
||||
<td>
|
||||
<div class="dropdown dropleft text-center">
|
||||
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
|
||||
@@ -117,8 +159,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php require_once "../includes/filter_footer.php";
|
||||
?>
|
||||
<?php require_once "../includes/filter_footer.php"; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-life-ring mr-2"></i>Ticket Templates</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addTicketTemplateModal"><i class="fas fa-plus mr-2"></i>New Ticket Template</button>
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/ticket_template/ticket_template_add.php" data-modal-size="lg"><i class="fas fa-plus mr-2"></i>New Ticket Template</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@@ -120,5 +120,4 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "modals/ticket_template/ticket_template_add.php";
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
@@ -156,7 +156,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
?>
|
||||
<tr>
|
||||
<td class="text-center">
|
||||
<a href="#"
|
||||
<a href="#" title="UserID: <?= $user_id ?>"
|
||||
<?php if ($user_id !== $session_user_id) { // Prevent modifying self ?>
|
||||
class="ajax-modal"
|
||||
data-modal-url="modals/user/user_edit.php?id=<?= $user_id ?>"
|
||||
|
||||
@@ -140,7 +140,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</a>
|
||||
<?php if ($session_user_role == 3) { ?>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_vendor=<?php echo $vendor_template_id; ?>">
|
||||
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_vendor_template=<?= $vendor_template_id ?>">
|
||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||
</a>
|
||||
<?php } ?>
|
||||
|
||||
@@ -118,6 +118,28 @@ if (isset($_GET['asset_id'])) {
|
||||
);
|
||||
$document_count = mysqli_num_rows($sql_related_documents);
|
||||
|
||||
// Tags - many to many relationship
|
||||
$asset_tag_name_display_array = array();
|
||||
$asset_tag_id_array = array();
|
||||
$sql_asset_tags = mysqli_query($mysqli, "SELECT * FROM asset_tags LEFT JOIN tags ON asset_tag_tag_id = tag_id WHERE asset_tag_asset_id = $asset_id ORDER BY tag_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_asset_tags)) {
|
||||
|
||||
$asset_tag_id = intval($row['tag_id']);
|
||||
$asset_tag_name = nullable_htmlentities($row['tag_name']);
|
||||
$asset_tag_color = nullable_htmlentities($row['tag_color']);
|
||||
if (empty($asset_tag_color)) {
|
||||
$asset_tag_color = "dark";
|
||||
}
|
||||
$asset_tag_icon = nullable_htmlentities($row['tag_icon']);
|
||||
if (empty($asset_tag_icon)) {
|
||||
$asset_tag_icon = "tag";
|
||||
}
|
||||
|
||||
$asset_tag_id_array[] = $asset_tag_id;
|
||||
$asset_tag_name_display_array[] = "<a href='client_assets.php?client_id=$client_id&q=$asset_tag_name'><span class='badge text-light p-1 mr-1' style='background-color: $asset_tag_color;'><i class='fa fa-fw fa-$asset_tag_icon mr-2'></i>$asset_tag_name</span></a>";
|
||||
}
|
||||
$asset_tags_display = implode('', $asset_tag_name_display_array);
|
||||
|
||||
// Network Interfaces
|
||||
$sql_related_interfaces = mysqli_query($mysqli, "
|
||||
SELECT
|
||||
@@ -257,8 +279,13 @@ if (isset($_GET['asset_id'])) {
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php if ($asset_tags_display) { ?>
|
||||
<div>
|
||||
<?= $asset_tags_display ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
<?php if ($asset_type) { ?>
|
||||
<div><i class="fa fa-fw fa-tag text-secondary mr-3"></i><?= $asset_type; ?></div>
|
||||
<div class="mt-1"><i class="fa fa-fw fa-tag text-secondary mr-3"></i><?= $asset_type; ?></div>
|
||||
<?php }
|
||||
if ($asset_make) { ?>
|
||||
<div class="mt-2"><i class="fa fa-fw fa-circle text-secondary mr-3"></i><?= "$asset_make $asset_model"; ?></div>
|
||||
|
||||
100
agent/assets.php
100
agent/assets.php
@@ -78,6 +78,18 @@ if ($client_url && isset($_GET['location']) && !empty($_GET['location'])) {
|
||||
$location_filter = 0;
|
||||
}
|
||||
|
||||
// Tags Filter
|
||||
if (isset($_GET['tags']) && is_array($_GET['tags']) && !empty($_GET['tags'])) {
|
||||
// Sanitize each element of the tags array
|
||||
$sanitizedTags = array_map('intval', $_GET['tags']);
|
||||
// Convert the sanitized tags into a comma-separated string
|
||||
$tag_filter = implode(",", $sanitizedTags);
|
||||
$tag_query = "AND tag_id IN ($tag_filter)";
|
||||
} else {
|
||||
$tag_filter = 0;
|
||||
$tag_query = '';
|
||||
}
|
||||
|
||||
//Get Asset Counts
|
||||
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "
|
||||
SELECT
|
||||
@@ -93,9 +105,13 @@ $row = mysqli_fetch_assoc(mysqli_query($mysqli, "
|
||||
LEFT JOIN contacts ON asset_contact_id = contact_id
|
||||
LEFT JOIN locations ON asset_location_id = location_id
|
||||
LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1
|
||||
LEFT JOIN asset_tags ON asset_tag_asset_id = asset_id
|
||||
LEFT JOIN tags ON tag_id = asset_tag_tag_id
|
||||
WHERE $archive_query
|
||||
$tag_query
|
||||
$access_permission_query
|
||||
$client_query
|
||||
GROUP BY asset_id
|
||||
) AS filtered_assets;
|
||||
"));
|
||||
|
||||
@@ -117,9 +133,6 @@ $network_count = intval($row['network_count']);
|
||||
//Other Count
|
||||
$other_count = intval($row['other_count']);
|
||||
|
||||
//Rebuild URL
|
||||
$url_query_strings_sort = http_build_query($get_copy);
|
||||
|
||||
$sql = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT SQL_CALC_FOUND_ROWS * FROM assets
|
||||
@@ -127,13 +140,16 @@ $sql = mysqli_query(
|
||||
LEFT JOIN contacts ON asset_contact_id = contact_id
|
||||
LEFT JOIN locations ON asset_location_id = location_id
|
||||
LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1
|
||||
LEFT JOIN asset_tags ON asset_tag_asset_id = asset_id
|
||||
LEFT JOIN tags ON tag_id = asset_tag_tag_id
|
||||
WHERE $archive_query
|
||||
AND (asset_name LIKE '%$q%' OR asset_description LIKE '%$q%' OR asset_type LIKE '%$q%' OR interface_ip LIKE '%$q%' OR interface_ipv6 LIKE '%$q%' OR interface_mac LIKE '%$q%' OR asset_make LIKE '%$q%' OR asset_model LIKE '%$q%' OR asset_serial LIKE '%$q%' OR asset_os LIKE '%$q%' OR contact_name LIKE '%$q%' OR location_name LIKE '%$q%' OR client_name LIKE '%$q%')
|
||||
$tag_query
|
||||
AND (asset_name LIKE '%$q%' OR asset_description LIKE '%$q%' OR asset_type LIKE '%$q%' OR interface_ip LIKE '%$q%' OR interface_ipv6 LIKE '%$q%' OR interface_mac LIKE '%$q%' OR asset_make LIKE '%$q%' OR asset_model LIKE '%$q%' OR asset_serial LIKE '%$q%' OR asset_os LIKE '%$q%' OR contact_name LIKE '%$q%' OR location_name LIKE '%$q%' OR client_name LIKE '%$q%' OR tag_name LIKE '%$q%')
|
||||
AND ($type_query)
|
||||
$access_permission_query
|
||||
$location_query
|
||||
$client_query
|
||||
|
||||
GROUP BY asset_id
|
||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
||||
);
|
||||
|
||||
@@ -270,7 +286,32 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
<div class="col-md-3">
|
||||
<div class="col-md-2">
|
||||
<div class="input-group mb-3 mb-md-0">
|
||||
<select onchange="this.form.submit()" class="form-control select2" name="tags[]" data-placeholder="- Select Tags -" multiple>
|
||||
|
||||
<?php
|
||||
$sql_tags_filter = mysqli_query($mysqli, "
|
||||
SELECT tag_id, tag_name
|
||||
FROM tags
|
||||
LEFT JOIN asset_tags ON asset_tag_tag_id = tag_id
|
||||
LEFT JOIN assets ON asset_tag_asset_id = asset_id
|
||||
WHERE tag_type = 5
|
||||
$client_query OR tag_id IN ($tag_filter)
|
||||
GROUP BY tag_id
|
||||
HAVING COUNT(asset_tag_asset_id) > 0 OR tag_id IN ($tag_filter)
|
||||
");
|
||||
while ($row = mysqli_fetch_array($sql_tags_filter)) {
|
||||
$tag_id = intval($row['tag_id']);
|
||||
$tag_name = nullable_htmlentities($row['tag_name']); ?>
|
||||
|
||||
<option value="<?php echo $tag_id ?>" <?php if (isset($_GET['tags']) && in_array($tag_id, $_GET['tags'])) { echo 'selected'; } ?>> <?php echo $tag_name ?> </option>
|
||||
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<select onchange="this.form.submit()" class="form-control select2" name="show_column[]" data-placeholder="- Show Additional Columns -" multiple>
|
||||
<option
|
||||
@@ -291,7 +332,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="col-md-2">
|
||||
<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"; } ?>">
|
||||
@@ -314,7 +355,14 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-map-marker-alt mr-2"></i>Assign Location
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<?php } ?>
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/asset/asset_bulk_assign_tags.php"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-tags mr-2"></i>Assign Tags
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/asset/asset_bulk_assign_physical_location.php"
|
||||
data-bulk="true">
|
||||
@@ -576,20 +624,48 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
$sql_credentials = mysqli_query($mysqli, "SELECT * FROM credentials WHERE credential_asset_id = $asset_id");
|
||||
$credential_count = mysqli_num_rows($sql_credentials);
|
||||
|
||||
// Tags
|
||||
$asset_tag_name_display_array = array();
|
||||
$asset_tag_id_array = array();
|
||||
$sql_asset_tags = mysqli_query($mysqli, "SELECT * FROM asset_tags LEFT JOIN tags ON asset_tag_tag_id = tag_id WHERE asset_tag_asset_id = $asset_id ORDER BY tag_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_asset_tags)) {
|
||||
|
||||
$asset_tag_id = intval($row['tag_id']);
|
||||
$asset_tag_name = nullable_htmlentities($row['tag_name']);
|
||||
$asset_tag_color = nullable_htmlentities($row['tag_color']);
|
||||
if (empty($asset_tag_color)) {
|
||||
$asset_tag_color = "dark";
|
||||
}
|
||||
$asset_tag_icon = nullable_htmlentities($row['tag_icon']);
|
||||
if (empty($asset_tag_icon)) {
|
||||
$asset_tag_icon = "tag";
|
||||
}
|
||||
|
||||
$asset_tag_id_array[] = $asset_tag_id;
|
||||
$asset_tag_name_display_array[] = "<a href='assets.php?$client_url tags[]=$asset_tag_id'><span class='badge text-light p-1 mr-1' style='background-color: $asset_tag_color;'><i class='fa fa-fw fa-$asset_tag_icon mr-2'></i>$asset_tag_name</span></a>";
|
||||
}
|
||||
$asset_tags_display = implode('', $asset_tag_name_display_array);
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<td class="pr-0 bg-light">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input bulk-select" type="checkbox" name="asset_ids[]" value="<?php echo $asset_id ?>">
|
||||
<input class="form-check-input bulk-select" type="checkbox" name="asset_ids[]" value="<?= $asset_id ?>">
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<a class="text-dark" href="asset_details.php?client_id=<?php echo $client_id; ?>&asset_id=<?php echo $asset_id; ?>">
|
||||
<a class="text-dark" href="asset_details.php?client_id=<?= $client_id ?>&asset_id=<?= $asset_id ?>">
|
||||
<div class="media">
|
||||
<i class="fa fa-fw fa-2x fa-<?php echo $device_icon; ?> mr-3 mt-1"></i>
|
||||
<i class="fa fa-fw fa-2x fa-<?= $device_icon ?> mr-3 mt-1"></i>
|
||||
<div class="media-body">
|
||||
<div><?php echo $asset_name; ?></div>
|
||||
<div><small class="text-secondary"><?php echo $asset_description; ?></small></div>
|
||||
<div><?= $asset_name ?></div>
|
||||
<div><small class="text-secondary"><?= $asset_description ?></small></div>
|
||||
<?php
|
||||
if ($asset_tags_display) { ?>
|
||||
<div class="mt-1">
|
||||
<?= $asset_tags_display ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
@@ -64,7 +64,14 @@ if (isset($_GET['contact_id'])) {
|
||||
}
|
||||
|
||||
// Related Assets Query - 1 to 1 relationship
|
||||
$sql_related_assets = mysqli_query($mysqli, "SELECT * FROM assets LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1 WHERE asset_contact_id = $contact_id ORDER BY asset_name DESC");
|
||||
$sql_related_assets = mysqli_query($mysqli, "SELECT * FROM assets
|
||||
LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1
|
||||
LEFT JOIN asset_tags ON asset_tag_asset_id = asset_id
|
||||
LEFT JOIN tags ON tag_id = asset_tag_tag_id
|
||||
WHERE asset_contact_id = $contact_id
|
||||
GROUP BY asset_id
|
||||
ORDER BY asset_name ASC"
|
||||
);
|
||||
$asset_count = mysqli_num_rows($sql_related_assets);
|
||||
|
||||
// Linked Software Licenses
|
||||
@@ -90,7 +97,7 @@ if (isset($_GET['contact_id'])) {
|
||||
LEFT JOIN tags ON tags.tag_id = credential_tags.tag_id
|
||||
WHERE credential_contact_id = $contact_id
|
||||
GROUP BY credentials.credential_id
|
||||
ORDER BY credential_name DESC
|
||||
ORDER BY credential_name ASC
|
||||
");
|
||||
$credential_count = mysqli_num_rows($sql_related_credentials);
|
||||
|
||||
@@ -401,6 +408,28 @@ if (isset($_GET['contact_id'])) {
|
||||
$asset_created_at = nullable_htmlentities($row['asset_created_at']);
|
||||
$device_icon = getAssetIcon($asset_type);
|
||||
|
||||
// Tags
|
||||
$asset_tag_name_display_array = array();
|
||||
$asset_tag_id_array = array();
|
||||
$sql_asset_tags = mysqli_query($mysqli, "SELECT * FROM asset_tags LEFT JOIN tags ON asset_tag_tag_id = tag_id WHERE asset_tag_asset_id = $asset_id ORDER BY tag_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_asset_tags)) {
|
||||
|
||||
$asset_tag_id = intval($row['tag_id']);
|
||||
$asset_tag_name = nullable_htmlentities($row['tag_name']);
|
||||
$asset_tag_color = nullable_htmlentities($row['tag_color']);
|
||||
if (empty($asset_tag_color)) {
|
||||
$asset_tag_color = "dark";
|
||||
}
|
||||
$asset_tag_icon = nullable_htmlentities($row['tag_icon']);
|
||||
if (empty($asset_tag_icon)) {
|
||||
$asset_tag_icon = "tag";
|
||||
}
|
||||
|
||||
$asset_tag_id_array[] = $asset_tag_id;
|
||||
$asset_tag_name_display_array[] = "<a href='assets.php?$client_url tags[]=$asset_tag_id'><span class='badge text-light p-1 mr-1' style='background-color: $asset_tag_color;'><i class='fa fa-fw fa-$asset_tag_icon mr-2'></i>$asset_tag_name</span></a>";
|
||||
}
|
||||
$asset_tags_display = implode('', $asset_tag_name_display_array);
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<th>
|
||||
@@ -413,6 +442,12 @@ if (isset($_GET['contact_id'])) {
|
||||
<div class="mt-0">
|
||||
<small class="text-muted"><?php echo $asset_description; ?></small>
|
||||
</div>
|
||||
<?php
|
||||
if ($asset_tags_display) { ?>
|
||||
<div class="mt-1">
|
||||
<?= $asset_tags_display ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</th>
|
||||
<td><?php echo $asset_type; ?></td>
|
||||
<td>
|
||||
|
||||
@@ -729,13 +729,22 @@ if ($user_config_dashboard_technical_enable == 1) {
|
||||
$client_name = nullable_htmlentities($row['client_name']);
|
||||
$contact_id = intval($row['ticket_contact_id']);
|
||||
$contact_name = nullable_htmlentities($row['contact_name']);
|
||||
if ($client_id) {
|
||||
$has_client = "&client_id=$client_id";
|
||||
} else {
|
||||
$has_client = "";
|
||||
}
|
||||
|
||||
$ticket_priority_color = $ticket_priority == "High" ? "danger" : ($ticket_priority == "Medium" ? "warning" : "info");
|
||||
$contact_display = empty($contact_name) ? "-" : "<a href='contact_details.php?client_id=$client_id&contact_id=$contact_id'>$contact_name</a>";
|
||||
?>
|
||||
<tr class="<?php echo empty($ticket_updated_at) ? 'text-bold' : ''; ?>">
|
||||
<td><a class="text-dark" href="ticket.php?client_id=<?= $client_id ?>&ticket_id=<?php echo $ticket_id; ?>"><?php echo "$ticket_prefix$ticket_number"; ?></a></td>
|
||||
<td><a href="ticket.php?client_id=<?= $client_id ?>&ticket_id=<?php echo $ticket_id; ?>"><?php echo $ticket_subject; ?></a></td>
|
||||
<td>
|
||||
<a class="text-dark"
|
||||
href="ticket.php?ticket_id=<?= "$ticket_id$has_client" ?>"><?= "$ticket_prefix$ticket_number" ?>
|
||||
</a>
|
||||
</td>
|
||||
<td><a href="ticket.php?ticket_id=<?= "$ticket_id$has_client" ?>"><?= $ticket_subject ?></a></td>
|
||||
<td><a href="tickets.php?client_id=<?php echo $client_id; ?>"><strong><?php echo $client_name; ?></strong></a></td>
|
||||
<td><?php echo $contact_display; ?></td>
|
||||
<td><span class='p-2 badge badge-pill badge-<?php echo $ticket_priority_color; ?>'><?php echo $ticket_priority; ?></span></td>
|
||||
|
||||
@@ -104,18 +104,31 @@ $page_title = $row['document_name'];
|
||||
<div class="col-md-9">
|
||||
<div class="card">
|
||||
<div class="card-header bg-dark">
|
||||
|
||||
<h3><?php echo $document_name; ?> <?php if (!empty($document_description)) { ?><span class="h6 text-muted">(<?php echo $document_description; ?>)</span><?php } ?></h3>
|
||||
|
||||
<div class="row">
|
||||
<div class="col"><strong>Date:</strong> <?php echo date('Y-m-d', strtotime($document_created_at)); ?></div>
|
||||
<?php if(!empty($document_created_by_name)){ ?>
|
||||
<div class="col"><strong>Prepared By:</strong> <?php echo $document_created_by_name; ?></div>
|
||||
<?php } ?>
|
||||
<div class="col">
|
||||
<div class="h4 mb-0"><?= $document_name ?></div>
|
||||
<?php if ($document_description) { ?>
|
||||
<div class="text-light"><?= $document_description ?></div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="float-right">
|
||||
<div>
|
||||
Date:
|
||||
<strong><?= date('Y-m-d', strtotime($document_created_at)); ?></strong>
|
||||
</div>
|
||||
<?php if($document_created_by_name) { ?>
|
||||
<div>
|
||||
Prepared By:
|
||||
<strong><?= $document_created_by_name ?></strong>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body prettyContent">
|
||||
<?php echo $document_content; ?>
|
||||
<?= $document_content ?>
|
||||
<hr>
|
||||
<h4>Documentation Revision History</h4>
|
||||
|
||||
@@ -151,11 +164,11 @@ $page_title = $row['document_name'];
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<td><?php echo $document_version_count; ?></td>
|
||||
<td><?php echo $document_version_created_date; ?></td>
|
||||
<td><?php echo $document_version_name; ?></td>
|
||||
<td><?php echo $document_version_description_display; ?></td>
|
||||
<td><?php echo $document_version_author; ?></td>
|
||||
<td><?= $document_version_count ?></td>
|
||||
<td><?= $document_version_created_date ?></td>
|
||||
<td><?= $document_version_name ?></td>
|
||||
<td><?= $document_version_description_display ?></td>
|
||||
<td><?= $document_version_author ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
$document_version_count++; // Increment the counter
|
||||
@@ -176,10 +189,10 @@ $page_title = $row['document_name'];
|
||||
<i class="fas fa-fw fa-edit" title="Edit"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-secondary mr-1" data-toggle="modal" data-target="#shareModal"
|
||||
onclick="populateShareModal(<?php echo "$client_id, 'Document', $document_id"; ?>)">
|
||||
onclick="populateShareModal(<?= "$client_id, 'Document', $document_id"; ?>)">
|
||||
<i class="fas fa-fw fa-share" title="Share"></i>
|
||||
</button>
|
||||
<a class="btn btn-success mr-1" href="post.php?export_document=<?php echo $document_id; ?>"><i class='fas fa-fw fa-file-pdf' title="PDF Export"></i></a>
|
||||
<a class="btn btn-success mr-1" href="post.php?export_document=<?= $document_id ?>"><i class='fas fa-fw fa-file-pdf' title="PDF Export"></i></a>
|
||||
<button type="button" class="btn btn-secondary mr-4" onclick="window.print();"><i class="fas fa-fw fa-print" title="Print"></i></button>
|
||||
<a class="btn btn-warning mr-1 confirm-link" href="post.php?archive_document=<?= $document_id ?>" title="Archive"><i class='fas fa-fw fa-archive'></i></a>
|
||||
<a class="btn btn-danger confirm-link" href="post.php?delete_document=<?= $document_id ?>&from=document_details" title="Delete"><i class='fas fa-fw fa-trash-alt'></i></a>
|
||||
|
||||
@@ -23,9 +23,6 @@ if (!empty($q)) {
|
||||
$query_snippet = ""; // empty
|
||||
}
|
||||
|
||||
//Rebuild URL
|
||||
$url_query_strings_sort = http_build_query($get_copy);
|
||||
|
||||
// Folder ID
|
||||
$get_folder_id = 0;
|
||||
if (!empty($_GET['folder_id'])) {
|
||||
|
||||
1169
agent/files.php
1169
agent/files.php
File diff suppressed because it is too large
Load Diff
622
agent/files_legacy.php
Normal file
622
agent/files_legacy.php
Normal file
@@ -0,0 +1,622 @@
|
||||
<?php
|
||||
|
||||
// Default Column Sortby Filter
|
||||
$sort = "file_name";
|
||||
$order = "ASC";
|
||||
|
||||
require_once "includes/inc_all_client.php";
|
||||
|
||||
|
||||
// Folder
|
||||
if (!empty($_GET['folder_id'])) {
|
||||
$folder_id = intval($_GET['folder_id']);
|
||||
} else {
|
||||
$folder_id = 0;
|
||||
}
|
||||
|
||||
// Folder ID
|
||||
$get_folder_id = 0;
|
||||
if (!empty($_GET['folder_id'])) {
|
||||
$get_folder_id = intval($_GET['folder_id']);
|
||||
}
|
||||
|
||||
// View Mode -- 0 List, 1 Thumbnail
|
||||
if (!empty($_GET['view'])) {
|
||||
$view = intval($_GET['view']);
|
||||
} else {
|
||||
$view = 0;
|
||||
}
|
||||
|
||||
if ($view == 1) {
|
||||
$query_images = "AND (file_ext LIKE 'JPG' OR file_ext LIKE 'jpg' OR file_ext LIKE 'JPEG' OR file_ext LIKE 'jpeg' OR file_ext LIKE 'png' OR file_ext LIKE 'PNG' OR file_ext LIKE 'webp' OR file_ext LIKE 'WEBP')";
|
||||
} else {
|
||||
$query_images = '';
|
||||
}
|
||||
|
||||
// Set Folder Location Var used when creating folders
|
||||
$folder_location = 1;
|
||||
|
||||
if ($get_folder_id == 0 && isset($_GET["q"])) {
|
||||
$sql = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT SQL_CALC_FOUND_ROWS * FROM files
|
||||
LEFT JOIN users ON file_created_by = user_id
|
||||
WHERE file_client_id = $client_id
|
||||
AND file_archived_at IS NULL
|
||||
AND (file_name LIKE '%$q%' OR file_ext LIKE '%$q%' OR file_description LIKE '%$q%')
|
||||
$query_images
|
||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
||||
);
|
||||
}else{
|
||||
$sql = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT SQL_CALC_FOUND_ROWS * FROM files
|
||||
LEFT JOIN users ON file_created_by = user_id
|
||||
WHERE file_client_id = $client_id
|
||||
AND file_folder_id = $folder_id
|
||||
AND file_archived_at IS NULL
|
||||
AND (file_name LIKE '%$q%' OR file_ext LIKE '%$q%' OR file_description LIKE '%$q%')
|
||||
$query_images
|
||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
||||
);
|
||||
}
|
||||
|
||||
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
|
||||
$num_of_files = mysqli_num_rows($sql);
|
||||
|
||||
// Breadcrumbs
|
||||
// Build the full folder path
|
||||
$folder_id = $get_folder_id;
|
||||
$folder_path = array();
|
||||
|
||||
while ($folder_id > 0) {
|
||||
$sql_folder = mysqli_query($mysqli, "SELECT folder_name, parent_folder FROM folders WHERE folder_id = $folder_id");
|
||||
if ($row_folder = mysqli_fetch_assoc($sql_folder)) {
|
||||
$folder_name = nullable_htmlentities($row_folder['folder_name']);
|
||||
$parent_folder = intval($row_folder['parent_folder']);
|
||||
|
||||
// Prepend the folder to the beginning of the array
|
||||
array_unshift($folder_path, array('folder_id' => $folder_id, 'folder_name' => $folder_name));
|
||||
|
||||
// Move up to the parent folder
|
||||
$folder_id = $parent_folder;
|
||||
} else {
|
||||
// If the folder is not found, break the loop
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fa fa-fw fa-paperclip mr-2"></i>Files</h3>
|
||||
|
||||
<div class="card-tools">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/file/file_upload.php?client_id=<?= $client_id ?>&folder_id=<?= $get_folder_id ?>">
|
||||
<i class="fas fa-fw fa-cloud-upload-alt mr-2"></i>Upload
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item text-dark ajax-modal" href="#" data-modal-url="modals/folder/folder_add.php?client_id=<?= $client_id ?>&folder_location=1¤t_folder_id=<?= $get_folder_id ?>">
|
||||
<i class="fa fa-fw fa-folder-plus mr-2"></i>New Folder
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-3 border-right mb-3">
|
||||
<h4>Folders</h4>
|
||||
<hr>
|
||||
<ul class="nav nav-pills flex-column bg-light">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link <?php if ($get_folder_id == 0) { echo "active"; } ?>" href="?client_id=<?php echo $client_id; ?>&folder_id=0">/</a>
|
||||
</li>
|
||||
<?php
|
||||
// Function to check if a folder is an ancestor of the current folder
|
||||
function is_ancestor_folder($folder_id, $current_folder_id, $client_id) {
|
||||
global $mysqli;
|
||||
|
||||
// Base case: if current_folder_id is 0 or equal to folder_id
|
||||
if ($current_folder_id == 0) {
|
||||
return false;
|
||||
}
|
||||
if ($current_folder_id == $folder_id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get the parent folder of the current folder
|
||||
$result = mysqli_query($mysqli, "SELECT parent_folder FROM folders WHERE folder_id = $current_folder_id AND folder_client_id = $client_id");
|
||||
if ($row = mysqli_fetch_assoc($result)) {
|
||||
$parent_folder_id = intval($row['parent_folder']);
|
||||
// Recursive call to check the parent folder
|
||||
return is_ancestor_folder($folder_id, $parent_folder_id, $client_id);
|
||||
} else {
|
||||
// Folder not found
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Recursive function to display folders and subfolders
|
||||
function display_folders($parent_folder_id, $client_id, $indent = 0) {
|
||||
global $mysqli, $get_folder_id, $session_user_role;
|
||||
|
||||
$sql_folders = mysqli_query($mysqli, "SELECT * FROM folders WHERE parent_folder = $parent_folder_id AND folder_location = 1 AND folder_client_id = $client_id ORDER BY folder_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_folders)) {
|
||||
$folder_id = intval($row['folder_id']);
|
||||
$folder_name = nullable_htmlentities($row['folder_name']);
|
||||
|
||||
// Get the number of files in the folder
|
||||
$row2 = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('file_id') AS num FROM files WHERE file_folder_id = $folder_id AND file_archived_at IS NULL"));
|
||||
$num_files = intval($row2['num']);
|
||||
|
||||
// Get the number of subfolders
|
||||
$subfolder_result = mysqli_query($mysqli, "SELECT COUNT(*) AS count FROM folders WHERE parent_folder = $folder_id AND folder_client_id = $client_id");
|
||||
$subfolder_count = intval(mysqli_fetch_assoc($subfolder_result)['count']);
|
||||
|
||||
echo '<li class="nav-item">';
|
||||
echo '<div class="row">';
|
||||
echo '<div class="col-10">';
|
||||
echo '<a class="nav-link ';
|
||||
if ($get_folder_id == $folder_id) { echo "active"; }
|
||||
echo '" href="?client_id=' . $client_id . '&folder_id=' . $folder_id . '">';
|
||||
|
||||
// Indentation for subfolders
|
||||
echo str_repeat(' ', $indent * 4);
|
||||
|
||||
// Determine if the folder is open
|
||||
if ($get_folder_id == $folder_id || is_ancestor_folder($folder_id, $get_folder_id, $client_id)) {
|
||||
echo '<i class="fas fa-fw fa-folder-open"></i>';
|
||||
} else {
|
||||
echo '<i class="fas fa-fw fa-folder"></i>';
|
||||
}
|
||||
|
||||
echo ' ' . $folder_name;
|
||||
|
||||
if ($num_files > 0) {
|
||||
echo "<span class='badge badge-pill badge-dark float-right mt-1'>$num_files</span>";
|
||||
}
|
||||
|
||||
echo '</a>';
|
||||
echo '</div>';
|
||||
echo '<div class="col-2">';
|
||||
?>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-sm" type="button" data-toggle="dropdown">
|
||||
<i class="fas fa-ellipsis-v"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/folder/folder_rename.php?id=<?= $folder_id ?>">
|
||||
<i class="fas fa-fw fa-edit mr-2"></i>Rename
|
||||
</a>
|
||||
<?php
|
||||
// Only show delete option if user is admin, folder has no files, and no subfolders
|
||||
if ($session_user_role == 3 && $num_files == 0 && $subfolder_count == 0) { ?>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_folder=<?php echo $folder_id; ?>">
|
||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||
</a>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
echo '</div>';
|
||||
echo '</div>';
|
||||
|
||||
if ($subfolder_count > 0) {
|
||||
// Display subfolders
|
||||
echo '<ul class="nav nav-pills flex-column bg-light">';
|
||||
display_folders($folder_id, $client_id, $indent + 1);
|
||||
echo '</ul>';
|
||||
}
|
||||
|
||||
echo '</li>';
|
||||
}
|
||||
}
|
||||
|
||||
// Start displaying folders from the root (parent_folder = 0)
|
||||
display_folders(0, $client_id);
|
||||
?>
|
||||
</ul>
|
||||
<?php //require_once "modals/folder/folder_add.php"; ?>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-md-9">
|
||||
|
||||
<form autocomplete="off">
|
||||
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
|
||||
<input type="hidden" name="view" value="<?php echo $view; ?>">
|
||||
<input type="hidden" name="folder_id" value="<?php echo $get_folder_id; ?>">
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
<div class="input-group mb-3 mb-md-0">
|
||||
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search for files in <?php if($get_folder_id == 0) { echo "all folders"; } else { echo "current folder"; } ?>">
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-dark"><i class="fa fa-search"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-7">
|
||||
<div class="btn-group float-right">
|
||||
<a href="?<?php echo $url_query_strings_sort; ?>&view=0" class="btn <?php if($view == 0){ echo "btn-primary"; } else { echo "btn-outline-secondary"; } ?>"><i class="fas fa-list-ul"></i></a>
|
||||
<a href="?<?php echo $url_query_strings_sort; ?>&view=1" class="btn <?php if($view == 1){ echo "btn-primary"; } else { echo "btn-outline-secondary"; } ?>"><i class="fas fa-th-large"></i></a>
|
||||
|
||||
<div class="dropdown ml-2" id="bulkActionButton" hidden>
|
||||
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">
|
||||
<i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>)
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/file/file_bulk_move.php?client_id=<?= $client_id ?>"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-exchange-alt mr-2"></i>Move
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<button class="dropdown-item text-danger text-bold"
|
||||
type="submit" form="bulkActions" name="bulk_delete_files">
|
||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<nav class="mt-3">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="?client_id=<?php echo $client_id; ?>&folder_id=0">
|
||||
<i class="fas fa-fw fa-folder mr-2"></i>Root
|
||||
</a>
|
||||
</li>
|
||||
<?php
|
||||
// Output breadcrumb items for each folder in the path
|
||||
foreach ($folder_path as $folder) {
|
||||
$bread_crumb_folder_id = $folder['folder_id']; // Already Sanitized before it was pushed into array
|
||||
$bread_crumb_folder_name = $folder['folder_name']; // Already Sanitized before it was pushed into array
|
||||
|
||||
?>
|
||||
<li class="breadcrumb-item">
|
||||
<a href="?client_id=<?php echo $client_id; ?>&folder_id=<?php echo $bread_crumb_folder_id; ?>">
|
||||
<i class="fas fa-fw fa-folder-open mr-2"></i><?php echo $bread_crumb_folder_name; ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<hr>
|
||||
|
||||
<?php
|
||||
|
||||
if($view == 1){
|
||||
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<?php
|
||||
$files = [];
|
||||
while ($row = mysqli_fetch_array($sql)) {
|
||||
$file_id = intval($row['file_id']);
|
||||
$file_name = nullable_htmlentities($row['file_name']);
|
||||
$file_reference_name = nullable_htmlentities($row['file_reference_name']);
|
||||
$file_ext = nullable_htmlentities($row['file_ext']);
|
||||
$file_size = intval($row['file_size']);
|
||||
$file_size_KB = number_format($file_size / 1024);
|
||||
$file_mime_type = nullable_htmlentities($row['file_mime_type']);
|
||||
$file_uploaded_by = nullable_htmlentities($row['user_name']);
|
||||
|
||||
// Store file data into an array for JS
|
||||
$files[] = [
|
||||
'id' => $file_id,
|
||||
'name' => $file_name,
|
||||
'preview' => "../uploads/clients/$client_id/$file_reference_name"
|
||||
];
|
||||
|
||||
?>
|
||||
|
||||
<div class="col-xl-2 col-lg-2 col-md-6 col-sm-6 mb-3 text-center">
|
||||
|
||||
<a href="#" onclick="openModal(<?php echo count($files)-1; ?>)"><!-- passing the index -->
|
||||
<img class="img-thumbnail" src="<?php echo "../uploads/clients/$client_id/$file_reference_name"; ?>" alt="<?php echo $file_reference_name ?>">
|
||||
</a>
|
||||
|
||||
<div>
|
||||
|
||||
<div class="dropdown float-right">
|
||||
<button class="btn btn-link btn-sm" type="button" data-toggle="dropdown">
|
||||
<i class="fas fa-ellipsis-v"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="<?php echo "../uploads/clients/$client_id/$file_reference_name"; ?>" download="<?php echo $file_name; ?>">
|
||||
<i class="fas fa-fw fa-cloud-download-alt mr-2"></i>Download
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#shareModal" onclick="populateShareModal(<?php echo "$client_id, 'File', $file_id"; ?>)">
|
||||
<i class="fas fa-fw fa-share mr-2"></i>Share
|
||||
</a>
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/file/file_rename.php?id=<?= $file_id ?>">
|
||||
<i class="fas fa-fw fa-edit mr-2"></i>Rename
|
||||
</a>
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/file/file_move.php?id=<?= $file_id ?>">
|
||||
<i class="fas fa-fw fa-exchange-alt mr-2"></i>Move
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#linkAssetToFileModal<?php echo $file_id; ?>">
|
||||
<i class="fas fa-fw fa-desktop mr-2"></i>Asset
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_file=<?php echo $file_id; ?>">
|
||||
<i class="fas fa-fw fa-archive mr-2"></i>Archive
|
||||
</a>
|
||||
<?php if ($session_user_role == 3) { ?>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-danger text-bold" href="#" data-toggle="modal" data-target="#deleteFileModal" onclick="populateFileDeleteModal(<?php echo "$file_id , '$file_name'" ?>)">
|
||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||
</a>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
<small class="text-secondary"><?php echo $file_name; ?></small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require "modals/file/file_view.php";
|
||||
|
||||
}
|
||||
?>
|
||||
<script>
|
||||
// Pass PHP array to JavaScript
|
||||
var files = <?php echo json_encode($files); ?>;
|
||||
var currentIndex = 0; // Keep track of which file is displayed
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<?php } else { ?>
|
||||
|
||||
<form id="bulkActions" action="post.php" method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table border">
|
||||
|
||||
<thead class="thead-light <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
|
||||
<tr>
|
||||
<td class="bg-light pr-0">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" id="selectAllCheckbox" type="checkbox" onclick="checkAll(this)">
|
||||
</div>
|
||||
</td>
|
||||
<th>
|
||||
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=file_name&order=<?php echo $disp; ?>">
|
||||
Name <?php if ($sort == 'file_name') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=file_mime_type&order=<?php echo $disp; ?>">
|
||||
Type <?php if ($sort == 'file_mime_type') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=file_size&order=<?php echo $disp; ?>">
|
||||
Size <?php if ($sort == 'file_size') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=file_created_at&order=<?php echo $disp; ?>">
|
||||
Uploaded <?php if ($sort == 'file_created_at') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th></th>
|
||||
<th class="text-center">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
<?php
|
||||
while ($row = mysqli_fetch_array($sql)) {
|
||||
$file_id = intval($row['file_id']);
|
||||
$file_name = nullable_htmlentities($row['file_name']);
|
||||
$file_description = nullable_htmlentities($row['file_description']);
|
||||
$file_reference_name = nullable_htmlentities($row['file_reference_name']);
|
||||
$file_ext = nullable_htmlentities($row['file_ext']);
|
||||
if ($file_ext == 'pdf') {
|
||||
$file_icon = "file-pdf";
|
||||
} elseif ($file_ext == 'gz' || $file_ext == 'tar' || $file_ext == 'zip' || $file_ext == '7z' || $file_ext == 'rar') {
|
||||
$file_icon = "file-archive";
|
||||
} elseif ($file_ext == 'txt' || $file_ext == 'md') {
|
||||
$file_icon = "file-alt";
|
||||
} elseif ($file_ext == 'msg') {
|
||||
$file_icon = "envelope";
|
||||
} elseif ($file_ext == 'doc' || $file_ext == 'docx' || $file_ext == 'odt') {
|
||||
$file_icon = "file-word";
|
||||
} elseif ($file_ext == 'xls' || $file_ext == 'xlsx' || $file_ext == 'ods') {
|
||||
$file_icon = "file-excel";
|
||||
} elseif ($file_ext == 'pptx' || $file_ext == 'odp') {
|
||||
$file_icon = "file-powerpoint";
|
||||
} elseif ($file_ext == 'mp3' || $file_ext == 'wav' || $file_ext == 'ogg') {
|
||||
$file_icon = "file-audio";
|
||||
} elseif ($file_ext == 'mov' || $file_ext == 'mp4' || $file_ext == 'av1') {
|
||||
$file_icon = "file-video";
|
||||
} elseif ($file_ext == 'jpg' || $file_ext == 'jpeg' || $file_ext == 'png' || $file_ext == 'gif' || $file_ext == 'webp' || $file_ext == 'bmp' || $file_ext == 'tif') {
|
||||
$file_icon = "file-image";
|
||||
} else {
|
||||
$file_icon = "file";
|
||||
}
|
||||
$file_size = intval($row['file_size']);
|
||||
$file_size_KB = number_format($file_size / 1024);
|
||||
$file_mime_type = nullable_htmlentities($row['file_mime_type']);
|
||||
$file_size = intval($row['file_size']);
|
||||
$file_uploaded_by = nullable_htmlentities($row['user_name']);
|
||||
$file_created_at = nullable_htmlentities($row['file_created_at']);
|
||||
$file_folder_id = intval($row['file_folder_id']);
|
||||
|
||||
// Check if shared
|
||||
$sql_shared = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT * FROM shared_items
|
||||
WHERE item_client_id = $client_id
|
||||
AND item_active = 1
|
||||
AND item_views != item_view_limit
|
||||
AND item_expire_at > NOW()
|
||||
AND item_type = 'File'
|
||||
AND item_related_id = $file_id
|
||||
LIMIT 1"
|
||||
);
|
||||
$file_shared = (mysqli_num_rows($sql_shared) > 0) ? true : false;
|
||||
if ($file_shared) {
|
||||
$row = mysqli_fetch_array($sql_shared);
|
||||
$item_id = intval($row['item_id']);
|
||||
$item_active = nullable_htmlentities($row['item_active']);
|
||||
$item_key = nullable_htmlentities($row['item_key']);
|
||||
$item_type = nullable_htmlentities($row['item_type']);
|
||||
$item_related_id = intval($row['item_related_id']);
|
||||
$item_note = nullable_htmlentities($row['item_note']);
|
||||
$item_recipient = nullable_htmlentities($row['item_recipient']);
|
||||
$item_views = nullable_htmlentities($row['item_views']);
|
||||
$item_view_limit = nullable_htmlentities($row['item_view_limit']);
|
||||
$item_created_at = nullable_htmlentities($row['item_created_at']);
|
||||
$item_expire_at = nullable_htmlentities($row['item_expire_at']);
|
||||
$item_expire_at_human = timeAgo($row['item_expire_at']);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<tr>
|
||||
<td class="bg-light pr-0">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input bulk-select" type="checkbox" name="file_ids[]" value="<?php echo $file_id ?>">
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<a href="<?php echo "../uploads/clients/$client_id/$file_reference_name"; ?>" target="_blank">
|
||||
<div class="media">
|
||||
<i class="fa fa-fw fa-2x fa-<?php echo $file_icon; ?> text-dark mr-3"></i>
|
||||
<div class="media-body">
|
||||
<p>
|
||||
<?php echo basename($file_name); ?>
|
||||
<br>
|
||||
<small class="text-secondary"><?php echo $file_description; ?></small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</td>
|
||||
<td><?php echo $file_mime_type; ?></td>
|
||||
<td><?php echo $file_size_KB; ?> KB</td>
|
||||
<td>
|
||||
<?php echo $file_created_at; ?>
|
||||
<div class="text-secondary mt-1"><?php echo $file_uploaded_by; ?></div>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($file_shared) { ?>
|
||||
<div class="media" title="Expires <?php echo $item_expire_at_human; ?>">
|
||||
<i class="fas fa-link mr-2 mt-1"></i>
|
||||
<div class="media-body">Shared
|
||||
<br>
|
||||
<small class="text-secondary"><?php echo $item_recipient; ?></small>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</td>
|
||||
<td>
|
||||
<div class="dropdown dropleft text-center">
|
||||
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
|
||||
<i class="fas fa-ellipsis-h"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="<?php echo "../uploads/clients/$client_id/$file_reference_name"; ?>" download="<?php echo $file_name; ?>">
|
||||
<i class="fas fa-fw fa-cloud-download-alt mr-2"></i>Download
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#shareModal" onclick="populateShareModal(<?php echo "$client_id, 'File', $file_id"; ?>)">
|
||||
<i class="fas fa-fw fa-share mr-2"></i>Share
|
||||
</a>
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/file/file_rename.php?id=<?= $file_id ?>">
|
||||
<i class="fas fa-fw fa-edit mr-2"></i>Rename
|
||||
</a>
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/file/file_move.php?id=<?= $file_id ?>">
|
||||
<i class="fas fa-fw fa-exchange-alt mr-2"></i>Move
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#linkAssetToFileModal<?php echo $file_id; ?>">
|
||||
<i class="fas fa-fw fa-desktop mr-2"></i>Asset
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_file=<?php echo $file_id; ?>">
|
||||
<i class="fas fa-fw fa-archive mr-2"></i>Archive
|
||||
</a>
|
||||
<?php if ($session_user_role == 3) { ?>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-danger text-bold" href="#" data-toggle="modal" data-target="#deleteFileModal" onclick="populateFileDeleteModal(<?php echo "$file_id , '$file_name'" ?>)">
|
||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||
</a>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
require "modals/file/file_link_asset.php";
|
||||
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
<?php require_once "../includes/filter_footer.php"; ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function openModal(index) {
|
||||
currentIndex = index;
|
||||
updateModalContent();
|
||||
$('#viewFileModal').modal('show');
|
||||
}
|
||||
|
||||
function updateModalContent() {
|
||||
document.getElementById('modalTitle').innerText = files[currentIndex].name;
|
||||
document.getElementById('modalImage').src = files[currentIndex].preview;
|
||||
}
|
||||
|
||||
function nextFile() {
|
||||
currentIndex = (currentIndex + 1) % files.length; // loop around
|
||||
updateModalContent();
|
||||
}
|
||||
|
||||
function prevFile() {
|
||||
currentIndex = (currentIndex - 1 + files.length) % files.length; // loop around
|
||||
updateModalContent();
|
||||
}
|
||||
</script>
|
||||
|
||||
<script src="../js/bulk_actions.js"></script>
|
||||
|
||||
<?php
|
||||
require_once "modals/share_modal.php";
|
||||
require_once "modals/file/file_delete.php";
|
||||
require_once "../includes/footer.php";
|
||||
@@ -53,6 +53,7 @@ $num_software = $row['num'];
|
||||
<i class="nav-icon fas fa-address-book"></i>
|
||||
<p>
|
||||
Contacts
|
||||
<span href="#" class="fas fa-plus-circle right ajax-modal" data-modal-url="/agent/modals/contact/contact_add.php"></span>
|
||||
<?php
|
||||
if ($num_contacts > 0) { ?>
|
||||
<span class="right badge text-light"><?php echo $num_contacts; ?></span>
|
||||
@@ -65,6 +66,7 @@ $num_software = $row['num'];
|
||||
<i class="nav-icon fas fa-map-marker-alt"></i>
|
||||
<p>
|
||||
Locations
|
||||
<span href="#" class="fas fa-plus-circle right ajax-modal" data-modal-url="/agent/modals/location/location_add.php"></span>
|
||||
<?php
|
||||
if ($num_locations > 0) { ?>
|
||||
<span class="right badge text-light"><?php echo $num_locations; ?></span>
|
||||
@@ -77,6 +79,7 @@ $num_software = $row['num'];
|
||||
<i class="nav-icon fas fa-desktop"></i>
|
||||
<p>
|
||||
Assets
|
||||
<span href="#" class="fas fa-plus-circle right ajax-modal" data-modal-url="/agent/modals/asset/asset_add.php"></span>
|
||||
<?php
|
||||
if ($num_assets > 0) { ?>
|
||||
<span class="right badge text-light"><?php echo $num_assets; ?></span>
|
||||
@@ -89,6 +92,7 @@ $num_software = $row['num'];
|
||||
<i class="nav-icon fas fa-cube"></i>
|
||||
<p>
|
||||
Licenses
|
||||
<span href="#" class="fas fa-plus-circle right ajax-modal" data-modal-url="/agent/modals/software/software_add.php"></span>
|
||||
<?php
|
||||
if ($num_software > 0) { ?>
|
||||
<span class="right badge text-light"><?php echo $num_software; ?></span>
|
||||
@@ -101,6 +105,7 @@ $num_software = $row['num'];
|
||||
<i class="nav-icon fas fa-key"></i>
|
||||
<p>
|
||||
Credentials
|
||||
<span href="#" class="fas fa-plus-circle right ajax-modal" data-modal-url="/agent/modals/credential/credential_add.php"></span>
|
||||
<?php
|
||||
if ($num_credentials > 0) { ?>
|
||||
<span class="right badge text-light"><?php echo $num_credentials; ?></span>
|
||||
@@ -113,6 +118,7 @@ $num_software = $row['num'];
|
||||
<i class="nav-icon fas fa-network-wired"></i>
|
||||
<p>
|
||||
Networks
|
||||
<span href="#" class="fas fa-plus-circle right ajax-modal" data-modal-url="/agent/modals/network/network_add.php"></span>
|
||||
<?php
|
||||
if ($num_networks > 0) { ?>
|
||||
<span class="right badge text-light"><?php echo $num_networks; ?></span>
|
||||
@@ -125,6 +131,7 @@ $num_software = $row['num'];
|
||||
<i class="nav-icon fas fa-lock"></i>
|
||||
<p>
|
||||
Certificates
|
||||
<span href="#" class="fas fa-plus-circle right ajax-modal" data-modal-url="/agent/modals/certificate/certificate_add.php"></span>
|
||||
<?php
|
||||
if ($num_certificates > 0) { ?>
|
||||
<span class="right badge text-light"><?php echo $num_certificates; ?></span>
|
||||
@@ -137,6 +144,7 @@ $num_software = $row['num'];
|
||||
<i class="nav-icon fas fa-globe"></i>
|
||||
<p>
|
||||
Domains
|
||||
<span href="#" class="fas fa-plus-circle right ajax-modal" data-modal-url="/agent/modals/domain/domain_add.php"></span>
|
||||
<?php
|
||||
if ($num_domains > 0) { ?>
|
||||
<span class="right badge text-light"><?php echo $num_domains; ?></span>
|
||||
@@ -149,6 +157,7 @@ $num_software = $row['num'];
|
||||
<i class="nav-icon fas fa-stream"></i>
|
||||
<p>
|
||||
Services
|
||||
<span href="#" class="fas fa-plus-circle right ajax-modal" data-modal-url="/agent/modals/service/service_add.php"></span>
|
||||
<?php
|
||||
if ($num_services > 0) { ?>
|
||||
<span class="right badge text-light"><?php echo $num_services; ?></span>
|
||||
|
||||
@@ -199,7 +199,6 @@
|
||||
<i class="nav-icon fas fa-lock"></i>
|
||||
<p>
|
||||
Certificates
|
||||
|
||||
<?php
|
||||
if ($num_certificates > 0) { ?>
|
||||
<span class="right badge <?php if ($num_certificates_expiring > 0) { ?> badge-warning text-dark <?php } ?> <?php if ($num_certificates_expired > 0) { ?> badge-danger <?php } ?> text-white"><?php echo $num_certificates; ?></span>
|
||||
@@ -213,7 +212,6 @@
|
||||
<i class="nav-icon fas fa-globe"></i>
|
||||
<p>
|
||||
Domains
|
||||
|
||||
<?php
|
||||
if ($num_domains > 0) { ?>
|
||||
<span class="right badge <?php if (isset($num_domains_expiring)) { ?> badge-warning text-dark<?php } ?> <?php if (isset($num_domains_expired)) { ?> badge-danger <?php } ?> text-white"><?php echo $num_domains; ?></span>
|
||||
@@ -235,25 +233,12 @@
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="/agent/documents.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "documents.php" || basename($_SERVER["PHP_SELF"]) == "document_details.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-folder"></i>
|
||||
<p>
|
||||
Documents
|
||||
<?php
|
||||
if ($num_documents > 0) { ?>
|
||||
<span class="right badge text-light"><?php echo $num_documents; ?></span>
|
||||
<?php } ?>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
<!-- Allow files even without module_support for things like contracts, etc. ) -->
|
||||
<li class="nav-item">
|
||||
<a href="/agent/files.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "files.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-paperclip"></i>
|
||||
<i class="nav-icon fas fa-folder"></i>
|
||||
<p>
|
||||
Files
|
||||
<?php
|
||||
|
||||
@@ -29,8 +29,8 @@ if (isset($_GET['client_id'])) {
|
||||
$sql = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT * FROM clients
|
||||
LEFT JOIN locations ON clients.client_id = locations.location_client_id AND location_primary = 1
|
||||
LEFT JOIN contacts ON clients.client_id = contacts.contact_client_id AND contact_primary = 1
|
||||
LEFT JOIN locations ON client_id = location_client_id AND location_primary = 1
|
||||
LEFT JOIN contacts ON client_id = contact_client_id AND contact_primary = 1
|
||||
WHERE client_id = $client_id"
|
||||
);
|
||||
|
||||
|
||||
@@ -23,10 +23,10 @@
|
||||
<a href="/agent/clients.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "clients.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-users"></i>
|
||||
<p>
|
||||
Clients
|
||||
<?php if ($num_active_clients) { ?>
|
||||
<span class="right badge text-light" data-toggle="tooltip" title="Active Clients"><?php echo $num_active_clients; ?></span>
|
||||
<?php } ?>
|
||||
Clients
|
||||
<?php if ($num_active_clients) { ?>
|
||||
<span class="right badge text-light" data-toggle="tooltip" title="Active Clients"><?php echo $num_active_clients; ?></span>
|
||||
<?php } ?>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@@ -18,8 +18,8 @@ if (isset($_GET['invoice_id'])) {
|
||||
$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
|
||||
LEFT JOIN contacts ON client_id = contact_client_id AND contact_primary = 1
|
||||
LEFT JOIN locations ON client_id = location_client_id AND location_primary = 1
|
||||
WHERE invoice_id = $invoice_id
|
||||
$access_permission_query
|
||||
LIMIT 1"
|
||||
@@ -162,7 +162,7 @@ if (isset($_GET['invoice_id'])) {
|
||||
|
||||
//Product autocomplete
|
||||
$products_sql = mysqli_query($mysqli, "
|
||||
SELECT
|
||||
SELECT
|
||||
CONCAT(product_code, ' - ', product_name) AS label,
|
||||
product_name,
|
||||
product_code,
|
||||
@@ -190,7 +190,7 @@ if (isset($_GET['invoice_id'])) {
|
||||
// Saved Payment Methods
|
||||
$sql_saved_payment_methods = mysqli_query($mysqli, "
|
||||
SELECT * FROM client_saved_payment_methods
|
||||
LEFT JOIN payment_providers
|
||||
LEFT JOIN payment_providers
|
||||
ON client_saved_payment_methods.saved_payment_provider_id = payment_providers.payment_provider_id
|
||||
WHERE saved_payment_client_id = $client_id
|
||||
AND payment_provider_active = 1;
|
||||
@@ -245,7 +245,7 @@ if (isset($_GET['invoice_id'])) {
|
||||
<?php if (mysqli_num_rows($sql_saved_payment_methods) > 0 && ($invoice_status === 'Sent' || $invoice_status === 'Viewed')) { ?>
|
||||
<button type="button" class="btn btn-success dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/payment/payment_saved_method_add.php?id=<?= $invoice_id ?>"><i class="fas fa-fw fa-wallet mr-2"></i>Pay with Saved Card</a>
|
||||
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/payment/payment_saved_method_add.php?id=<?= $invoice_id ?>"><i class="fas fa-fw fa-wallet mr-2"></i>Pay with Saved Card</a>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
@@ -456,10 +456,10 @@ if (isset($_GET['invoice_id'])) {
|
||||
<textarea class="form-control" rows="2" id="desc" name="description" placeholder="Enter a Description"></textarea>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" class="form-control" style="text-align: center;" id="qty" name="qty" placeholder="Qty">
|
||||
<input type="text" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" class="form-control" style="text-align: center;" id="qty" name="qty" placeholder="Qty">
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="-?[0-9]*\.?[0-9]{0,2}" style="text-align: right;" id="price" name="price" placeholder="Price (<?php echo $invoice_currency_code; ?>)">
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="-?[0-9]*\.?[0-9]{0,2}" style="text-align: right;" id="price" name="price" placeholder="Price (<?php echo $invoice_currency_code; ?>)">
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control select2" name="tax_id" id="tax" required>
|
||||
|
||||
@@ -344,8 +344,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
$recurring_invoice_display = "-";
|
||||
}
|
||||
|
||||
|
||||
|
||||
$now = time();
|
||||
|
||||
if (($invoice_status == "Sent" || $invoice_status == "Partial" || $invoice_status == "Viewed") && strtotime($invoice_due) + 86400 < $now) {
|
||||
@@ -356,6 +354,15 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
|
||||
$invoice_badge_color = getInvoiceBadgeColor($invoice_status);
|
||||
|
||||
// Saved Payment Methods
|
||||
$sql_saved_payment_methods = mysqli_query($mysqli, "
|
||||
SELECT * FROM client_saved_payment_methods
|
||||
LEFT JOIN payment_providers
|
||||
ON client_saved_payment_methods.saved_payment_provider_id = payment_providers.payment_provider_id
|
||||
WHERE saved_payment_client_id = $client_id
|
||||
AND payment_provider_active = 1;
|
||||
");
|
||||
|
||||
?>
|
||||
|
||||
<tr>
|
||||
@@ -395,10 +402,8 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<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>
|
||||
<?php if (mysqli_num_rows($sql_saved_payment_methods) > 0 && ($invoice_status === 'Sent' || $invoice_status === 'Viewed')) { ?>
|
||||
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/payment/payment_saved_method_add.php?id=<?= $invoice_id ?>"><i class="fas fa-fw fa-wallet mr-2"></i>Pay with Saved Card</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
|
||||
@@ -32,7 +32,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-dollar-sign"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="-?[0-9]*\.?[0-9]{0,2}" name="opening_balance" placeholder="0.00" required>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="-?[0-9]*\.?[0-9]{0,2}" name="opening_balance" placeholder="0.00" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@ if ($os_sql && mysqli_num_rows($os_sql) > 0) {
|
||||
$json_os = json_encode($os_arr);
|
||||
}
|
||||
|
||||
$sql_tags_select = mysqli_query($mysqli, "SELECT tag_id, tag_name FROM tags WHERE tag_type = 5 ORDER BY tag_name ASC");
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
@@ -465,6 +467,33 @@ ob_start();
|
||||
<textarea class="form-control" rows="8" placeholder="Enter some notes" name="notes"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Tags</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-tags"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="tags[]" data-placeholder="Add some tags" multiple>
|
||||
<?php
|
||||
|
||||
while ($row = mysqli_fetch_array($sql_tags_select)) {
|
||||
$tag_id = intval($row['tag_id']);
|
||||
$tag_name = nullable_htmlentities($row['tag_name']);
|
||||
?>
|
||||
<option value="<?= $tag_id ?>"><?= $tag_name ?></option>
|
||||
<?php } ?>
|
||||
|
||||
</select>
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-secondary ajax-modal" type="button"
|
||||
data-modal-url="../admin/modals/tag/tag_add.php?type=5">
|
||||
<i class="fas fa-plus"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
61
agent/modals/asset/asset_bulk_assign_tags.php
Normal file
61
agent/modals/asset/asset_bulk_assign_tags.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
|
||||
|
||||
$count = count($selected_ids);
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-tags mr-2"></i>Assign Tags for <strong><?= $count ?></strong> Assets</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="asset_ids[]" value="<?= $id ?>"><?php } ?>
|
||||
|
||||
<div class="modal-body">
|
||||
<input type="hidden" name="remove_tags" value="0">
|
||||
|
||||
<div class="form-group form-check">
|
||||
<input type="checkbox" class="form-check-input" name="remove_tags" value="1">
|
||||
<label class="form-check-label text-danger">Remove Existing Tags</label>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Tags</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-tags"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="tags[]" data-placeholder="Add some tags" multiple>
|
||||
<?php
|
||||
|
||||
$sql_tags_select = mysqli_query($mysqli, "SELECT * FROM tags WHERE tag_type = 5 ORDER BY tag_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_tags_select)) {
|
||||
$tag_id_select = intval($row['tag_id']);
|
||||
$tag_name_select = nullable_htmlentities($row['tag_name']);
|
||||
?>
|
||||
<option value="<?php echo $tag_id_select; ?>"><?php echo $tag_name_select; ?></option>
|
||||
<?php } ?>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="bulk_assign_asset_tags" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Assign Tags</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
@@ -70,6 +70,28 @@ if ($location_archived_at) {
|
||||
$location_name_display = $location_name;
|
||||
}
|
||||
|
||||
// Tags - many to many relationship
|
||||
$asset_tag_name_display_array = array();
|
||||
$asset_tag_id_array = array();
|
||||
$sql_asset_tags = mysqli_query($mysqli, "SELECT * FROM asset_tags LEFT JOIN tags ON asset_tag_tag_id = tag_id WHERE asset_tag_asset_id = $asset_id ORDER BY tag_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_asset_tags)) {
|
||||
|
||||
$asset_tag_id = intval($row['tag_id']);
|
||||
$asset_tag_name = nullable_htmlentities($row['tag_name']);
|
||||
$asset_tag_color = nullable_htmlentities($row['tag_color']);
|
||||
if (empty($asset_tag_color)) {
|
||||
$asset_tag_color = "dark";
|
||||
}
|
||||
$asset_tag_icon = nullable_htmlentities($row['tag_icon']);
|
||||
if (empty($asset_tag_icon)) {
|
||||
$asset_tag_icon = "tag";
|
||||
}
|
||||
|
||||
$asset_tag_id_array[] = $asset_tag_id;
|
||||
$asset_tag_name_display_array[] = "<a href='client_assets.php?client_id=$client_id&q=$asset_tag_name'><span class='badge text-light p-1 mr-1' style='background-color: $asset_tag_color;'><i class='fa fa-fw fa-$asset_tag_icon mr-2'></i>$asset_tag_name</span></a>";
|
||||
}
|
||||
$asset_tags_display = implode('', $asset_tag_name_display_array);
|
||||
|
||||
// Network Interfaces
|
||||
$sql_related_interfaces = mysqli_query($mysqli, "
|
||||
SELECT
|
||||
@@ -262,8 +284,13 @@ ob_start();
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php if ($asset_tags_display) { ?>
|
||||
<div>
|
||||
<?= $asset_tags_display ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
<?php if ($asset_type) { ?>
|
||||
<div><i class="fa fa-fw fa-tag text-secondary mr-2"></i><?php echo $asset_type; ?></div>
|
||||
<div class="mt-1"><i class="fa fa-fw fa-tag text-secondary mr-2"></i><?php echo $asset_type; ?></div>
|
||||
<?php }
|
||||
if ($asset_make) { ?>
|
||||
<div class="mt-2"><i class="fa fa-fw fa-circle text-secondary mr-2"></i><?php echo "$asset_make $asset_model"; ?></div>
|
||||
@@ -353,7 +380,7 @@ ob_start();
|
||||
|
||||
// Send a POST request to ajax.php as ajax.php with data contact_set_notes=true, contact_id=NUM, notes=NOTES
|
||||
jQuery.post(
|
||||
"../ajax.php",
|
||||
"ajax.php",
|
||||
{
|
||||
asset_set_notes: 'TRUE',
|
||||
asset_id: asset_id,
|
||||
|
||||
@@ -50,7 +50,14 @@ $sql_asset_history = mysqli_query($mysqli, "SELECT * FROM asset_history
|
||||
DESC LIMIT 10"
|
||||
);
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
// Tags
|
||||
$asset_tag_id_array = array();
|
||||
$sql_asset_tags = mysqli_query($mysqli, "SELECT asset_tag_tag_id FROM asset_tags WHERE asset_tag_asset_id = $asset_id");
|
||||
while ($row = mysqli_fetch_array($sql_asset_tags)) {
|
||||
$asset_tag_tag_id = intval($row['asset_tag_tag_id']);
|
||||
$asset_tag_id_array[] = $asset_tag_tag_id;
|
||||
}
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
|
||||
@@ -462,6 +469,33 @@ ob_start();
|
||||
<textarea class="form-control" rows="8" placeholder="Enter some notes" name="notes"><?= $asset_notes ?></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Tags</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-tags"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="tags[]" data-placeholder="Add some tags" multiple>
|
||||
<?php
|
||||
|
||||
$sql_tags_select = mysqli_query($mysqli, "SELECT * FROM tags WHERE tag_type = 5 ORDER BY tag_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_tags_select)) {
|
||||
$tag_id_select = intval($row['tag_id']);
|
||||
$tag_name_select = nullable_htmlentities($row['tag_name']);
|
||||
?>
|
||||
<option value="<?= $tag_id_select ?>" <?php if (in_array($tag_id_select, $asset_tag_id_array)) { echo "selected"; } ?>><?php echo $tag_name_select; ?></option>
|
||||
<?php } ?>
|
||||
|
||||
</select>
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-secondary ajax-modal" type="button"
|
||||
data-modal-url="../admin/modals/tag/tag_add.php?type=5">
|
||||
<i class="fas fa-plus"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="text-muted text-right">Asset ID: <?= $asset_id ?></p>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -207,7 +207,7 @@ ob_start();
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<label>Location Phone / <span class="text-secondary">Extension</span></label>
|
||||
<div class="form-row">
|
||||
<div class="col-9">
|
||||
@@ -228,7 +228,7 @@ ob_start();
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label>Location Fax</label>
|
||||
<label>Location Fax</label>
|
||||
<div class="form-row">
|
||||
<div class="col-9">
|
||||
<div class="form-group">
|
||||
@@ -287,7 +287,7 @@ ob_start();
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label>Mobile</label>
|
||||
<label>Mobile</label>
|
||||
<div class="form-row">
|
||||
<div class="col-9">
|
||||
<div class="form-group">
|
||||
@@ -324,7 +324,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="rate" placeholder="0.00" value="<?php echo "$config_default_hourly_rate"; ?>">
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="rate" placeholder="0.00" value="<?php echo "$config_default_hourly_rate"; ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="bulk_rate" placeholder="0.00" required>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="bulk_rate" placeholder="0.00" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-dollar-sign"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="amount" placeholder="0.00" required>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="amount" placeholder="0.00" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric"
|
||||
<input type="text" class="form-control" inputmode="decimal"
|
||||
pattern="[0-9]*\.?[0-9]{0,2}" name="rate" placeholder="0.00"
|
||||
value="<?php echo number_format($client_rate, 2, '.', ''); ?>">
|
||||
</div>
|
||||
|
||||
@@ -51,7 +51,14 @@ $auth_method = nullable_htmlentities($row['user_auth_method']);
|
||||
$contact_client_id = intval($row['contact_client_id']);
|
||||
|
||||
// Related Assets Query - 1 to 1 relationship
|
||||
$sql_related_assets = mysqli_query($mysqli, "SELECT * FROM assets LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1 WHERE asset_contact_id = $contact_id ORDER BY asset_name DESC");
|
||||
$sql_related_assets = mysqli_query($mysqli, "SELECT * FROM assets
|
||||
LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1
|
||||
LEFT JOIN asset_tags ON asset_tag_asset_id = asset_id
|
||||
LEFT JOIN tags ON tag_id = asset_tag_tag_id
|
||||
WHERE asset_contact_id = $contact_id
|
||||
GROUP BY asset_id
|
||||
ORDER BY asset_name ASC"
|
||||
);
|
||||
$asset_count = mysqli_num_rows($sql_related_assets);
|
||||
|
||||
// Linked Software Licenses
|
||||
@@ -77,7 +84,7 @@ $sql_related_credentials = mysqli_query($mysqli, "
|
||||
LEFT JOIN tags ON tags.tag_id = credential_tags.tag_id
|
||||
WHERE credential_contact_id = $contact_id
|
||||
GROUP BY credentials.credential_id
|
||||
ORDER BY credential_name DESC
|
||||
ORDER BY credential_name ASC
|
||||
");
|
||||
$credential_count = mysqli_num_rows($sql_related_credentials);
|
||||
|
||||
@@ -376,6 +383,27 @@ ob_start();
|
||||
$asset_notes = nullable_htmlentities($row['asset_notes']);
|
||||
$asset_created_at = nullable_htmlentities($row['asset_created_at']);
|
||||
$device_icon = getAssetIcon($asset_type);
|
||||
// Tags
|
||||
$asset_tag_name_display_array = array();
|
||||
$asset_tag_id_array = array();
|
||||
$sql_asset_tags = mysqli_query($mysqli, "SELECT * FROM asset_tags LEFT JOIN tags ON asset_tag_tag_id = tag_id WHERE asset_tag_asset_id = $asset_id ORDER BY tag_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_asset_tags)) {
|
||||
|
||||
$asset_tag_id = intval($row['tag_id']);
|
||||
$asset_tag_name = nullable_htmlentities($row['tag_name']);
|
||||
$asset_tag_color = nullable_htmlentities($row['tag_color']);
|
||||
if (empty($asset_tag_color)) {
|
||||
$asset_tag_color = "dark";
|
||||
}
|
||||
$asset_tag_icon = nullable_htmlentities($row['tag_icon']);
|
||||
if (empty($asset_tag_icon)) {
|
||||
$asset_tag_icon = "tag";
|
||||
}
|
||||
|
||||
$asset_tag_id_array[] = $asset_tag_id;
|
||||
$asset_tag_name_display_array[] = "<a href='assets.php?$client_url tags[]=$asset_tag_id'><span class='badge text-light p-1 mr-1' style='background-color: $asset_tag_color;'><i class='fa fa-fw fa-$asset_tag_icon mr-2'></i>$asset_tag_name</span></a>";
|
||||
}
|
||||
$asset_tags_display = implode('', $asset_tag_name_display_array);
|
||||
|
||||
?>
|
||||
<tr>
|
||||
@@ -389,6 +417,12 @@ ob_start();
|
||||
<div class="mt-0">
|
||||
<small class="text-muted"><?= $asset_description ?></small>
|
||||
</div>
|
||||
<?php
|
||||
if ($asset_tags_display) { ?>
|
||||
<div class="mt-1">
|
||||
<?= $asset_tags_display ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</th>
|
||||
<td><?= $asset_type ?></td>
|
||||
<td>
|
||||
|
||||
@@ -33,7 +33,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-dollar-sign"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="amount" placeholder="0.00" required>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="amount" placeholder="0.00" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -50,7 +50,7 @@ ob_start();
|
||||
<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($expense_amount, 2, '.', ''); ?>" placeholder="0.00" required>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="amount" value="<?php echo number_format($expense_amount, 2, '.', ''); ?>" placeholder="0.00" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -211,4 +211,3 @@ ob_start();
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
?>
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ ob_start();
|
||||
<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($expense_amount, 2, '.', ''); ?>" placeholder="0.00" required>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="-?[0-9]*\.?[0-9]{0,2}" name="amount" value="<?php echo number_format($expense_amount, 2, '.', ''); ?>" placeholder="0.00" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ ob_start();
|
||||
<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($expense_amount, 2, '.', ''); ?>" placeholder="-0.00" required>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="-?[0-9]*\.?[0-9]{0,2}" name="amount" value="-<?php echo number_format($expense_amount, 2, '.', ''); ?>" placeholder="-0.00" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -89,4 +89,3 @@ ob_start();
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
|
||||
@@ -97,6 +97,16 @@ ob_start();
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='form-group'>
|
||||
<label>Discount Amount</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="decimal" pattern="-?[0-9]*\.?[0-9]{0,2}" name='invoice_discount' placeholder='0.00'>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_invoice" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create</button>
|
||||
|
||||
@@ -91,7 +91,7 @@ ob_start();
|
||||
<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='invoice_discount' placeholder='0.00' value="<?php echo number_format($invoice_discount, 2, '.', ''); ?>">
|
||||
<input type='text' class='form-control' inputmode="decimal" pattern="-?[0-9]*\.?[0-9]{0,2}" name='invoice_discount' placeholder='0.00' value="<?php echo number_format($invoice_discount, 2, '.', ''); ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ ob_start();
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="item_id" value="<?php echo $item_id; ?>">
|
||||
<input type="hidden" name="product_id" value="<?php echo $product_id; ?>">
|
||||
|
||||
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label>Item <strong class="text-danger">*</strong></label>
|
||||
@@ -47,7 +47,7 @@ ob_start();
|
||||
<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" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="qty" value="<?php echo number_format($item_quantity, 2); ?>" placeholder="0.00" required>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="qty" value="<?php echo number_format($item_quantity, 2); ?>" placeholder="0.00" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -59,7 +59,7 @@ ob_start();
|
||||
<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="price" value="<?php echo number_format($item_price, 2, '.', ''); ?>" placeholder="0.00" required>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="-?[0-9]*\.?[0-9]{0,2}" name="price" value="<?php echo number_format($item_price, 2, '.', ''); ?>" placeholder="0.00" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -80,8 +80,8 @@ ob_start();
|
||||
</div>
|
||||
<select class="form-control select2" name="tax_id" required>
|
||||
<option value="0">No Tax</option>
|
||||
<?php
|
||||
$taxes_sql = mysqli_query($mysqli, "SELECT * FROM taxes WHERE (tax_archived_at > '$item_created_at' OR tax_archived_at IS NULL) ORDER BY tax_name ASC");
|
||||
<?php
|
||||
$taxes_sql = mysqli_query($mysqli, "SELECT * FROM taxes WHERE (tax_archived_at > '$item_created_at' OR tax_archived_at IS NULL) ORDER BY tax_name ASC");
|
||||
while ($row = mysqli_fetch_array($taxes_sql)) {
|
||||
$tax_id_select = intval($row['tax_id']);
|
||||
$tax_name = nullable_htmlentities($row['tax_name']);
|
||||
|
||||
@@ -39,7 +39,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-wallet"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="amount_credit_applied" value="<?php echo number_format($credit_balance, 2, '.', ''); ?>" placeholder="0.00" required>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="amount_credit_applied" value="<?php echo number_format($credit_balance, 2, '.', ''); ?>" placeholder="0.00" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ ob_start();
|
||||
<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>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="amount" value="<?php echo number_format($balance, 2, '.', ''); ?>" placeholder="0.00" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ ob_start();
|
||||
<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>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="amount" value="<?php echo number_format($balance, 2, '.', ''); ?>" placeholder="0.00" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -9,9 +9,12 @@ if ($type == 'product') {
|
||||
$type_icon = "fa-wrench";
|
||||
}
|
||||
|
||||
$product_types_array = ['product', 'service'];
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw <?= $type_icon ?> mr-2"></i>New <strong><?= ucwords($type); ?></strong></h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
@@ -19,7 +22,6 @@ ob_start();
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="type" value="<?= $type ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
@@ -33,6 +35,27 @@ ob_start();
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($type) { ?>
|
||||
<input type="hidden" name="type" value="<?= $type ?>">
|
||||
<?php } else { ?>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Type <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="type" required>
|
||||
<option value="">- Select Type -</option>
|
||||
<?php foreach ($product_types_array as $type_select) { ?>
|
||||
<option><?= $type_select ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Category <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
@@ -71,7 +94,7 @@ ob_start();
|
||||
<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="price" placeholder="0.00" required>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="price" placeholder="0.00" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -78,7 +78,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-dollar-sign"></i></span>
|
||||
</div>
|
||||
<input type="text" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" class="form-control" name="price" value="<?php echo number_format($product_price, 2, '.', ''); ?>" placeholder="0.00" required>
|
||||
<input type="text" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" class="form-control" name="price" value="<?php echo number_format($product_price, 2, '.', ''); ?>" placeholder="0.00" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -88,7 +88,7 @@ ob_start();
|
||||
<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='quote_discount' placeholder='0.00' value="<?php echo number_format($quote_discount, 2, '.', ''); ?>">
|
||||
<input type='text' class='form-control' inputmode="decimal" pattern="-?[0-9]*\.?[0-9]{0,2}" name='quote_discount' placeholder='0.00' value="<?php echo number_format($quote_discount, 2, '.', ''); ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-dollar-sign"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="-?[0-9]*\.?[0-9]{0,2}" name="amount" placeholder="0.00" required>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="-?[0-9]*\.?[0-9]{0,2}" name="amount" placeholder="0.00" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -97,7 +97,7 @@ ob_start();
|
||||
<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($recurring_expense_amount, 2, '.', ''); ?>" required>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="-?[0-9]*\.?[0-9]{0,2}" name="amount" value="<?php echo number_format($recurring_expense_amount, 2, '.', ''); ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -102,7 +102,7 @@ ob_start();
|
||||
<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='recurring_invoice_discount' placeholder='0.00' value="<?php echo number_format($recurring_invoice_discount, 2, '.', ''); ?>">
|
||||
<input type='text' class='form-control' inputmode="decimal" pattern="-?[0-9]*\.?[0-9]{0,2}" name='recurring_invoice_discount' placeholder='0.00' value="<?php echo number_format($recurring_invoice_discount, 2, '.', ''); ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-dollar-sign"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="amount" placeholder="0.00" required>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="amount" placeholder="0.00" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ ob_start();
|
||||
<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($revenue_amount, 2, '.', ''); ?>" placeholder="0.00" required>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="amount" value="<?php echo number_format($revenue_amount, 2, '.', ''); ?>" placeholder="0.00" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$ticket_id = intval($_GET['ticket_id']);
|
||||
$client_id = intval(getFieldById('tickets', $ticket_id, 'ticket_client_id'));
|
||||
|
||||
ob_start();
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ ob_start();
|
||||
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-clone mr-2"></i>Merge & close <strong><?= $count ?></strong>tickets</h5>
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-clone mr-2"></i>Merge & close <strong><?= $count ?></strong> tickets</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
@@ -75,3 +75,5 @@ ob_start();
|
||||
|
||||
<!-- Ticket merge JS -->
|
||||
<script src="/agent/js/ticket_merge.js"></script>
|
||||
|
||||
<?php require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -38,33 +38,35 @@ while ($row = mysqli_fetch_array($sql_additional_assets)) {
|
||||
ob_start();
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-life-ring mr-2"></i>Editing ticket: <strong><?php echo "$ticket_prefix$ticket_number"; ?></strong> - <?php echo $client_name; ?></h5>
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-life-ring mr-2"></i>Ticket: <strong><?= "$ticket_prefix$ticket_number" ?></strong> - <?= $client_name ?></h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="ticket_id" value="<?php echo $ticket_id; ?>">
|
||||
<input type="hidden" name="ticket_id" value="<?= $ticket_id ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<?php if ($client_id) { ?>
|
||||
<ul class="nav nav-pills nav-justified mb-3">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-toggle="pill" href="#pills-details<?php echo $ticket_id; ?>"><i class="fa fa-fw fa-life-ring mr-2"></i>Details</a>
|
||||
<a class="nav-link active" data-toggle="pill" href="#pills-details"><i class="fa fa-fw fa-life-ring mr-2"></i>Details</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-contacts"><i class="fa fa-fw fa-users mr-2"></i>Contact</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-contacts<?php echo $ticket_id; ?>"><i class="fa fa-fw fa-users mr-2"></i>Contact</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-assignment<?php echo $ticket_id; ?>"><i class="fa fa-fw fa-desktop mr-2"></i>Assignment</a>
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-assignment"><i class="fa fa-fw fa-desktop mr-2"></i>Assignment</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
<div class="tab-content" <?php if (lookupUserPermission('module_support') <= 1) { echo 'inert'; } ?>>
|
||||
|
||||
<div class="tab-pane fade show active" id="pills-details<?php echo $ticket_id; ?>">
|
||||
<div class="tab-pane fade show active" id="pills-details">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Subject <strong class="text-danger">*</strong></label>
|
||||
@@ -182,7 +184,9 @@ ob_start();
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-contacts<?php echo $ticket_id; ?>">
|
||||
<?php if ($client_id) { ?>
|
||||
|
||||
<div class="tab-pane fade" id="pills-contacts">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Contact</label>
|
||||
@@ -236,7 +240,7 @@ ob_start();
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-assignment<?php echo $ticket_id; ?>">
|
||||
<div class="tab-pane fade" id="pills-assignment">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Asset</label>
|
||||
@@ -372,7 +376,7 @@ ob_start();
|
||||
while ($row = mysqli_fetch_array($sql_projects)) {
|
||||
$project_id_select = intval($row['project_id']);
|
||||
$project_name_select = nullable_htmlentities($row['project_name']); ?>
|
||||
<option <?php if ($project_id == $project_id_select) { echo "selected"; } ?> value="<?php echo $project_id_select; ?>"><?php echo $project_name_select; ?></option>
|
||||
<option <?php if ($project_id == $project_id_select) { echo "selected"; } ?> value="<?= $project_id_select ?>"><?= $project_name_select ?></option>
|
||||
|
||||
<?php } ?>
|
||||
</select>
|
||||
@@ -380,13 +384,14 @@ ob_start();
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<?php } // End client_id check ?>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="edit_ticket" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button>
|
||||
<button type="submit" name="edit_ticket" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save changes</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ ob_start();
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-create-invoice"><i class="fa fa-fw fa-check mr-2"></i>Create New Invoice</a>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
@@ -108,7 +108,7 @@ ob_start();
|
||||
<div class="tab-content">
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
if (mysqli_num_rows($sql_invoices) > 0) { ?>
|
||||
|
||||
<div class="tab-pane fade <?php if (mysqli_num_rows($sql_invoices) > 0) { echo "active show"; } ?>" id="pills-add-to-invoice">
|
||||
@@ -146,7 +146,7 @@ ob_start();
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label>Invoice Date <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
@@ -203,7 +203,7 @@ ob_start();
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
@@ -260,7 +260,7 @@ ob_start();
|
||||
<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" inputmode="numeric" pattern="-?[0-9]*\.?[0-9]{0,2}" name="qty" value="<?php echo roundToNearest15($ticket_total_reply_time); ?>" required>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="-?[0-9]*\.?[0-9]{0,2}" name="qty" value="<?php echo roundToNearest15($ticket_total_reply_time); ?>" required>
|
||||
</div>
|
||||
<small class="form-text text-muted">
|
||||
Based off Ticket time spent <strong><?= $ticket_total_reply_time ?></strong> in 15 Min Increments rounded up.
|
||||
@@ -277,7 +277,7 @@ ob_start();
|
||||
<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="price" value="<?php echo number_format($client_rate, 2, '.', ''); ?>" required>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="-?[0-9]*\.?[0-9]{0,2}" name="price" value="<?php echo number_format($client_rate, 2, '.', ''); ?>" required>
|
||||
</div>
|
||||
<small class="form-text text-muted">
|
||||
Based off Hourly Client rate of <strong><?= numfmt_format_currency($currency_format, $client_rate, $session_company_currency); ?></strong>
|
||||
|
||||
@@ -32,7 +32,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-dollar-sign"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="amount" placeholder="0.00" required>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="amount" placeholder="0.00" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -182,7 +182,7 @@ ob_start();
|
||||
function addOptionToTextbox() {
|
||||
var selectElement = document.getElementById("paymentSelect");
|
||||
var selectedOption = selectElement.options[selectElement.selectedIndex];
|
||||
|
||||
|
||||
var textboxElement = document.getElementById("transferNotes");
|
||||
textboxElement.value += selectedOption.value + "\n";
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-dollar-sign"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="amount" placeholder="0.00" value="<?php echo number_format($transfer_amount, 2, '.', ''); ?>" required>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" name="amount" placeholder="0.00" value="<?php echo number_format($transfer_amount, 2, '.', ''); ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ ob_start();
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-row">
|
||||
@@ -34,7 +34,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-bicycle"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,1}" name="miles" placeholder="0.0" required autofocus>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,1}" name="miles" placeholder="0.0" required autofocus>
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text">
|
||||
<input type="checkbox" name="roundtrip" value="1">
|
||||
|
||||
@@ -49,7 +49,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-bicycle"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,1}" name="miles" value="<?php echo $trip_miles; ?>" placeholder="0.0" required>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,1}" name="miles" value="<?php echo $trip_miles; ?>" placeholder="0.0" required>
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text">
|
||||
<input type="checkbox" name="roundtrip" value="1" <?php if ($round_trip == 1) { echo "checked"; } ?>>
|
||||
|
||||
@@ -50,7 +50,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-bicycle"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,1}" name="miles" value="<?php echo $trip_miles; ?>" placeholder="0.0" required>
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,1}" name="miles" value="<?php echo $trip_miles; ?>" placeholder="0.0" required>
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text">
|
||||
<input type="checkbox" name="roundtrip" value="1" <?php if ($round_trip == 1) { echo "checked"; } ?>>
|
||||
|
||||
@@ -38,9 +38,6 @@ if (isset($_GET['account']) & !empty($_GET['account'])) {
|
||||
$account_filter = '';
|
||||
}
|
||||
|
||||
//Rebuild URL
|
||||
$url_query_strings_sort = http_build_query($get_copy);
|
||||
|
||||
$sql = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT SQL_CALC_FOUND_ROWS * FROM payments
|
||||
|
||||
@@ -20,6 +20,14 @@ if (isset($_POST['add_asset'])) {
|
||||
|
||||
$asset_id = mysqli_insert_id($mysqli);
|
||||
|
||||
// Add Tags
|
||||
if (isset($_POST['tags'])) {
|
||||
foreach($_POST['tags'] as $tag) {
|
||||
$tag = intval($tag);
|
||||
mysqli_query($mysqli, "INSERT INTO asset_tags SET asset_tag_asset_id = $asset_id, asset_tag_tag_id = $tag");
|
||||
}
|
||||
}
|
||||
|
||||
// Add Photo
|
||||
if (isset($_FILES['file']['tmp_name'])) {
|
||||
if ($new_file_name = checkFileUpload($_FILES['file'], array('jpg', 'jpeg', 'gif', 'png', 'webp'))) {
|
||||
@@ -108,6 +116,18 @@ if (isset($_POST['edit_asset'])) {
|
||||
mysqli_query($mysqli,"UPDATE assets SET asset_photo = '$new_file_name' WHERE asset_id = $asset_id");
|
||||
}
|
||||
|
||||
// Tags
|
||||
// Delete existing tags
|
||||
mysqli_query($mysqli, "DELETE FROM asset_tags WHERE asset_tag_asset_id = $asset_id");
|
||||
|
||||
// Add new tags
|
||||
if (isset($_POST['tags'])) {
|
||||
foreach($_POST['tags'] as $tag) {
|
||||
$tag = intval($tag);
|
||||
mysqli_query($mysqli, "INSERT INTO asset_tags SET asset_tag_asset_id = $asset_id, asset_tag_tag_id = $tag");
|
||||
}
|
||||
}
|
||||
|
||||
logAction("Asset", "Edit", "$session_name edited asset $name", $client_id, $asset_id);
|
||||
|
||||
flash_alert("Asset <strong>$name</strong> edited");
|
||||
@@ -188,6 +208,50 @@ if (isset($_GET['delete_asset'])) {
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['bulk_assign_asset_tags'])) {
|
||||
|
||||
enforceUserPermission('module_client', 2);
|
||||
|
||||
if (isset($_POST['asset_ids'])) {
|
||||
|
||||
$count = count($_POST['asset_ids']);
|
||||
|
||||
foreach($_POST['asset_ids'] as $asset_id) {
|
||||
$asset_id = intval($asset_id);
|
||||
|
||||
$sql = mysqli_query($mysqli,"SELECT asset_name, asset_client_id FROM assets WHERE asset_id = $asset_id");
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$asset_name = sanitizeInput($row['asset_name']);
|
||||
$client_id = intval($row['asset_client_id']);
|
||||
|
||||
if($_POST['remove_tags']) {
|
||||
mysqli_query($mysqli, "DELETE FROM asset_tags WHERE asset_tag_asset_id = $asset_id");
|
||||
}
|
||||
|
||||
if (isset($_POST['tags'])) {
|
||||
foreach($_POST['tags'] as $tag) {
|
||||
$tag = intval($tag);
|
||||
|
||||
$sql = mysqli_query($mysqli,"SELECT * FROM asset_tags WHERE asset_tag_asset_id = $asset_id AND asset_tag_tag_id = $tag");
|
||||
if (mysqli_num_rows($sql) == 0) {
|
||||
mysqli_query($mysqli, "INSERT INTO asset_tags SET asset_tag_asset_id = $asset_id, asset_tag_tag_id = $tag");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logAction("Asset", "Edit", "$session_name added tags to asset $asset_name", $client_id, $asset_id);
|
||||
|
||||
}
|
||||
|
||||
logAction("Asset", "Bulk Edit", "$session_name added tags for $asset_count assets", $client_id);
|
||||
|
||||
flash_alert("Assigned tags for <strong>$count</strong> assets");
|
||||
}
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['bulk_assign_asset_location'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
@@ -14,113 +14,238 @@ if (isset($_POST['add_client'])) {
|
||||
|
||||
require_once 'client_model.php';
|
||||
|
||||
// Location inputs
|
||||
$location_phone_country_code = preg_replace("/[^0-9]/", '', $_POST['location_phone_country_code']);
|
||||
$location_phone = preg_replace("/[^0-9]/", '', $_POST['location_phone']);
|
||||
$location_extension = preg_replace("/[^0-9]/", '', $_POST['location_extension']);
|
||||
$location_fax_country_code = preg_replace("/[^0-9]/", '', $_POST['location_fax_country_code']);
|
||||
$location_fax = preg_replace("/[^0-9]/", '', $_POST['location_fax']);
|
||||
$address = sanitizeInput($_POST['address']);
|
||||
$city = sanitizeInput($_POST['city']);
|
||||
$state = sanitizeInput($_POST['state']);
|
||||
$zip = sanitizeInput($_POST['zip']);
|
||||
$country = sanitizeInput($_POST['country']);
|
||||
$contact = sanitizeInput($_POST['contact']);
|
||||
$title = sanitizeInput($_POST['title']);
|
||||
$address = cleanInput($_POST['address']);
|
||||
$city = cleanInput($_POST['city']);
|
||||
$state = cleanInput($_POST['state']);
|
||||
$zip = cleanInput($_POST['zip']);
|
||||
$country = cleanInput($_POST['country']);
|
||||
|
||||
// Contact inputs
|
||||
$contact = cleanInput($_POST['contact']);
|
||||
$title = cleanInput($_POST['title']);
|
||||
$contact_phone_country_code = preg_replace("/[^0-9]/", '', $_POST['contact_phone_country_code']);
|
||||
$contact_phone = preg_replace("/[^0-9]/", '', $_POST['contact_phone']);
|
||||
$contact_extension = preg_replace("/[^0-9]/", '', $_POST['contact_extension']);
|
||||
$contact_mobile_country_code = preg_replace("/[^0-9]/", '', $_POST['contact_mobile_country_code']);
|
||||
$contact_mobile = preg_replace("/[^0-9]/", '', $_POST['contact_mobile']);
|
||||
$contact_email = sanitizeInput($_POST['contact_email']);
|
||||
$contact_email = cleanInput($_POST['contact_email']);
|
||||
|
||||
$extended_log_description = '';
|
||||
|
||||
// Create client
|
||||
mysqli_query($mysqli, "INSERT INTO clients SET client_name = '$name', client_type = '$type', client_website = '$website', client_referral = '$referral', client_rate = $rate, client_currency_code = '$session_company_currency', client_net_terms = $net_terms, client_tax_id_number = '$tax_id_number', client_lead = $lead, client_abbreviation = '$abbreviation', client_notes = '$notes', client_accessed_at = NOW()");
|
||||
|
||||
// Insert client using SET
|
||||
$query = mysqli_prepare(
|
||||
$mysqli,
|
||||
"INSERT INTO clients SET
|
||||
client_name = ?,
|
||||
client_type = ?,
|
||||
client_website = ?,
|
||||
client_referral = ?,
|
||||
client_rate = ?,
|
||||
client_currency_code = ?,
|
||||
client_net_terms = ?,
|
||||
client_tax_id_number = ?,
|
||||
client_lead = ?,
|
||||
client_abbreviation = ?,
|
||||
client_notes = ?,
|
||||
client_accessed_at = NOW()"
|
||||
);
|
||||
mysqli_stmt_bind_param(
|
||||
$query,
|
||||
"ssssdsiisss",
|
||||
$name,
|
||||
$type,
|
||||
$website,
|
||||
$referral,
|
||||
$rate,
|
||||
$session_company_currency,
|
||||
$net_terms,
|
||||
$tax_id_number,
|
||||
$lead,
|
||||
$abbreviation,
|
||||
$notes
|
||||
);
|
||||
mysqli_stmt_execute($query);
|
||||
$client_id = mysqli_insert_id($mysqli);
|
||||
|
||||
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . "/uploads/clients/$client_id")) {
|
||||
mkdir($_SERVER['DOCUMENT_ROOT'] . "/uploads/clients/$client_id");
|
||||
file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/uploads/clients/$client_id/index.php", "");
|
||||
// Create client folder
|
||||
$client_folder = $_SERVER['DOCUMENT_ROOT'] . "/uploads/clients/$client_id";
|
||||
if (!file_exists($client_folder)) {
|
||||
mkdir($client_folder);
|
||||
file_put_contents("$client_folder/index.php", "");
|
||||
}
|
||||
|
||||
// Create Referral if it doesn't exist
|
||||
$sql = mysqli_query($mysqli, "SELECT category_name FROM categories WHERE category_type = 'Referral' AND category_archived_at IS NULL AND category_name = '$referral'");
|
||||
if(mysqli_num_rows($sql) == 0) {
|
||||
mysqli_query($mysqli, "INSERT INTO categories SET category_name = '$referral', category_type = 'Referral'");
|
||||
// Create referral category if it doesn't exist
|
||||
$query = mysqli_prepare($mysqli, "SELECT category_name FROM categories WHERE category_type = 'Referral' AND category_archived_at IS NULL AND category_name = ?");
|
||||
mysqli_stmt_bind_param($query, "s", $referral);
|
||||
mysqli_stmt_execute($query);
|
||||
mysqli_stmt_store_result($query);
|
||||
if (mysqli_stmt_num_rows($query) == 0) {
|
||||
$query = mysqli_prepare($mysqli, "INSERT INTO categories SET category_name = ?, category_type = 'Referral'");
|
||||
mysqli_stmt_bind_param($query, "s", $referral);
|
||||
mysqli_stmt_execute($query);
|
||||
|
||||
logAction("Category", "Create", "$session_name created referral category $referral");
|
||||
}
|
||||
|
||||
// Create Location
|
||||
// Insert primary location using SET
|
||||
if (!empty($location_phone) || !empty($address) || !empty($city) || !empty($state) || !empty($zip)) {
|
||||
mysqli_query($mysqli, "INSERT INTO locations SET location_name = 'Primary', location_address = '$address', location_city = '$city', location_state = '$state', location_zip = '$zip', location_phone_country_code = '$location_phone_country_code', location_phone = '$location_phone', location_phone_extension = '$location_extension', location_fax_country_code = '$location_fax_country_code', location_fax = '$location_fax', location_country = '$country', location_primary = 1, location_client_id = $client_id");
|
||||
|
||||
//Extended Logging
|
||||
$query = mysqli_prepare(
|
||||
$mysqli,
|
||||
"INSERT INTO locations SET
|
||||
location_name = 'Primary',
|
||||
location_address = ?,
|
||||
location_city = ?,
|
||||
location_state = ?,
|
||||
location_zip = ?,
|
||||
location_phone_country_code = ?,
|
||||
location_phone = ?,
|
||||
location_phone_extension = ?,
|
||||
location_fax_country_code = ?,
|
||||
location_fax = ?,
|
||||
location_country = ?,
|
||||
location_primary = 1,
|
||||
location_client_id = ?"
|
||||
);
|
||||
mysqli_stmt_bind_param(
|
||||
$query,
|
||||
"ssssssssssi",
|
||||
$address,
|
||||
$city,
|
||||
$state,
|
||||
$zip,
|
||||
$location_phone_country_code,
|
||||
$location_phone,
|
||||
$location_extension,
|
||||
$location_fax_country_code,
|
||||
$location_fax,
|
||||
$country,
|
||||
$client_id
|
||||
);
|
||||
mysqli_stmt_execute($query);
|
||||
$extended_log_description .= ", primary location $address added";
|
||||
}
|
||||
|
||||
|
||||
// Create Contact
|
||||
// Insert primary contact using SET
|
||||
if (!empty($contact) || !empty($title) || !empty($contact_phone) || !empty($contact_mobile) || !empty($contact_email)) {
|
||||
mysqli_query($mysqli, "INSERT INTO contacts SET contact_name = '$contact', contact_title = '$title', contact_phone_country_code = '$contact_phone_country_code', contact_phone = '$contact_phone', contact_extension = '$contact_extension', contact_mobile_country_code = '$contact_mobile_country_code', contact_mobile = '$contact_mobile', contact_email = '$contact_email', contact_primary = 1, contact_important = 1, contact_client_id = $client_id");
|
||||
|
||||
//Extended Logging
|
||||
$query = mysqli_prepare(
|
||||
$mysqli,
|
||||
"INSERT INTO contacts SET
|
||||
contact_name = ?,
|
||||
contact_title = ?,
|
||||
contact_phone_country_code = ?,
|
||||
contact_phone = ?,
|
||||
contact_extension = ?,
|
||||
contact_mobile_country_code = ?,
|
||||
contact_mobile = ?,
|
||||
contact_email = ?,
|
||||
contact_primary = 1,
|
||||
contact_important = 1,
|
||||
contact_client_id = ?"
|
||||
);
|
||||
mysqli_stmt_bind_param(
|
||||
$query,
|
||||
"ssssssssi",
|
||||
$contact,
|
||||
$title,
|
||||
$contact_phone_country_code,
|
||||
$contact_phone,
|
||||
$contact_extension,
|
||||
$contact_mobile_country_code,
|
||||
$contact_mobile,
|
||||
$contact_email,
|
||||
$client_id
|
||||
);
|
||||
mysqli_stmt_execute($query);
|
||||
$extended_log_description .= ", primary contact $contact added";
|
||||
}
|
||||
|
||||
// Add Tags
|
||||
// Add tags
|
||||
if (isset($_POST['tags'])) {
|
||||
$query = mysqli_prepare($mysqli, "INSERT INTO client_tags SET client_id = ?, tag_id = ?");
|
||||
foreach ($_POST['tags'] as $tag) {
|
||||
$tag = intval($tag);
|
||||
mysqli_query($mysqli, "INSERT INTO client_tags SET client_id = $client_id, tag_id = $tag");
|
||||
mysqli_stmt_bind_param($query, "ii", $client_id, $tag);
|
||||
mysqli_stmt_execute($query);
|
||||
}
|
||||
}
|
||||
|
||||
// Create domain in domains/certificates
|
||||
// Insert domain and SSL using SET
|
||||
if (!empty($website) && filter_var($website, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)) {
|
||||
// Get domain expiry date
|
||||
$expire = getDomainExpirationDate($website);
|
||||
|
||||
// NS, MX, A and WHOIS records/data
|
||||
$records = getDomainRecords($website);
|
||||
$a = sanitizeInput($records['a']);
|
||||
$ns = sanitizeInput($records['ns']);
|
||||
$mx = sanitizeInput($records['mx']);
|
||||
$whois = sanitizeInput($records['whois']);
|
||||
$a = cleanInput($records['a']);
|
||||
$ns = cleanInput($records['ns']);
|
||||
$mx = cleanInput($records['mx']);
|
||||
$whois = cleanInput($records['whois']);
|
||||
|
||||
// Add domain record info using whois, or not
|
||||
try {
|
||||
mysqli_query($mysqli, "INSERT INTO domains SET domain_name = '$website', domain_registrar = 0, domain_webhost = 0, domain_expire = '$expire', domain_ip = '$a', domain_name_servers = '$ns', domain_mail_servers = '$mx', domain_raw_whois = '$whois', domain_client_id = $client_id");
|
||||
$extended_log_description .= ", domain $website added"; //Extended Logging
|
||||
$query = mysqli_prepare(
|
||||
$mysqli,
|
||||
"INSERT INTO domains SET
|
||||
domain_name = ?,
|
||||
domain_registrar = 0,
|
||||
domain_webhost = 0,
|
||||
domain_expire = ?,
|
||||
domain_ip = ?,
|
||||
domain_name_servers = ?,
|
||||
domain_mail_servers = ?,
|
||||
domain_raw_whois = ?,
|
||||
domain_client_id = ?"
|
||||
);
|
||||
mysqli_stmt_bind_param($query, "ssssssi", $website, $expire, $a, $ns, $mx, $whois, $client_id);
|
||||
mysqli_stmt_execute($query);
|
||||
$extended_log_description .= ", domain $website added";
|
||||
} catch (Exception $e) {
|
||||
$extended_log_description .= ", domain not added"; //Extended Logging
|
||||
logApp("Client", "warning", "Failed to add domain $website during client creation (usually a whois result error)");
|
||||
$extended_log_description .= ", domain not added";
|
||||
logApp("Client", "warning", "Failed to add domain $website during client creation");
|
||||
}
|
||||
|
||||
// Get inserted ID (for linking certificate, if exists)
|
||||
$domain_id = mysqli_insert_id($mysqli);
|
||||
|
||||
// Get SSL cert for domain (if exists)
|
||||
$certificate = getSSL($website);
|
||||
|
||||
if ($certificate['success'] == "TRUE") {
|
||||
$expire = sanitizeInput($certificate['expire']);
|
||||
$issued_by = sanitizeInput($certificate['issued_by']);
|
||||
$public_key = sanitizeInput($certificate['public_key']);
|
||||
$expire = cleanInput($certificate['expire']);
|
||||
$issued_by = cleanInput($certificate['issued_by']);
|
||||
$public_key = cleanInput($certificate['public_key']);
|
||||
|
||||
mysqli_query($mysqli, "INSERT INTO certificates SET certificate_name = '$website', certificate_domain = '$website', certificate_issued_by = '$issued_by', certificate_expire = '$expire', certificate_public_key = '$public_key', certificate_domain_id = $domain_id, certificate_client_id = $client_id");
|
||||
|
||||
//Extended Logging
|
||||
$query = mysqli_prepare(
|
||||
$mysqli,
|
||||
"INSERT INTO certificates SET
|
||||
certificate_name = ?,
|
||||
certificate_domain = ?,
|
||||
certificate_issued_by = ?,
|
||||
certificate_expire = ?,
|
||||
certificate_public_key = ?,
|
||||
certificate_domain_id = ?,
|
||||
certificate_client_id = ?"
|
||||
);
|
||||
mysqli_stmt_bind_param(
|
||||
$query,
|
||||
"sssssii",
|
||||
$website,
|
||||
$website,
|
||||
$issued_by,
|
||||
$expire,
|
||||
$public_key,
|
||||
$domain_id,
|
||||
$client_id
|
||||
);
|
||||
mysqli_stmt_execute($query);
|
||||
|
||||
$extended_log_description .= ", SSL certificate $website added";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
logAction("Client", "Create", "$session_name created client $name$extended_log_description", $client_id, $client_id);
|
||||
|
||||
flash_alert("Client <strong>$name</strong> created");
|
||||
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
@@ -1390,22 +1515,25 @@ if (isset($_POST["export_client_pdf"])) {
|
||||
<th>Description</th>
|
||||
<th>Username</th>
|
||||
<th>Password</th>
|
||||
<th>TOTP</th>
|
||||
<th>URI</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>";
|
||||
while ($row = mysqli_fetch_array($sql_credentials)) {
|
||||
$credential_name = nullable_htmlentities($row["credential_name"]);
|
||||
$credential_description = nullable_htmlentities($row["credential_description"]);
|
||||
$credential_description = getFallback(nullable_htmlentities($row["credential_description"]));
|
||||
$credential_username = nullable_htmlentities(decryptCredentialEntry($row["credential_username"]));
|
||||
$credential_password = nullable_htmlentities(decryptCredentialEntry($row["credential_password"]));
|
||||
$credential_uri = nullable_htmlentities($row["credential_uri"]);
|
||||
$credential_totp_secret = getFallback(nullable_htmlentities($row['credential_otp_secret']));
|
||||
$credential_uri = getFallback(nullable_htmlentities($row["credential_uri"]));
|
||||
$html .= "
|
||||
<tr>
|
||||
<td>$credential_name</td>
|
||||
<td>$credential_description</td>
|
||||
<td>$credential_username</td>
|
||||
<td>$credential_password</td>
|
||||
<td>$credential_totp_secret</td>
|
||||
<td>$credential_uri</td>
|
||||
</tr>";
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
<?php
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
$name = sanitizeInput($_POST['name']);
|
||||
$type = sanitizeInput($_POST['type']);
|
||||
$website = preg_replace("(^https?://)", "", sanitizeInput($_POST['website']));
|
||||
$referral = sanitizeInput($_POST['referral']);
|
||||
$name = cleanInput($_POST['name']);
|
||||
$type = cleanInput($_POST['type']);
|
||||
$website = preg_replace("(^https?://)", "", cleanInput($_POST['website']));
|
||||
$referral = cleanInput($_POST['referral']);
|
||||
$rate = floatval($_POST['rate'] ?? 0);
|
||||
$net_terms = intval($_POST['net_terms'] ?? $config_default_net_terms);
|
||||
$tax_id_number = sanitizeInput($_POST['tax_id_number'] ?? '');
|
||||
$abbreviation = sanitizeInput($_POST['abbreviation']);
|
||||
$tax_id_number = cleanInput($_POST['tax_id_number'] ?? '');
|
||||
$abbreviation = cleanInput($_POST['abbreviation'] ?? '');
|
||||
if (empty($abbreviation)) {
|
||||
$abbreviation = shortenClient($name);
|
||||
$abbreviation = shortenClient($name);
|
||||
}
|
||||
$notes = sanitizeInput($_POST['notes']);
|
||||
$notes = cleanInput($_POST['notes'] ?? '');
|
||||
$lead = intval($_POST['lead'] ?? 0);
|
||||
|
||||
@@ -16,10 +16,23 @@ if (isset($_POST['add_document'])) {
|
||||
$asset_id = intval($_POST['asset'] ?? 0);
|
||||
|
||||
// Document add query
|
||||
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 = $session_user_id, document_client_id = $client_id");
|
||||
mysqli_query($mysqli,"INSERT INTO documents SET document_name = '$name', document_description = '$description', document_content = '', document_content_raw = '$content_raw', document_folder_id = $folder, document_created_by = $session_user_id, document_client_id = $client_id");
|
||||
|
||||
$document_id = mysqli_insert_id($mysqli);
|
||||
|
||||
$processed_content = mysqli_escape_string(
|
||||
$mysqli,
|
||||
saveBase64Images(
|
||||
$_POST['content'],
|
||||
$_SERVER['DOCUMENT_ROOT'] . "/uploads/documents/",
|
||||
"uploads/documents/",
|
||||
$document_id
|
||||
)
|
||||
);
|
||||
|
||||
// Document update content
|
||||
mysqli_query($mysqli,"UPDATE documents SET document_content = '$processed_content' WHERE document_id = $document_id");
|
||||
|
||||
if ($contact_id) {
|
||||
mysqli_query($mysqli,"INSERT INTO contact_documents SET contact_id = $contact_id, document_id = $document_id");
|
||||
}
|
||||
@@ -38,36 +51,82 @@ if (isset($_POST['add_document'])) {
|
||||
|
||||
if (isset($_POST['add_document_from_template'])) {
|
||||
|
||||
// ROLE Check
|
||||
enforceUserPermission('module_support', 2);
|
||||
|
||||
// GET POST Data
|
||||
$client_id = intval($_POST['client_id']);
|
||||
$document_name = sanitizeInput($_POST['name']);
|
||||
$document_description = sanitizeInput($_POST['description']);
|
||||
$document_template_id = intval($_POST['document_template_id']);
|
||||
$folder = intval($_POST['folder']);
|
||||
$client_id = intval($_POST['client_id']);
|
||||
$document_name = sanitizeInput($_POST['name']);
|
||||
$document_description = sanitizeInput($_POST['description']);
|
||||
$document_template_id = intval($_POST['document_template_id']);
|
||||
$folder = intval($_POST['folder']);
|
||||
|
||||
// GET Document Template Info
|
||||
$sql_document = mysqli_query($mysqli,"SELECT * FROM document_templates WHERE document_template_id = $document_template_id");
|
||||
// Get template
|
||||
$sql_document = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT * FROM document_templates
|
||||
WHERE document_template_id = $document_template_id"
|
||||
);
|
||||
|
||||
$row = mysqli_fetch_array($sql_document);
|
||||
|
||||
$document_template_name = sanitizeInput($row['document_template_name']);
|
||||
$content = mysqli_real_escape_string($mysqli,$row['document_template_content']);
|
||||
$content_raw = sanitizeInput($_POST['name'] . " " . str_replace("<", " <", $row['document_content']));
|
||||
$template_content_html = $row['document_template_content']; // raw HTML from template
|
||||
|
||||
// Document add query
|
||||
mysqli_query($mysqli,"INSERT INTO documents SET document_name = '$document_name', document_description = '$document_description', document_content = '$content', document_content_raw = '$content_raw', document_folder_id = $folder, document_created_by = $session_user_id, document_client_id = $client_id");
|
||||
// 1) Create the new document with placeholder content to get an ID
|
||||
mysqli_query(
|
||||
$mysqli,
|
||||
"INSERT INTO documents SET
|
||||
document_name = '$document_name',
|
||||
document_description = '$document_description',
|
||||
document_content = '',
|
||||
document_content_raw = '',
|
||||
document_folder_id = $folder,
|
||||
document_created_by = $session_user_id,
|
||||
document_client_id = $client_id"
|
||||
);
|
||||
|
||||
$document_id = mysqli_insert_id($mysqli);
|
||||
|
||||
logAction("Document", "Create", "$session_name created document $name from template $document_template_name", $client_id, $document_id);
|
||||
// 2) Copy template images to the document's folder
|
||||
$templateFsPath = $_SERVER['DOCUMENT_ROOT'] . "/uploads/document_templates/" . $document_template_id;
|
||||
$documentFsPath = $_SERVER['DOCUMENT_ROOT'] . "/uploads/documents/" . $document_id;
|
||||
|
||||
copyDirectory($templateFsPath, $documentFsPath);
|
||||
|
||||
// 3) Rewrite image paths in the HTML
|
||||
// /uploads/document_templates/{template_id}/ -> /uploads/documents/{document_id}/
|
||||
$oldPath = "/uploads/document_templates/" . $document_template_id . "/";
|
||||
$newPath = "/uploads/documents/" . $document_id . "/";
|
||||
|
||||
$processed_html = str_replace($oldPath, $newPath, $template_content_html);
|
||||
|
||||
// 4) Prepare content + content_raw
|
||||
$content = mysqli_real_escape_string($mysqli, $processed_html);
|
||||
|
||||
$content_raw = sanitizeInput(
|
||||
$document_name . " " . str_replace("<", " <", $processed_html)
|
||||
);
|
||||
$content_raw = mysqli_real_escape_string($mysqli, $content_raw);
|
||||
|
||||
// 5) Update the document with final content
|
||||
mysqli_query(
|
||||
$mysqli,
|
||||
"UPDATE documents SET
|
||||
document_content = '$content',
|
||||
document_content_raw = '$content_raw'
|
||||
WHERE document_id = $document_id"
|
||||
);
|
||||
|
||||
logAction(
|
||||
"Document",
|
||||
"Create",
|
||||
"$session_name created document $document_name from template $document_template_name",
|
||||
$client_id,
|
||||
$document_id
|
||||
);
|
||||
|
||||
flash_alert("Document <strong>$document_name</strong> created from template");
|
||||
|
||||
redirect("document_details.php?client_id=$client_id&document_id=$document_id");
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['edit_document'])) {
|
||||
@@ -75,22 +134,26 @@ if (isset($_POST['edit_document'])) {
|
||||
enforceUserPermission('module_support', 2);
|
||||
|
||||
require_once 'document_model.php';
|
||||
|
||||
$document_id = intval($_POST['document_id']);
|
||||
|
||||
// Save Original Document as a Version
|
||||
$sql_original_document = mysqli_query($mysqli, "SELECT * FROM documents
|
||||
WHERE document_client_id = $client_id AND document_id = $document_id"
|
||||
// 1) Load the current document to create a version
|
||||
$sql_original_document = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT * FROM documents
|
||||
WHERE document_client_id = $client_id
|
||||
AND document_id = $document_id"
|
||||
);
|
||||
|
||||
$row = mysqli_fetch_array($sql_original_document);
|
||||
|
||||
$original_document_name = sanitizeInput($row['document_name']);
|
||||
$original_document_name = sanitizeInput($row['document_name']);
|
||||
$original_document_description = sanitizeInput($row['document_description']);
|
||||
$original_document_content = mysqli_escape_string($mysqli, $row['document_content']);
|
||||
$original_document_created_by = intval($row['document_created_by']);
|
||||
$original_document_updated_by = intval($row['document_updated_by']);
|
||||
$original_document_created_at = sanitizeInput($row['document_created_at']);
|
||||
$original_document_updated_at = sanitizeInput($row['document_updated_at']);
|
||||
$original_document_content = mysqli_real_escape_string($mysqli, $row['document_content']);
|
||||
$original_document_created_by = intval($row['document_created_by']);
|
||||
$original_document_updated_by = intval($row['document_updated_by']);
|
||||
$original_document_created_at = sanitizeInput($row['document_created_at']);
|
||||
$original_document_updated_at = sanitizeInput($row['document_updated_at']);
|
||||
|
||||
if ($original_document_updated_at) {
|
||||
$document_version_created_at = $original_document_updated_at;
|
||||
@@ -104,19 +167,66 @@ if (isset($_POST['edit_document'])) {
|
||||
$document_version_created_by = $original_document_created_by;
|
||||
}
|
||||
|
||||
// Document add query
|
||||
mysqli_query($mysqli,"INSERT INTO document_versions SET document_version_name = '$original_document_name', document_version_description = '$original_document_description', document_version_content = '$original_document_content', document_version_created_by = $document_version_created_by, document_version_created_at = '$document_version_created_at', document_version_document_id = $document_id");
|
||||
// 2) Save the current version into document_versions
|
||||
mysqli_query(
|
||||
$mysqli,
|
||||
"INSERT INTO document_versions SET
|
||||
document_version_name = '$original_document_name',
|
||||
document_version_description = '$original_document_description',
|
||||
document_version_content = '$original_document_content',
|
||||
document_version_created_by = $document_version_created_by,
|
||||
document_version_created_at = '$document_version_created_at',
|
||||
document_version_document_id = $document_id"
|
||||
);
|
||||
|
||||
$document_version_id = mysqli_insert_id($mysqli);
|
||||
|
||||
// Update Document
|
||||
mysqli_query($mysqli,"UPDATE documents SET document_name = '$name', document_description = '$description', document_content = '$content', document_content_raw = '$content_raw', document_folder_id = $folder, document_updated_by = $session_user_id WHERE document_id = $document_id");
|
||||
// 3) Process the NEW content from the form:
|
||||
// - convert base64 <img> tags to files under /uploads/documents/<document_id>/
|
||||
// - rewrite <img src> to file URLs
|
||||
$raw_post_content = $_POST['content'];
|
||||
|
||||
logAction("Document", "Edit", "$session_name edited document $name, previous version kept", $client_id, $document_version_id);
|
||||
$processed_html = saveBase64Images(
|
||||
$raw_post_content,
|
||||
$_SERVER['DOCUMENT_ROOT'] . "/uploads/documents/",
|
||||
"uploads/documents/",
|
||||
$document_id
|
||||
);
|
||||
|
||||
// Escape for DB
|
||||
$content = mysqli_real_escape_string($mysqli, $processed_html);
|
||||
|
||||
// Rebuild content_raw for full-text search
|
||||
$content_raw = sanitizeInput(
|
||||
$name . " " . str_replace("<", " <", $processed_html)
|
||||
);
|
||||
$content_raw = mysqli_real_escape_string($mysqli, $content_raw);
|
||||
|
||||
// 4) Update the document with the new content + metadata
|
||||
mysqli_query(
|
||||
$mysqli,
|
||||
"UPDATE documents SET
|
||||
document_name = '$name',
|
||||
document_description = '$description',
|
||||
document_content = '$content',
|
||||
document_content_raw = '$content_raw',
|
||||
document_folder_id = $folder,
|
||||
document_updated_by = $session_user_id
|
||||
WHERE document_id = $document_id"
|
||||
);
|
||||
|
||||
logAction(
|
||||
"Document",
|
||||
"Edit",
|
||||
"$session_name edited document $name, previous version kept",
|
||||
$client_id,
|
||||
$document_version_id
|
||||
);
|
||||
|
||||
flash_alert("Document <strong>$name</strong> edited, previous version kept");
|
||||
|
||||
redirect("document_details.php?client_id=$client_id&document_id=$document_id");
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['move_document'])) {
|
||||
@@ -629,6 +739,9 @@ if (isset($_GET['delete_document'])) {
|
||||
// Delete all versions associated with the master document
|
||||
mysqli_query($mysqli,"DELETE FROM document_versions WHERE document_version_document_id = $document_id");
|
||||
|
||||
// Delete uploads/document/$document_id if exists
|
||||
removeDirectory($_SERVER['DOCUMENT_ROOT'] . "/uploads/documents/" . $document_id);
|
||||
|
||||
logAction("Document", "Delete", "$session_name deleted document $document_name and all versions", $client_id);
|
||||
|
||||
flash_alert("Document <strong>$document_name</strong> deleted and all versions", 'error');
|
||||
@@ -670,6 +783,9 @@ if (isset($_POST['bulk_delete_documents'])) {
|
||||
// Delete all versions associated with the master document
|
||||
mysqli_query($mysqli,"DELETE FROM document_versions WHERE document_version_document_id = $document_id");
|
||||
|
||||
// Delete uploads/document/$document_id if exists
|
||||
removeDirectory($_SERVER['DOCUMENT_ROOT'] . "/uploads/documents/" . $document_id);
|
||||
|
||||
logAction("Document", "Delete", "$session_name deleted document $document_name and all versions", $client_id);
|
||||
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ if (isset($_POST['add_invoice'])) {
|
||||
|
||||
$client_id = intval($_POST['client']);
|
||||
|
||||
$invoice_amount = 0 - $invoice_discount; // Calc amount if discount is applied, otherwise wrongly shows 0
|
||||
|
||||
// Get Net Terms
|
||||
$client_net_terms = intval(getFieldById('clients', $client_id, 'client_net_terms'));
|
||||
|
||||
@@ -23,7 +25,7 @@ if (isset($_POST['add_invoice'])) {
|
||||
//Generate a unique URL key for clients to access
|
||||
$url_key = randomString(156);
|
||||
|
||||
mysqli_query($mysqli,"INSERT INTO invoices SET invoice_prefix = '$config_invoice_prefix', invoice_number = $invoice_number, invoice_scope = '$scope', invoice_date = '$date', invoice_due = DATE_ADD('$date', INTERVAL $client_net_terms day), invoice_currency_code = '$session_company_currency', invoice_category_id = $category, invoice_status = 'Draft', invoice_url_key = '$url_key', invoice_client_id = $client_id");
|
||||
mysqli_query($mysqli,"INSERT INTO invoices SET invoice_prefix = '$config_invoice_prefix', invoice_number = $invoice_number, invoice_scope = '$scope', invoice_date = '$date', invoice_due = DATE_ADD('$date', INTERVAL $client_net_terms day), invoice_discount_amount = '$invoice_discount', invoice_amount = '$invoice_amount', invoice_currency_code = '$session_company_currency', invoice_category_id = $category, invoice_status = 'Draft', invoice_url_key = '$url_key', invoice_client_id = $client_id");
|
||||
|
||||
$invoice_id = mysqli_insert_id($mysqli);
|
||||
|
||||
|
||||
@@ -497,7 +497,7 @@ if (isset($_GET['email_quote'])) {
|
||||
|
||||
logAction("Quote", "Email", "$session_name emailed quote $quote_prefix$quote_number to $contact_email", $client_id, $quote_id);
|
||||
|
||||
flash_alert("Quote has been queued successfully! <a class='text-bold text-light' href='admin_mail_queue.php'>See Mail Queue</a>");
|
||||
flash_alert("Quote sent!");
|
||||
|
||||
//Don't change the status to sent if the status is anything but draft
|
||||
if ($quote_status == 'Draft') {
|
||||
|
||||
@@ -1814,14 +1814,19 @@ if (isset($_POST['merge_ticket'])) {
|
||||
|
||||
// NEW PARENT ticket details
|
||||
// Get merge into ticket id (as it may differ from the number)
|
||||
$sql = mysqli_query($mysqli, "SELECT ticket_id FROM tickets WHERE ticket_number = $merge_into_ticket_number");
|
||||
$sql = mysqli_query($mysqli, "SELECT ticket_id, ticket_client_id FROM tickets WHERE ticket_number = $merge_into_ticket_number");
|
||||
if (mysqli_num_rows($sql) == 0) {
|
||||
flash_alert("Cannot merge into that ticket.", 'error');
|
||||
redirect();
|
||||
}
|
||||
$merge_row = mysqli_fetch_array($sql);
|
||||
$merge_into_ticket_id = intval($merge_row['ticket_id']);
|
||||
|
||||
$client_id = intval($merge_row['ticket_client_id']);
|
||||
if ($client_id) {
|
||||
$has_client = "&client_id=$client_id";
|
||||
} else {
|
||||
$has_client = "";
|
||||
}
|
||||
// Sanity check
|
||||
if ($ticket_number == $merge_into_ticket_number) {
|
||||
flash_alert("Cannot merge into the same ticket.", 'error');
|
||||
@@ -1853,7 +1858,7 @@ if (isset($_POST['merge_ticket'])) {
|
||||
|
||||
flash_alert("Ticket merged into $ticket_prefix$merge_into_ticket_number");
|
||||
|
||||
redirect();
|
||||
redirect("ticket.php?ticket_id=$merge_into_ticket_id$has_client");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -382,10 +382,10 @@ if (isset($_GET['quote_id'])) {
|
||||
<textarea class="form-control" rows="2" name="description" id="desc" placeholder="Enter a Description"></textarea>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="-?[0-9]*\.?[0-9]{0,2}" id="qty" style="text-align: center;" name="qty" placeholder="Qty">
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="-?[0-9]*\.?[0-9]{0,2}" id="qty" style="text-align: center;" name="qty" placeholder="Qty">
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="-?[0-9]*\.?[0-9]{0,2}" id="price" style="text-align: right;" name="price" placeholder="Price (<?php echo $quote_currency_code; ?>)">
|
||||
<input type="text" class="form-control" inputmode="decimal" pattern="-?[0-9]*\.?[0-9]{0,2}" id="price" style="text-align: right;" name="price" placeholder="Price (<?php echo $quote_currency_code; ?>)">
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control select2" id="tax" name="tax_id" required>
|
||||
@@ -439,7 +439,7 @@ if (isset($_GET['quote_id'])) {
|
||||
</div>
|
||||
|
||||
<div class="col-sm-3 offset-sm-2">
|
||||
|
||||
|
||||
<table class="table table-hover mb-0">
|
||||
<tbody>
|
||||
<tr>
|
||||
@@ -464,7 +464,7 @@ if (isset($_GET['quote_id'])) {
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -621,4 +621,4 @@ new Sortable(document.querySelector('table#items tbody'), {
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<link rel="stylesheet" href="css/quote_dropdowns_fix.css">
|
||||
<link rel="stylesheet" href="css/quote_dropdowns_fix.css">
|
||||
|
||||
@@ -9,9 +9,6 @@ require_once "includes/inc_all.php";
|
||||
// Perms
|
||||
enforceUserPermission('module_financial');
|
||||
|
||||
//Rebuild URL
|
||||
$url_query_strings_sort = http_build_query($get_copy);
|
||||
|
||||
$sql = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT SQL_CALC_FOUND_ROWS * FROM recurring_expenses
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// If client_id is in URI then show client Side Bar and client header
|
||||
if (isset($_GET['client_id'])) {
|
||||
require_once "includes/inc_all_client.php";
|
||||
} else {
|
||||
} else {
|
||||
require_once "includes/inc_all.php";
|
||||
}
|
||||
|
||||
@@ -292,7 +292,7 @@ if (isset($_GET['recurring_invoice_id'])) {
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-sm btn-link drag-handle">
|
||||
<i class="fas fa-bars text-muted"></i>
|
||||
</button>
|
||||
</button>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-sm btn-light" type="button" data-toggle="dropdown">
|
||||
<i class="fas fa-ellipsis-v"></i>
|
||||
@@ -340,10 +340,10 @@ if (isset($_GET['recurring_invoice_id'])) {
|
||||
<textarea class="form-control" rows="2" id="desc" name="description" placeholder="Enter a Description"></textarea>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" class="form-control" style="text-align: center;" id="qty" name="qty" placeholder="Qty">
|
||||
<input type="text" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" class="form-control" style="text-align: center;" id="qty" name="qty" placeholder="Qty">
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" class="form-control" style="text-align: right;" id="price" name="price" placeholder="Price (<?php echo $recurring_invoice_currency_code; ?>)">
|
||||
<input type="text" inputmode="decimal" pattern="[0-9]*\.?[0-9]{0,2}" class="form-control" style="text-align: right;" id="price" name="price" placeholder="Price (<?php echo $recurring_invoice_currency_code; ?>)">
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" name="tax_id" id="tax" required>
|
||||
|
||||
@@ -9,9 +9,6 @@ require_once "includes/inc_all.php";
|
||||
// Perms
|
||||
enforceUserPermission('module_financial');
|
||||
|
||||
//Rebuild URL
|
||||
$url_query_strings_sort = http_build_query($get_copy);
|
||||
|
||||
$sql = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT SQL_CALC_FOUND_ROWS * FROM revenues
|
||||
|
||||
122
agent/ticket.php
122
agent/ticket.php
@@ -39,7 +39,6 @@ if (isset($_GET['ticket_id'])) {
|
||||
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
|
||||
LEFT JOIN categories ON ticket_category = category_id
|
||||
WHERE ticket_id = $ticket_id
|
||||
$access_permission_query
|
||||
LIMIT 1"
|
||||
);
|
||||
|
||||
@@ -358,9 +357,11 @@ if (isset($_GET['ticket_id'])) {
|
||||
<li class="breadcrumb-item">
|
||||
<a href="tickets.php">All Tickets</a>
|
||||
</li>
|
||||
<?php if ($client_url) { ?>
|
||||
<li class="breadcrumb-item">
|
||||
<a href="tickets.php?client_id=<?php echo $client_id; ?>"><?= $client_name ?> Tickets</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<li class="breadcrumb-item active"><?php echo "$ticket_prefix$ticket_number";?></li>
|
||||
</ol>
|
||||
|
||||
@@ -415,18 +416,13 @@ if (isset($_GET['ticket_id'])) {
|
||||
<i class="fas fa-fw fa-ellipsis-v"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-size = "lg"
|
||||
data-modal-url="modals/ticket/ticket_edit.php?id=<?= $ticket_id ?>">
|
||||
<i class="fas fa-fw fa-edit mr-2"></i>Edit
|
||||
</a>
|
||||
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/ticket/ticket_summary.php?ticket_id=<?= $ticket_id ?>" data-modal-size="lg">
|
||||
<i class="fas fa-fw fa-lightbulb mr-2"></i>Summarize
|
||||
</a>
|
||||
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/ticket/ticket_merge.php?ticket_id=<?= $ticket_id ?>">
|
||||
<i class="fas fa-fw fa-clone mr-2"></i>Merge
|
||||
</a>
|
||||
<?php if (empty($ticket_closed_at)) { ?>
|
||||
<?php if (empty($ticket_closed_at) && $client_id) { ?>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/ticket/ticket_contact.php?id=<?= $ticket_id ?>">
|
||||
@@ -564,9 +560,14 @@ if (isset($_GET['ticket_id'])) {
|
||||
<div class="card card-dark mb-3">
|
||||
|
||||
<div class="card-header bg-dark">
|
||||
<h3 class="card-title">
|
||||
<h5 class="card-title">
|
||||
Ticket Details
|
||||
</h3>
|
||||
</h5>
|
||||
<?php if (empty($ticket_closed_at)) { ?>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-tool ajax-modal" data-modal-url="modals/ticket/ticket_edit.php?id=<?= $ticket_id ?>" data-modal-size="lg"><i class="fas fa-edit"></i></button>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
<div class="card-body prettyContent" id="ticketDetails">
|
||||
@@ -599,9 +600,11 @@ if (isset($_GET['ticket_id'])) {
|
||||
<label class="btn btn-outline-dark active">
|
||||
<input type="radio" name="public_reply_type" value="0" checked>Internal Note
|
||||
</label>
|
||||
<?php if ($contact_email) { ?>
|
||||
<label class="btn btn-outline-info">
|
||||
<input type="radio" name="public_reply_type" value="2">Public Comment & Email
|
||||
</label>
|
||||
<?php } ?>
|
||||
<label class="btn btn-outline-info">
|
||||
<input type="radio" name="public_reply_type" value="1">Public Comment
|
||||
</label>
|
||||
@@ -807,16 +810,17 @@ if (isset($_GET['ticket_id'])) {
|
||||
<div class="col-md-3">
|
||||
|
||||
<!-- Ticket details right card -->
|
||||
<div class="card">
|
||||
<div class="card <?php if(!$ticket_resolved_at) { echo "collapsed-card"; } ?>">
|
||||
<div class="card-header">
|
||||
<a class="text-reset text-decoration-none" href="#" data-toggle="collapse" data-target="#ticketDetailsCard">
|
||||
<h5 class="card-title mt-1"><i class="fas fa-fw fa-life-ring mr-2"></i>Ticket Details</h5>
|
||||
</a>
|
||||
<h5 class="card-title"><i class="fas fa-fw fa-life-ring mr-2"></i>Ticket Details</h5>
|
||||
|
||||
<div class="card-tools">
|
||||
<a class="fa fa-chevron-down" href="#" data-toggle="collapse" data-target="#ticketDetailsCard"></a>
|
||||
<button type="button" class="btn btn-tool" data-card-widget="collapse">
|
||||
<i class="fas fa-chevron-down"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body collapse <?php echo !empty($ticket_resolved_at) ? 'show' : ''; ?>" id="ticketDetailsCard">
|
||||
<div class="card-body">
|
||||
|
||||
<!-- Created -->
|
||||
<div title="<?php echo $ticket_created_at; ?>">
|
||||
@@ -912,12 +916,12 @@ if (isset($_GET['ticket_id'])) {
|
||||
<!-- Tasks Card -->
|
||||
<?php if (empty($ticket_resolved_at) || (!empty($ticket_resolved_at) && $task_count > 0)) { ?>
|
||||
<div class="card">
|
||||
<div class="card-header py-2">
|
||||
<h5 class="card-title"><i class="fas fa-fw fa-tasks mr-2 mt-2"></i>Tasks</h5>
|
||||
<div class="card-header">
|
||||
<h5 class="card-title"><i class="fas fa-fw fa-tasks mr-2"></i>Tasks</h5>
|
||||
<?php if (empty($ticket_resolved_at) && lookupUserPermission("module_support") >= 2) { ?>
|
||||
<div class="card-tools">
|
||||
<?php if (empty($ticket_resolved_at) && lookupUserPermission("module_support") >= 2) { ?>
|
||||
<div class="dropdown dropleft text-center">
|
||||
<button class="btn btn-light text-secondary btn-sm" type="button" data-toggle="dropdown">
|
||||
<button class="btn btn-tool" type="button" data-toggle="dropdown">
|
||||
<i class="fas fa-ellipsis-v"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
@@ -934,8 +938,8 @@ if (isset($_GET['ticket_id'])) {
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
|
||||
@@ -964,7 +968,7 @@ if (isset($_GET['ticket_id'])) {
|
||||
$task_completion_estimate = intval($row['task_completion_estimate']);
|
||||
$task_completed_at = nullable_htmlentities($row['task_completed_at']);
|
||||
?>
|
||||
<tr data-task-id="<?php echo $task_id; ?>">
|
||||
<tr data-task-id="<?= $task_id ?>">
|
||||
<td>
|
||||
<?php if ($task_completed_at) { ?>
|
||||
<i class="far fa-check-square text-success"></i>
|
||||
@@ -1022,16 +1026,16 @@ if (isset($_GET['ticket_id'])) {
|
||||
<!-- Contact card -->
|
||||
<?php if ($contact_id) { ?>
|
||||
<div class="card">
|
||||
<div class="card-header py-2">
|
||||
<h5 class="card-title"><i class="fas fa-fw fa-user-check mr-2 mt-2"></i>Contact</h5>
|
||||
<div class="card-header">
|
||||
<h5 class="card-title"><i class="fas fa-fw fa-user-check mr-2"></i>Contact</h5>
|
||||
<?php if (empty($ticket_resolved_at) && lookupUserPermission("module_support") >= 2) { ?>
|
||||
<div class="card-tools">
|
||||
<?php if (empty($ticket_resolved_at) && lookupUserPermission("module_support") >= 2) { ?>
|
||||
<a class="btn btn-light text-secondary btn-sm ajax-modal" href="#"
|
||||
data-modal-url="modals/ticket/ticket_contact.php?id=<?= $ticket_id ?>">
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
<?php } ?>
|
||||
<a class="btn btn-tool ajax-modal" href="#"
|
||||
data-modal-url="modals/ticket/ticket_contact.php?id=<?= $ticket_id ?>">
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
@@ -1073,23 +1077,19 @@ if (isset($_GET['ticket_id'])) {
|
||||
<?php } ?>
|
||||
<!-- End contact card -->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Ticket watchers card -->
|
||||
<?php if (empty($ticket_closed_at) && mysqli_num_rows($sql_ticket_watchers) > 0) { ?>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header py-2">
|
||||
<h5 class="card-title"><i class="fas fa-fw fa-eye mr-2 mt-2"></i>Watchers</h5>
|
||||
<div class="card-header">
|
||||
<h5 class="card-title"><i class="fas fa-fw fa-eye mr-2"></i>Watchers</h5>
|
||||
<?php if (empty($ticket_resolved_at) && lookupUserPermission("module_support") >= 2) { ?>
|
||||
<div class="card-tools">
|
||||
<?php if (empty($ticket_resolved_at) && lookupUserPermission("module_support") >= 2) { ?>
|
||||
<a class="btn btn-light text-secondary btn-sm ajax-modal" href="#" data-modal-url="modals/ticket/ticket_add_watcher.php?ticket_id=<?= $ticket_id ?>">
|
||||
<i class="fas fa-fw fa-plus"></i>
|
||||
</a>
|
||||
<?php } ?>
|
||||
<a class="btn btn-tool ajax-modal" href="#" data-modal-url="modals/ticket/ticket_add_watcher.php?ticket_id=<?= $ticket_id ?>">
|
||||
<i class="fas fa-fw fa-plus"></i>
|
||||
</a>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
@@ -1117,15 +1117,15 @@ if (isset($_GET['ticket_id'])) {
|
||||
<!-- Asset card -->
|
||||
<?php if ($asset_id) { ?>
|
||||
<div class="card mb-3">
|
||||
<div class="card-header py-2">
|
||||
<h5 class="card-title"><i class="fas fa-fw fa-desktop mr-2 mt-2"></i>Assets</h5>
|
||||
<div class="card-header">
|
||||
<h5 class="card-title"><i class="fas fa-fw fa-desktop mr-2"></i>Assets</h5>
|
||||
<?php if (empty($ticket_resolved_at) && lookupUserPermission("module_support") >= 2) { ?>
|
||||
<div class="card-tools">
|
||||
<?php if (empty($ticket_resolved_at) && lookupUserPermission("module_support") >= 2) { ?>
|
||||
<a class="btn btn-light text-secondary btn-sm ajax-modal" href="#" data-modal-url="modals/ticket/ticket_edit_asset.php?id=<?= $ticket_id ?>">
|
||||
<i class="fas fa-fw fa-edit"></i>
|
||||
</a>
|
||||
<?php } ?>
|
||||
<a class="btn btn-tool ajax-modal" href="#" data-modal-url="modals/ticket/ticket_edit_asset.php?id=<?= $ticket_id ?>">
|
||||
<i class="fas fa-fw fa-edit"></i>
|
||||
</a>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div>
|
||||
@@ -1165,15 +1165,15 @@ if (isset($_GET['ticket_id'])) {
|
||||
<!-- Vendor card -->
|
||||
<?php if ($vendor_id) { ?>
|
||||
<div class="card mb-3">
|
||||
<div class="card-header py-2">
|
||||
<h5 class="card-title"><i class="fas fa-fw fa-building mr-2 mt-2"></i>Vendor</h5>
|
||||
<div class="card-header">
|
||||
<h5 class="card-title"><i class="fas fa-fw fa-building mr-2"></i>Vendor</h5>
|
||||
<?php if (empty($ticket_resolved_at) && lookupUserPermission("module_support") >= 2) { ?>
|
||||
<div class="card-tools">
|
||||
<?php if (empty($ticket_resolved_at) && lookupUserPermission("module_support") >= 2) { ?>
|
||||
<a class="btn btn-light text-secondary btn-sm ajax-modal" href="#" data-modal-url="modals/ticket/ticket_edit_vendor.php?ticket_id=<?= $ticket_id ?>">
|
||||
<i class="fas fa-fw fa-edit"></i>
|
||||
</a>
|
||||
<?php } ?>
|
||||
<a class="btn btn-tool ajax-modal" href="#" data-modal-url="modals/ticket/ticket_edit_vendor.php?ticket_id=<?= $ticket_id ?>">
|
||||
<i class="fas fa-fw fa-edit"></i>
|
||||
</a>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
@@ -1220,15 +1220,15 @@ if (isset($_GET['ticket_id'])) {
|
||||
<!-- project card -->
|
||||
<?php if ($project_id) { ?>
|
||||
<div class="card">
|
||||
<div class="card-header py-2">
|
||||
<h5 class="card-title"><i class="fas fa-fw fa-project-diagram mr-2 mt-2"></i>Project</h5>
|
||||
<div class="card-header">
|
||||
<h5 class="card-title"><i class="fas fa-fw fa-project-diagram mr-2"></i>Project</h5>
|
||||
<?php if (empty($ticket_resolved_at) && lookupUserPermission("module_support") >= 2) { ?>
|
||||
<div class="card-tools">
|
||||
<?php if (empty($ticket_resolved_at) && lookupUserPermission("module_support") >= 2) { ?>
|
||||
<button type="button" class="btn btn-light text-secondary btn-sm ajax-modal" data-modal-url="modals/ticket/ticket_edit_project.php?id=<?= $ticket_id ?>">
|
||||
<i class="fas fa-edit"></i>
|
||||
</button>
|
||||
<?php } ?>
|
||||
<button type="button" class="btn btn-tool ajax-modal" data-modal-url="modals/ticket/ticket_edit_project.php?id=<?= $ticket_id ?>">
|
||||
<i class="fas fa-edit"></i>
|
||||
</button>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div>
|
||||
|
||||
@@ -108,6 +108,11 @@
|
||||
$contact_id = intval($row['contact_id']);
|
||||
$contact_name = nullable_htmlentities($row['contact_name']);
|
||||
$contact_email = nullable_htmlentities($row['contact_email']);
|
||||
if ($client_id) {
|
||||
$has_client = "&client_id=$client_id";
|
||||
} else {
|
||||
$has_client = "";
|
||||
}
|
||||
|
||||
if ($ticket_priority == "High") {
|
||||
$ticket_priority_color = "danger";
|
||||
@@ -197,14 +202,14 @@
|
||||
|
||||
<!-- Ticket Number -->
|
||||
<td>
|
||||
<a href="ticket.php?client_id=<?= $client_id ?>&ticket_id=<?= $ticket_id ?>">
|
||||
<a href="ticket.php?ticket_id=<?= "$ticket_id$has_client" ?>">
|
||||
<span class="badge badge-pill badge-secondary p-3"><?php echo "$ticket_prefix$ticket_number"; ?></span>
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<!-- Ticket Subject -->
|
||||
<td>
|
||||
<a href="ticket.php?client_id=<?= $client_id ?>&ticket_id=<?= $ticket_id ?>"><?= $ticket_subject ?></a>
|
||||
<a href="ticket.php?ticket_id=<?= "$ticket_id$has_client" ?>"><?= $ticket_subject ?></a>
|
||||
|
||||
<?php if($task_count && $completed_task_count > 0) { ?>
|
||||
<div class="progress mt-2" style="height: 20px;">
|
||||
|
||||
@@ -28,10 +28,6 @@ if (isset($_GET['account_to']) & !empty($_GET['account_to'])) {
|
||||
$account_to_filter = '';
|
||||
}
|
||||
|
||||
|
||||
//Rebuild URL
|
||||
$url_query_strings_sort = http_build_query($get_copy);
|
||||
|
||||
$sql = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT SQL_CALC_FOUND_ROWS transfer_created_at, expense_date AS transfer_date, expense_amount AS transfer_amount, expense_account_id AS transfer_account_from, revenue_account_id AS transfer_account_to, transfer_expense_id, transfer_revenue_id , transfer_id, transfer_method, transfer_notes FROM transfers, expenses, revenues
|
||||
|
||||
@@ -15,9 +15,6 @@ if (isset($_GET['client_id'])) {
|
||||
$client_url = '';
|
||||
}
|
||||
|
||||
//Rebuild URL
|
||||
$url_query_strings_sort = http_build_query($get_copy);
|
||||
|
||||
$sql = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT SQL_CALC_FOUND_ROWS * FROM trips
|
||||
|
||||
@@ -13,12 +13,25 @@ $insert_id = false;
|
||||
if (!empty($name) && !(empty($content))) {
|
||||
|
||||
// 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_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 = '', document_content_raw = '$content_raw', document_folder_id = $folder, document_created_by = 0, document_client_id = $client_id");
|
||||
|
||||
// Check insert & get insert ID
|
||||
if ($insert_sql) {
|
||||
$insert_id = mysqli_insert_id($mysqli);
|
||||
|
||||
$processed_content = mysqli_escape_string(
|
||||
$mysqli,
|
||||
saveBase64Images(
|
||||
$content,
|
||||
$_SERVER['DOCUMENT_ROOT'] . "/uploads/documents/",
|
||||
"uploads/documents/",
|
||||
$insert_id
|
||||
)
|
||||
);
|
||||
|
||||
// Document update content
|
||||
mysqli_query($mysqli,"UPDATE documents SET document_content = '$processed_content' WHERE document_id = $insert_id");
|
||||
|
||||
// Logging
|
||||
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);
|
||||
|
||||
@@ -17,7 +17,17 @@ if (!empty($document_id)) {
|
||||
// Variable assignment from POST - assigning the current database value if a value is not provided
|
||||
require_once 'document_model.php';
|
||||
|
||||
$update_insert_sql = mysqli_query($mysqli,"UPDATE documents SET document_name = '$name', document_description = '$description', document_content = '$content', document_content_raw = '$content_raw', document_folder_id = $folder, document_updated_by = 0, document_client_id = $client_id");
|
||||
$processed_content = mysqli_escape_string(
|
||||
$mysqli,
|
||||
saveBase64Images(
|
||||
$content,
|
||||
$_SERVER['DOCUMENT_ROOT'] . "/uploads/documents/",
|
||||
"uploads/documents/",
|
||||
$document_id
|
||||
)
|
||||
);
|
||||
|
||||
$update_insert_sql = mysqli_query($mysqli,"UPDATE documents SET document_name = '$name', document_description = '$description', document_content = '$processed_content', document_content_raw = '$content_raw', document_folder_id = $folder, document_updated_by = 0, document_client_id = $client_id");
|
||||
|
||||
// Logging
|
||||
logAction("Document", "Edit", "$name via API ($api_key_name)", $client_id, $document_id);
|
||||
|
||||
@@ -49,7 +49,7 @@ if (isset($_POST['add_ticket'])) {
|
||||
$details = removeEmoji($details);
|
||||
|
||||
$email_subject = "ITFlow - New Ticket - $client_name: $subject";
|
||||
$email_body = "Hello, <br><br>This is a notification that a new ticket has been raised in ITFlow. <br>Client: $client_name<br>Priority: $priority<br>Link: https://$config_base_url/ticket.php?ticket_id=$ticket_id <br><br><b>$subject</b><br>$details";
|
||||
$email_body = "Hello, <br><br>This is a notification that a new ticket has been raised in ITFlow. <br>Client: $client_name<br>Priority: $priority<br>Link: https://$config_base_url/agent/ticket.php?ticket_id=$ticket_id&client_id=$session_client_id <br><br><b>$subject</b><br>$details";
|
||||
|
||||
// Queue Mail
|
||||
$data = [
|
||||
@@ -113,7 +113,7 @@ if (isset($_POST['add_ticket_comment'])) {
|
||||
$tech_name = sanitizeInput($tech_details['user_name']);
|
||||
|
||||
$subject = "$config_app_name Ticket updated - [$config_ticket_prefix$ticket_number] $ticket_subject";
|
||||
$body = "Hello $tech_name,<br><br>A new reply has been added to the below ticket, check ITFlow for full details.<br><br>Client: $client_name<br>Ticket: $config_ticket_prefix$ticket_number<br>Subject: $ticket_subject<br><br>https://$config_base_url/ticket.php?ticket_id=$ticket_id";
|
||||
$body = "Hello $tech_name,<br><br>A new reply has been added to the below ticket, check ITFlow for full details.<br><br>Client: $client_name<br>Ticket: $config_ticket_prefix$ticket_number<br>Subject: $ticket_subject<br><br>https://$config_base_url/agent/ticket.php?ticket_id=$ticket_id&client_id=$session_client_id";
|
||||
|
||||
$data = [
|
||||
[
|
||||
@@ -440,7 +440,7 @@ if (isset($_GET['add_payment_by_provider'])) {
|
||||
$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"
|
||||
WHERE invoice_id = $invoice_id AND client_id = $session_client_id"
|
||||
);
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$invoice_number = intval($row['invoice_number']);
|
||||
@@ -1075,14 +1075,13 @@ if (isset($_POST['client_add_document'])) {
|
||||
|
||||
$document_name = sanitizeInput($_POST['document_name']);
|
||||
$document_description = sanitizeInput($_POST['document_description']);
|
||||
$document_content = mysqli_real_escape_string($mysqli, $_POST['document_content']);
|
||||
$document_content_raw = sanitizeInput($document_name . " " . strip_tags($_POST['document_content']));
|
||||
|
||||
// Create document
|
||||
mysqli_query($mysqli, "INSERT INTO documents SET
|
||||
document_name = '$document_name',
|
||||
document_description = '$document_description',
|
||||
document_content = '$document_content',
|
||||
document_content = '',
|
||||
document_content_raw = '$document_content_raw',
|
||||
document_client_visible = 1,
|
||||
document_client_id = $session_client_id,
|
||||
@@ -1090,6 +1089,19 @@ if (isset($_POST['client_add_document'])) {
|
||||
|
||||
$document_id = mysqli_insert_id($mysqli);
|
||||
|
||||
$processed_content = mysqli_escape_string(
|
||||
$mysqli,
|
||||
saveBase64Images(
|
||||
$_POST['document_content'],
|
||||
$_SERVER['DOCUMENT_ROOT'] . "/uploads/documents/",
|
||||
"uploads/documents/",
|
||||
$document_id
|
||||
)
|
||||
);
|
||||
|
||||
// Document update content
|
||||
mysqli_query($mysqli,"UPDATE documents SET document_content = '$processed_content' WHERE document_id = $document_id");
|
||||
|
||||
logAction("Document", "Create", "Client contact $session_contact_name created document $document_name", $session_client_id, $document_id);
|
||||
|
||||
flash_alert("Document <strong>$document_name</strong> created successfully");
|
||||
|
||||
@@ -186,10 +186,7 @@ function sendQueueEmail(
|
||||
$mail->addAddress($to_email, $to_name);
|
||||
$mail->isHTML(true);
|
||||
$mail->Subject = $subject;
|
||||
$mail->Body = "<html><head><style>
|
||||
body { font-family: Arial, sans-serif; color: #333; line-height: 1.6; }
|
||||
.email-container { max-width: 600px; margin: auto; padding: 20px; border: 1px solid #ddd; border-radius: 5px; }
|
||||
</style></head><body><div class='email-container'>{$html_body}</div></body></html>";
|
||||
$mail->Body = $html_body;
|
||||
|
||||
if (!empty($ics_str)) {
|
||||
$mail->addStringAttachment($ics_str, 'Scheduled_ticket.ics', 'base64', 'text/calendar');
|
||||
|
||||
@@ -83,8 +83,16 @@ function addTicket($contact_id, $contact_name, $contact_email, $client_id, $date
|
||||
|
||||
// Clean up the message
|
||||
$message = trim($message);
|
||||
// Remove DOCTYPE and meta tags
|
||||
$message = preg_replace('/<!DOCTYPE[^>]*>/i', '', $message);
|
||||
$message = preg_replace('/<meta[^>]*>/i', '', $message);
|
||||
// Remove <html>, <head>, <body> and their closing tags
|
||||
$message = preg_replace('/<\/?(html|head|body)[^>]*>/i', '', $message);
|
||||
// Collapse excess whitespace
|
||||
$message = preg_replace('/\s+/', ' ', $message);
|
||||
// Convert newlines to <br>
|
||||
$message = nl2br($message);
|
||||
// Wrap final formatted message
|
||||
$message = "<i>Email from: <b>$contact_name</b> <$contact_email> at $date:-</i> <br><br><div style='line-height:1.5;'>$message</div>";
|
||||
|
||||
$ticket_prefix_esc = mysqli_real_escape_string($mysqli, $config_ticket_prefix);
|
||||
@@ -181,13 +189,37 @@ function addReply($from_email, $date, $subject, $ticket_number, $message, $attac
|
||||
global $mysqli, $config_app_name, $company_name, $company_phone, $config_ticket_prefix, $config_base_url, $config_ticket_from_name, $config_ticket_from_email, $allowed_extensions;
|
||||
|
||||
$ticket_reply_type = 'Client';
|
||||
$message_parts = explode("##- Please type your reply above this line -##", $message);
|
||||
$message_body = $message_parts[0];
|
||||
$message_body = trim($message_body);
|
||||
$message_body = preg_replace('/\r\n|\r|\n/', ' ', $message_body);
|
||||
$message_body = nl2br($message_body);
|
||||
// $message contains the raw HTML body from IMAP
|
||||
|
||||
$message = "<i>Email from: $from_email at $date:-</i> <br><br><div style='line-height:1.5;'>$message_body</div>";
|
||||
// 1) Remove the reply separator and everything below it (HTML-aware)
|
||||
// This matches: <i ...>##- Please type your reply above this line -##</i> and EVERYTHING after it
|
||||
$message = preg_replace(
|
||||
'/<i[^>]*>##-\s*Please\s+type\s+your\s+reply\s+above\s+this\s+line\s*-##<\/i>.*$/is',
|
||||
'',
|
||||
$message
|
||||
);
|
||||
|
||||
// 2) Clean up the remaining message
|
||||
|
||||
// Remove DOCTYPE and meta tags
|
||||
$message = preg_replace('/<!DOCTYPE[^>]*>/i', '', $message);
|
||||
$message = preg_replace('/<meta[^>]*>/i', '', $message);
|
||||
|
||||
// Remove <html>, <head>, <body> and their closing tags
|
||||
$message = preg_replace('/<\/?(html|head|body)[^>]*>/i', '', $message);
|
||||
|
||||
// Trim leading/trailing whitespace
|
||||
$message = trim($message);
|
||||
|
||||
// Normalize line breaks to spaces
|
||||
$message = preg_replace('/\r\n|\r|\n/', ' ', $message);
|
||||
|
||||
// Convert to <br> for HTML display
|
||||
$message = nl2br($message);
|
||||
|
||||
// 3) Final wrapper
|
||||
$message = "<i>Email from: $from_email at $date:-</i><br><br>
|
||||
<div style='line-height:1.5;'>$message</div>";
|
||||
|
||||
$ticket_number_esc = intval($ticket_number);
|
||||
$message_esc = mysqli_real_escape_string($mysqli, $message);
|
||||
@@ -598,16 +630,65 @@ foreach ($messages as $message) {
|
||||
}
|
||||
}
|
||||
|
||||
// Decide whether it's a reply to an existing ticket or a new ticket
|
||||
// 1. Reply to existing ticket with the number in subject
|
||||
if (preg_match("/\[$config_ticket_prefix(\d+)\]/", $subject, $ticket_number_matches)) {
|
||||
$ticket_number = intval($ticket_number_matches[1]);
|
||||
if (addReply($from_email, $date, $subject, $ticket_number, $message_body, $attachments)) {
|
||||
$email_processed = true;
|
||||
}
|
||||
} else {
|
||||
// Known contact?
|
||||
$email_processed = addReply($from_email, $date, $subject, $ticket_number, $message_body, $attachments);
|
||||
}
|
||||
|
||||
// 2. Fuzzy duplicate check using a known contact/domain and similar_text subject
|
||||
if (!$email_processed && strlen(trim($subject)) > 10) {
|
||||
$contact_id = 0;
|
||||
$client_id = 0;
|
||||
|
||||
// First: check if sender is a registered contact
|
||||
$from_email_esc = mysqli_real_escape_string($mysqli, $from_email);
|
||||
$any_contact_sql = mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_email = '$from_email_esc' LIMIT 1");
|
||||
$contact_sql = mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_email = '$from_email_esc' AND contact_archived_at IS NULL LIMIT 1");
|
||||
$contact_row = mysqli_fetch_array($contact_sql);
|
||||
|
||||
if ($contact_row) {
|
||||
$contact_id = intval($contact_row['contact_id']);
|
||||
$client_id = intval($contact_row['contact_client_id']);
|
||||
} else {
|
||||
// Else: check if sender domain is registered
|
||||
$from_domain_esc = mysqli_real_escape_string($mysqli, $from_domain);
|
||||
$domain_sql = mysqli_query($mysqli, "SELECT * FROM domains WHERE domain_name = '$from_domain_esc' AND domain_archived_at IS NULL LIMIT 1");
|
||||
$domain_row = mysqli_fetch_assoc($domain_sql);
|
||||
|
||||
if ($domain_row && $from_domain == $domain_row['domain_name']) {
|
||||
$client_id = intval($domain_row['domain_client_id']);
|
||||
}
|
||||
}
|
||||
|
||||
// If we found either a contact or a domain, check recent tickets for a matching subject
|
||||
if ($client_id) {
|
||||
$recent_tickets_sql = mysqli_query($mysqli,
|
||||
"SELECT ticket_id, ticket_number, ticket_subject
|
||||
FROM tickets
|
||||
WHERE ticket_client_id = $client_id AND ticket_resolved_at IS NULL
|
||||
AND ticket_created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)"
|
||||
);
|
||||
|
||||
while ($rowt = mysqli_fetch_assoc($recent_tickets_sql)) {
|
||||
$ticket_number = intval($rowt['ticket_number']);
|
||||
$existing_subject = $rowt['ticket_subject'];
|
||||
|
||||
// Calculate similarity percentage
|
||||
similar_text(strtolower($subject), strtolower($existing_subject), $percent);
|
||||
|
||||
if ($percent >= 95) {
|
||||
// Treat as a reply/duplicate
|
||||
$email_processed = addReply($from_email, $date, $subject, $ticket_number, $message_body, $attachments);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. A known, registered contact?
|
||||
if (!$email_processed) {
|
||||
$from_email_esc = mysqli_real_escape_string($mysqli, $from_email);
|
||||
$any_contact_sql = mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_email = '$from_email_esc' AND contact_archived_at IS NULL LIMIT 1");
|
||||
$rowc = mysqli_fetch_array($any_contact_sql);
|
||||
|
||||
if ($rowc) {
|
||||
@@ -616,43 +697,41 @@ foreach ($messages as $message) {
|
||||
$contact_email = sanitizeInput($rowc['contact_email']);
|
||||
$client_id = intval($rowc['contact_client_id']);
|
||||
|
||||
if (addTicket($contact_id, $contact_name, $contact_email, $client_id, $date, $subject, $message_body, $attachments, $original_message_file)) {
|
||||
$email_processed = true;
|
||||
}
|
||||
} else {
|
||||
// Known domain?
|
||||
$from_domain_esc = mysqli_real_escape_string($mysqli, $from_domain);
|
||||
$domain_sql = mysqli_query($mysqli, "SELECT * FROM domains WHERE domain_name = '$from_domain_esc' LIMIT 1");
|
||||
$rowd = mysqli_fetch_assoc($domain_sql);
|
||||
|
||||
if ($rowd && $from_domain == $rowd['domain_name']) {
|
||||
$client_id = intval($rowd['domain_client_id']);
|
||||
|
||||
// Create a new contact
|
||||
$contact_name = $from_name;
|
||||
$contact_email = $from_email;
|
||||
mysqli_query($mysqli, "INSERT INTO contacts SET contact_name = '".mysqli_real_escape_string($mysqli, $contact_name)."', contact_email = '".mysqli_real_escape_string($mysqli, $contact_email)."', contact_notes = 'Added automatically via email parsing.', contact_client_id = $client_id");
|
||||
$contact_id = mysqli_insert_id($mysqli);
|
||||
|
||||
// Logging
|
||||
logAction("Contact", "Create", "Email parser: created contact " . mysqli_real_escape_string($mysqli, $contact_name) . "", $client_id, $contact_id);
|
||||
customAction('contact_create', $contact_id);
|
||||
|
||||
if (addTicket($contact_id, $contact_name, $contact_email, $client_id, $date, $subject, $message_body, $attachments, $original_message_file)) {
|
||||
$email_processed = true;
|
||||
}
|
||||
} elseif ($config_ticket_email_parse_unknown_senders) {
|
||||
// Unknown sender allowed?
|
||||
$bad_from_pattern = "/daemon|postmaster/i";
|
||||
if (!(preg_match($bad_from_pattern, $from_email))) {
|
||||
if (addTicket(0, $from_name, $from_email, 0, $date, $subject, $message_body, $attachments, $original_message_file)) {
|
||||
$email_processed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
$email_processed = addTicket($contact_id, $contact_name, $contact_email, $client_id, $date, $subject, $message_body, $attachments, $original_message_file);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. A known domain?
|
||||
if (!$email_processed) {
|
||||
$from_domain_esc = mysqli_real_escape_string($mysqli, $from_domain);
|
||||
$domain_sql = mysqli_query($mysqli, "SELECT * FROM domains WHERE domain_name = '$from_domain_esc' AND domain_archived_at IS NULL LIMIT 1");
|
||||
$rowd = mysqli_fetch_assoc($domain_sql);
|
||||
|
||||
if ($rowd && $from_domain == $rowd['domain_name']) {
|
||||
$client_id = intval($rowd['domain_client_id']);
|
||||
|
||||
// Create a new contact
|
||||
$contact_name = $from_name;
|
||||
$contact_email = $from_email;
|
||||
mysqli_query($mysqli, "INSERT INTO contacts SET contact_name = '".mysqli_real_escape_string($mysqli, $contact_name)."', contact_email = '".mysqli_real_escape_string($mysqli, $contact_email)."', contact_notes = 'Added automatically via email parsing.', contact_client_id = $client_id");
|
||||
$contact_id = mysqli_insert_id($mysqli);
|
||||
|
||||
logAction("Contact", "Create", "Email parser: created contact " . mysqli_real_escape_string($mysqli, $contact_name), $client_id, $contact_id);
|
||||
customAction('contact_create', $contact_id);
|
||||
|
||||
$email_processed = addTicket($contact_id, $contact_name, $contact_email, $client_id, $date, $subject, $message_body, $attachments, $original_message_file);
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Unknown sender allowed?
|
||||
if (!$email_processed && $config_ticket_email_parse_unknown_senders) {
|
||||
$bad_from_pattern = "/daemon|postmaster/i";
|
||||
if (!preg_match($bad_from_pattern, $from_email)) {
|
||||
$email_processed = addTicket(0, $from_name, $from_email, 0, $date, $subject, $message_body, $attachments, $original_message_file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Flag/move based on processing result
|
||||
if ($email_processed) {
|
||||
$processed_count++; // increment first so a move failure doesn't hide the success
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user