stage #2
37
.github/workflows/dbsql-lint.yml
vendored
37
.github/workflows/dbsql-lint.yml
vendored
@@ -1,37 +0,0 @@
|
||||
name: SQL Syntax Check for db.sql
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'db.sql'
|
||||
|
||||
jobs:
|
||||
syntax_check:
|
||||
name: Check db.sql SQL Syntax
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
services:
|
||||
mariadb:
|
||||
image: mariadb:latest
|
||||
ports:
|
||||
- "3306:3306"
|
||||
env:
|
||||
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
|
||||
MARIADB_USER: user
|
||||
MARIADB_PASSWORD: password
|
||||
MARIADB_DATABASE: itfsyntaxdb
|
||||
options: >-
|
||||
--health-cmd="healthcheck.sh --connect --innodb_initialized"
|
||||
--health-interval=10s
|
||||
--health-timeout=5s
|
||||
--health-retries=3
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Import & Lint db.sql
|
||||
run: mysql --host 127.0.0.1 -uuser -ppassword itfsyntaxdb < db.sql
|
||||
|
||||
- name: Show imported tables
|
||||
run: mysql --host 127.0.0.1 -uuser -ppassword itfsyntaxdb -e "show tables;"
|
||||
29
.github/workflows/first-interaction.yml
vendored
29
.github/workflows/first-interaction.yml
vendored
@@ -1,29 +0,0 @@
|
||||
name: Welcome New Contributor
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
pull_request_target:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
run:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/first-interaction@v1.2.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-message: |
|
||||
Hello & Welcome! :)
|
||||
|
||||
Thanks for taking the time to get in touch.
|
||||
|
||||
We ask that all bugs/feature/support requests are raised via the [forum](https://forum.itflow.org). We'll be in touch shortly to confirm.
|
||||
pr-message: |
|
||||
Hello & Welcome! :)
|
||||
|
||||
Thanks for taking the time to help improve ITFlow. We're excited to review your contributions - we'll review this PR as soon as we can!
|
||||
|
||||
Whilst you're waiting, please feel free to check out the [forum](https://forum.itflow.org).
|
||||
|
||||
Just so you know, all contributions to ITFlow are licensed under the GNU GPL. By contributing you grant us a perpetual & irrevocable license to include your work in ITFlow.
|
||||
15
.github/workflows/php-lint.yml
vendored
15
.github/workflows/php-lint.yml
vendored
@@ -1,15 +0,0 @@
|
||||
|
||||
name: PHPLint
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Check PHP syntax errors
|
||||
uses: overtrue/phplint@9.4.1
|
||||
96
CHANGELOG.md
96
CHANGELOG.md
@@ -2,6 +2,102 @@
|
||||
|
||||
This file documents all notable changes made to ITFlow.
|
||||
|
||||
## [25.11] Changelog
|
||||
|
||||
### Deprecation Notice:
|
||||
- **Outdated CRON Scripts**: The following scripts are removed.
|
||||
- `/scripts/cron_mail_queue.php`
|
||||
- `/scripts/cron_ticket_email_parser.php`
|
||||
- `/scripts/cron.php`
|
||||
- `/scripts/cron_domain_refresher.php`
|
||||
- `/scripts/cron_certificate_refresher.php`
|
||||
|
||||
**Action Required**: Transition to the new versions:
|
||||
- `/cron/mail_queue.php`
|
||||
- `/cron/ticket_email_parser.php`
|
||||
- `/cron/cron.php`
|
||||
- `/cron/domain_refresher.php`
|
||||
- `/cron/certificate_refresher.php`
|
||||
|
||||
- PHP Extensions php-imap and php-mime-mail-parser are no longer required.
|
||||
---
|
||||
|
||||
### Fixes
|
||||
- **Ticket Listing**: Resolved issue where the “Check All” checkbox was visible even when ticket status wasn’t set. Now hidden for closed tickets only.
|
||||
- **Timer Auto-Start**: Show H/M/S placeholders when timer auto-start is disabled.
|
||||
- **Ticket Guest URL**: Fixed email not including the ticket guest URL key.
|
||||
- **EML Generation**: Resolved issue with EML not being generated in the new ticket parser.
|
||||
- **New Ticket Mail Notification**: Included message when notifying the tech of a reply in the new ticket mail parser.
|
||||
- **Advanced Filter Collapse**: Added clause to prevent collapse of advanced filters when the “from” date is set to the default (1970-01-01).
|
||||
- **Recurring Invoice**: Fixed issue where email was marked as sent but not actually sent when forcing a recurring invoice to an invoice.
|
||||
- **CSRF Token**: Fixed issue with deleting recurring ticket from asset details page due to missing CSRF check token.
|
||||
- **Vendor Website Link**: Fixed missing `https://` prefix in the vendor website link on the vendor details modal.
|
||||
- **Agent Select Box**: Resolved issue where agents sometimes didn’t appear in the agent select boxes.
|
||||
- **TinyMCE**: Fixed TinyMCE editor issue on Bulk Create Ticket in Assets.
|
||||
- **Ticket Timer**: Fixed ticket timer initialization after reload and when the tab is put to sleep (background tab).
|
||||
- **Client Deletion**: Fixed issue with client deletion.
|
||||
- **Domain Records**: Added flag for missing SOA record when adding a domain (prevents subdomain creation).
|
||||
- **Domain Fetching**: Quits domain record fetching if no SOA record exists (prevents subdomains).
|
||||
- **Domain Expiry**: Only show time to expiry when there’s an expiry date set; otherwise, display a dash.
|
||||
- **Certificates**: Improved handling of empty date in the agent UI.
|
||||
- **Certificates API**: Fixed bug with missing JS to fetch certificate details.
|
||||
- **API Updates**:
|
||||
- Clients API: Added support for archiving/un-archiving clients, updating client data, and abbreviation support.
|
||||
- Contacts API: Added archiving/un-archiving and restriction to only allow one primary contact per client.
|
||||
- Mail Queue: Added recipient domain MX validation before sending emails.
|
||||
|
||||
---
|
||||
|
||||
### Added / Changed
|
||||
- **Backup / Restore**: Improved backup and restore by streaming data to disk (to prevent memory issues), setting unlimited timeouts, checking for bad backup contents, and using PHP for DB import instead of shell exec. Added `.htaccess` to prevent PHP execution in `/uploads/` directory.
|
||||
- **Ajax Modals**: Migrated all Add and Bulk modals to the new Ajax Modal for improved performance.
|
||||
- **Recurring Ticket Sorting**: Default sorting of recurring tickets by `RunDate` instead of subject.
|
||||
- **Recurring Ticket Enhancements**:
|
||||
- Added Billable column.
|
||||
- Added bulk actions for setting priority, agent, billable status, and next run dates.
|
||||
- Added filters for category, assigned agent, and billable status.
|
||||
- Added new frequency options: 3-day and biweekly.
|
||||
- **Asset Select**: Updated asset select dropdown to separate asset types using opt groups (planned for wider use).
|
||||
- **Expiring Domains & Certificates**: Added "30 Day" warning for expiring domains and certificates in the dashboard.
|
||||
- **Ticket Search**: Allowed search using both ticket prefix and number.
|
||||
- **Recurring Invoice**: Cancel recurring invoices when the associated client is archived.
|
||||
- **Credentials Import/Export**: Now includes TOTP secrets when importing/exporting credentials.
|
||||
- **Asset Notes Import**: Allowed importing of asset notes.
|
||||
- **Ticket View**: Added a "View HTML Code" button in all ticket views for TinyMCE.
|
||||
- **Date Range Picker**: Updated all date filters to use the improved DateRangePicker JS.
|
||||
- **Bulk Ticket Creation**: Added bulk ticket creation for clients.
|
||||
- **Sidebar Updates**: Updated all sidebars to use absolute paths for easier integration with custom code.
|
||||
- **Document Actions**: Added Archive and Delete buttons to the Document Details view with improved redirect behavior.
|
||||
- **Ticket Template Sorting**: Allowed sorting by task count in ticket templates.
|
||||
- **Contact Modal UI**: Updated contact details modal to display contact information at the top.
|
||||
- **API & Code Updates**:
|
||||
- Separated out post files for recurring tickets, invoices, expenses, and payments.
|
||||
- Removed unused budget code.
|
||||
- **Invoice Product Autocomplete**: Now allows searching for product codes as well as names.
|
||||
- **Client Duplicate Check**: Flags duplicate clients or leads when using the client add modal.
|
||||
- **Recurring Invoice Reference**: Added a column to invoices indicating if they were created from a recurring invoice.
|
||||
- **Global Search Enhancements**:
|
||||
- Allowed ticket details to be searchable in global search.
|
||||
- Allowed searching for quotes in global search.
|
||||
- **UI/UX Improvements**:
|
||||
- Spruced up the ticket details page UI.
|
||||
- Added contact email validation to flag duplicates or invalid addresses.
|
||||
- **API Debugging**: Log API endpoint/URL path for authentication failures to aid in debugging.
|
||||
- **Image Upload Optimization**: Removed image optimization from uploads (this will be handled by a cron job in the future).
|
||||
- **View Behavior Change**: Updated ticket/invoice/quote views to always be in the Client section, showing client-side navigation and top info bar.
|
||||
|
||||
---
|
||||
|
||||
### Library Updates:
|
||||
- **DataTable**: Bumped from 2.3.3 to 2.3.4.
|
||||
- **TinyMCE**: Bumped from 8.0.2 to 8.2.0.
|
||||
- **Stripe-PHP**: Bumped from 17.6.0 to 18.1.0.
|
||||
- **PHPMailer**: Bumped from 6.10.0 to 7.0.0.
|
||||
- **Chart.js**: Bumped from 4.5.0 to 4.5.1.
|
||||
|
||||
|
||||
|
||||
|
||||
## [25.10.1]
|
||||
- Deprecation Notice: `/scripts/cron_mail_queue.php` , `/scripts/cron_ticket_email_parser.php` , `/scripts/cron.php` `/scripts/cron_domain_refresher.php`, `/scripts/cron_certificate_refresher.php` are being phased out. Please transition to `/cron/mail_queue.php` , `/cron/ticket_email_parser.php`, `/cron/cron.php`, `/cron/domain_refresher.php`, `/cron/certificate_refresher.php` These older scripts will be removed in the November 25.11 release—update accordingly. 25.10.1 installs have the script already configured.
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ $num_rows = mysqli_num_rows($sql);
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-robot mr-2"></i>AI Models</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addAIModelModal"><i class="fas fa-plus mr-2"></i>Add Model</button>
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/ai/ai_model_add.php"><i class="fas fa-plus mr-2"></i>Add Model</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@@ -104,5 +104,4 @@ $num_rows = mysqli_num_rows($sql);
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "modals/ai/ai_model_add.php";
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
@@ -16,7 +16,7 @@ $num_rows = mysqli_num_rows($sql);
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-robot mr-2"></i>AI Providers</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addAIProviderModal"><i class="fas fa-plus mr-2"></i>Add Provider</button>
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/ai/ai_provider_add.php"><i class="fas fa-plus mr-2"></i>Add Provider</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@@ -105,5 +105,4 @@ $num_rows = mysqli_num_rows($sql);
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "modals/ai/ai_provider_add.php";
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
@@ -18,11 +18,11 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-key mr-2"></i>API Keys</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addApiKeyModal"><i class="fas fa-plus mr-2"></i>Create</button>
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/api/api_key_add.php"><i class="fas fa-plus mr-2"></i>New API Key</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -128,17 +128,11 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<input class="form-check-input bulk-select" type="checkbox" name="api_key_ids[]" value="<?php echo $api_key_id ?>">
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td class="text-bold"><?php echo $api_key_name; ?></td>
|
||||
|
||||
<td><?php echo $api_key_client; ?></td>
|
||||
|
||||
<td><?php echo $api_key_secret; ?></td>
|
||||
|
||||
<td><?php echo $api_key_created_at; ?></td>
|
||||
|
||||
<td><?php echo $api_key_expire; ?></td>
|
||||
|
||||
<td>
|
||||
<div class="dropdown dropleft text-center">
|
||||
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
|
||||
@@ -162,15 +156,12 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<?php require_once "../includes/filter_footer.php";
|
||||
?>
|
||||
</div>
|
||||
<?php require_once "../includes/filter_footer.php"; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../js/bulk_actions.js"></script>
|
||||
<script src="../js/bulk_actions.js"></script>
|
||||
|
||||
<?php
|
||||
require_once "modals/api/api_key_add.php";
|
||||
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
|
||||
@@ -97,34 +97,15 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collapse mt-3 <?php if (!empty($_GET['dtf']) || $_GET['canned_date'] !== "custom" ) { echo "show"; } ?>" id="advancedFilter">
|
||||
<div class="collapse mt-3 <?php if (isset($_GET['dtf']) && $_GET['dtf'] !== '1970-01-01') { echo "show"; } ?>" id="advancedFilter">
|
||||
<div class="row">
|
||||
<div class="col-md-2">
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>Canned Date</label>
|
||||
<select onchange="this.form.submit()" class="form-control select2" name="canned_date">
|
||||
<option <?php if ($_GET['canned_date'] == "custom") { echo "selected"; } ?> value="">Custom</option>
|
||||
<option <?php if ($_GET['canned_date'] == "today") { echo "selected"; } ?> value="today">Today</option>
|
||||
<option <?php if ($_GET['canned_date'] == "yesterday") { echo "selected"; } ?> value="yesterday">Yesterday</option>
|
||||
<option <?php if ($_GET['canned_date'] == "thisweek") { echo "selected"; } ?> value="thisweek">This Week</option>
|
||||
<option <?php if ($_GET['canned_date'] == "lastweek") { echo "selected"; } ?> value="lastweek">Last Week</option>
|
||||
<option <?php if ($_GET['canned_date'] == "thismonth") { echo "selected"; } ?> value="thismonth">This Month</option>
|
||||
<option <?php if ($_GET['canned_date'] == "lastmonth") { echo "selected"; } ?> value="lastmonth">Last Month</option>
|
||||
<option <?php if ($_GET['canned_date'] == "thisyear") { echo "selected"; } ?> value="thisyear">This Year</option>
|
||||
<option <?php if ($_GET['canned_date'] == "lastyear") { echo "selected"; } ?> value="lastyear">Last Year</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>Date From</label>
|
||||
<input onchange="this.form.submit()" type="date" class="form-control" name="dtf" max="2999-12-31" value="<?php echo nullable_htmlentities($dtf); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>Date To</label>
|
||||
<input onchange="this.form.submit()" type="date" class="form-control" name="dtt" max="2999-12-31" value="<?php echo nullable_htmlentities($dtt); ?>">
|
||||
<label>Date range</label>
|
||||
<input type="text" id="dateFilter" class="form-control" autocomplete="off">
|
||||
<input type="hidden" name="canned_date" id="canned_date" value="<?php echo nullable_htmlentities($_GET['canned_date']) ?? ''; ?>">
|
||||
<input type="hidden" name="dtf" id="dtf" value="<?php echo nullable_htmlentities($dtf ?? ''); ?>">
|
||||
<input type="hidden" name="dtt" id="dtt" value="<?php echo nullable_htmlentities($dtt ?? ''); ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -159,34 +159,15 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collapse mt-3 <?php if (!empty($_GET['dtf']) || $_GET['canned_date'] !== "custom" ) { echo "show"; } ?>" id="advancedFilter">
|
||||
<div class="collapse mt-3 <?php if (isset($_GET['dtf']) && $_GET['dtf'] !== '1970-01-01') { echo "show"; } ?>" id="advancedFilter">
|
||||
<div class="row">
|
||||
<div class="col-md-2">
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>Canned Date</label>
|
||||
<select onchange="this.form.submit()" class="form-control select2" name="canned_date">
|
||||
<option <?php if ($_GET['canned_date'] == "custom") { echo "selected"; } ?> value="">Custom</option>
|
||||
<option <?php if ($_GET['canned_date'] == "today") { echo "selected"; } ?> value="today">Today</option>
|
||||
<option <?php if ($_GET['canned_date'] == "yesterday") { echo "selected"; } ?> value="yesterday">Yesterday</option>
|
||||
<option <?php if ($_GET['canned_date'] == "thisweek") { echo "selected"; } ?> value="thisweek">This Week</option>
|
||||
<option <?php if ($_GET['canned_date'] == "lastweek") { echo "selected"; } ?> value="lastweek">Last Week</option>
|
||||
<option <?php if ($_GET['canned_date'] == "thismonth") { echo "selected"; } ?> value="thismonth">This Month</option>
|
||||
<option <?php if ($_GET['canned_date'] == "lastmonth") { echo "selected"; } ?> value="lastmonth">Last Month</option>
|
||||
<option <?php if ($_GET['canned_date'] == "thisyear") { echo "selected"; } ?> value="thisyear">This Year</option>
|
||||
<option <?php if ($_GET['canned_date'] == "lastyear") { echo "selected"; } ?> value="lastyear">Last Year</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>Date From</label>
|
||||
<input onchange="this.form.submit()" type="date" class="form-control" name="dtf" max="2999-12-31" value="<?php echo nullable_htmlentities($dtf); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>Date To</label>
|
||||
<input onchange="this.form.submit()" type="date" class="form-control" name="dtt" max="2999-12-31" value="<?php echo nullable_htmlentities($dtt); ?>">
|
||||
<label>Date range</label>
|
||||
<input type="text" id="dateFilter" class="form-control" autocomplete="off">
|
||||
<input type="hidden" name="canned_date" id="canned_date" value="<?php echo nullable_htmlentities($_GET['canned_date']) ?? ''; ?>">
|
||||
<input type="hidden" name="dtf" id="dtf" value="<?php echo nullable_htmlentities($dtf ?? ''); ?>">
|
||||
<input type="hidden" name="dtt" id="dtt" value="<?php echo nullable_htmlentities($dtt ?? ''); ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
125
admin/contract_templates.php
Normal file
125
admin/contract_templates.php
Normal file
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
// Default Column Sort by Filter
|
||||
$sort = "contract_template_name";
|
||||
$order = "ASC";
|
||||
|
||||
require_once "includes/inc_all_admin.php";
|
||||
|
||||
// Search query
|
||||
$sql = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT SQL_CALC_FOUND_ROWS * FROM contract_templates
|
||||
WHERE contract_template_name LIKE '%$q%' OR contract_template_type LIKE '%$q%' OR contract_template_name LIKE '%$q%'
|
||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
||||
);
|
||||
|
||||
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fa fa-fw fa-file-contract mr-2"></i>Contract Templates</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/contract_template/contract_template_add.php" data-modal-size="lg">
|
||||
<i class="fas fa-plus mr-2"></i>New Template
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<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 templates">
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-secondary"><i class="fa fa-search"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<hr>
|
||||
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-striped table-borderless table-hover">
|
||||
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
|
||||
<tr>
|
||||
<th>Template Name</th>
|
||||
<th>Type</th>
|
||||
<th>Update Frequency</th>
|
||||
<th>SLA (L/M/H Response)</th>
|
||||
<th>SLA (L/M/H Resolution)</th>
|
||||
<th>Hourly Rate</th>
|
||||
<th>After Hours Rate</th>
|
||||
<th>Support Hours</th>
|
||||
<th>Net Terms</th>
|
||||
<th>Created</th>
|
||||
<th>Updated</th>
|
||||
<th class="text-center">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
while ($row = mysqli_fetch_array($sql)) {
|
||||
$id = intval($row['contract_template_id']);
|
||||
$name = nullable_htmlentities($row['contract_template_name']);
|
||||
$type = nullable_htmlentities($row['contract_template_type']);
|
||||
$freq = nullable_htmlentities($row['contract_template_update_frequency']);
|
||||
$sla_low_resp = nullable_htmlentities($row['sla_low_response_time']);
|
||||
$sla_med_resp = nullable_htmlentities($row['sla_medium_response_time']);
|
||||
$sla_high_resp = nullable_htmlentities($row['sla_high_response_time']);
|
||||
$sla_low_res = nullable_htmlentities($row['sla_low_resolution_time']);
|
||||
$sla_med_res = nullable_htmlentities($row['sla_medium_resolution_time']);
|
||||
$sla_high_res = nullable_htmlentities($row['sla_high_resolution_time']);
|
||||
$hourly_rate = nullable_htmlentities($row['contract_template_hourly_rate']);
|
||||
$after_hours = nullable_htmlentities($row['contract_template_after_hours_hourly_rate']);
|
||||
$support_hours = nullable_htmlentities($row['contract_template_support_hours']);
|
||||
$net_terms = nullable_htmlentities($row['contract_template_net_terms']);
|
||||
$created = nullable_htmlentities($row['contract_template_created_at']);
|
||||
$updated = nullable_htmlentities($row['contract_template_updated_at']);
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<a class="text-bold" href="contract_template_details.php?contract_template_id=<?php echo $id; ?>">
|
||||
<i class="fas fa-fw fa-file-alt text-dark"></i> <?php echo $name; ?>
|
||||
</a>
|
||||
<div class="mt-1 text-secondary"><?php echo nullable_htmlentities($row['contract_template_description']); ?></div>
|
||||
</td>
|
||||
<td><?php echo $type; ?></td>
|
||||
<td><?php echo $freq; ?></td>
|
||||
<td><?php echo "$sla_low_resp / $sla_med_resp / $sla_high_resp"; ?></td>
|
||||
<td><?php echo "$sla_low_res / $sla_med_res / $sla_high_res"; ?></td>
|
||||
<td><?php echo $hourly_rate; ?></td>
|
||||
<td><?php echo $after_hours; ?></td>
|
||||
<td><?php echo $support_hours; ?></td>
|
||||
<td><?php echo $net_terms; ?></td>
|
||||
<td><?php echo $created; ?></td>
|
||||
<td><?php echo $updated; ?></td>
|
||||
<td>
|
||||
<div class="dropdown dropleft text-center">
|
||||
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
|
||||
<i class="fas fa-ellipsis-h"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-size="xl"
|
||||
data-modal-url="modals/contract_template/contract_template_edit.php?id=<?= $id ?>">
|
||||
<i class="fas fa-fw fa-edit mr-2"></i>Edit
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-danger text-bold" href="post.php?delete_contract_template=<?php echo $id; ?>">
|
||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
</div>
|
||||
<?php require_once "../includes/filter_footer.php"; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once "../includes/footer.php"; ?>
|
||||
@@ -21,7 +21,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-external-link-alt mr-2"></i>Custom Links</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addLinkModal"><i class="fas fa-plus mr-2"></i>New Link</button>
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/custom_link/custom_link_add.php"><i class="fas fa-plus mr-2"></i>New Link</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -145,5 +145,4 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "modals/custom_link/custom_link_add.php";
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
@@ -4033,10 +4033,92 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
|
||||
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.3.6'");
|
||||
}
|
||||
|
||||
// if (CURRENT_DATABASE_VERSION == '2.3.5') {
|
||||
// // Insert queries here required to update to DB version 2.3.5
|
||||
if (CURRENT_DATABASE_VERSION == '2.3.6') {
|
||||
// Create New Contract Templates Table
|
||||
mysqli_query($mysqli, "CREATE TABLE `contract_templates` (
|
||||
`contract_template_id` INT(11) AUTO_INCREMENT PRIMARY KEY,
|
||||
`contract_template_name` VARCHAR(255) NOT NULL,
|
||||
`contract_template_description` TEXT NULL DEFAULT NULL,
|
||||
`contract_template_type` VARCHAR(50) NULL DEFAULT NULL,
|
||||
|
||||
`contract_template_sla_low_response_time` INT(11) NULL DEFAULT NULL,
|
||||
`contract_template_sla_low_resolution_time` INT(11) NULL DEFAULT NULL,
|
||||
`contract_template_sla_medium_response_time` INT(11) NULL DEFAULT NULL,
|
||||
`contract_template_sla_medium_resolution_time` INT(11) NULL DEFAULT NULL,
|
||||
`contract_template_sla_high_response_time` INT(11) NULL DEFAULT NULL,
|
||||
`contract_template_sla_high_resolution_time` INT(11) NULL DEFAULT NULL,
|
||||
|
||||
`contract_template_rate_standard` DECIMAL(10,2) NULL DEFAULT NULL,
|
||||
`contract_template_rate_after_hours` DECIMAL(10,2) NULL DEFAULT NULL,
|
||||
|
||||
`contract_template_net_terms` VARCHAR(50) NULL DEFAULT NULL,
|
||||
`contract_template_support_hours` VARCHAR(100) NULL DEFAULT NULL,
|
||||
`contract_template_renewal_frequency` VARCHAR(50) NULL DEFAULT NULL,
|
||||
|
||||
`contract_template_details` TEXT NULL DEFAULT NULL,
|
||||
|
||||
`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
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||
|
||||
|
||||
// Create New Contracts Table
|
||||
mysqli_query($mysqli, "CREATE TABLE `contracts` (
|
||||
`contract_id` INT(11) AUTO_INCREMENT PRIMARY KEY,
|
||||
`contract_name` VARCHAR(255) NOT NULL,
|
||||
`contract_status` VARCHAR(50) NOT NULL,
|
||||
`contract_type` VARCHAR(50) NOT NULL,
|
||||
|
||||
`contract_sla_low_response_time` INT(11) NULL DEFAULT NULL,
|
||||
`contract_sla_low_resolution_time` INT(11) NULL DEFAULT NULL,
|
||||
`contract_sla_medium_response_time` INT(11) NULL DEFAULT NULL,
|
||||
`contract_sla_medium_resolution_time` INT(11) NULL DEFAULT NULL,
|
||||
`contract_sla_high_response_time` INT(11) NULL DEFAULT NULL,
|
||||
`contract_sla_high_resolution_time` INT(11) NULL DEFAULT NULL,
|
||||
|
||||
`contract_details` TEXT NULL DEFAULT NULL,
|
||||
|
||||
`contract_client_id` INT(11) NULL DEFAULT NULL,
|
||||
`contract_client_name` VARCHAR(255) NULL DEFAULT NULL,
|
||||
`contract_client_address` TEXT NULL DEFAULT NULL,
|
||||
`contract_client_email` VARCHAR(255) NULL DEFAULT NULL,
|
||||
`contract_client_phone` VARCHAR(100) NULL DEFAULT NULL,
|
||||
|
||||
`contract_contact_name` VARCHAR(255) NULL DEFAULT NULL,
|
||||
`contract_contact_signature` TEXT NULL DEFAULT NULL,
|
||||
`contract_contact_signature_date` DATETIME NULL DEFAULT NULL,
|
||||
|
||||
`contract_agent_name` VARCHAR(255) NULL DEFAULT NULL,
|
||||
`contract_agent_signature` TEXT NULL DEFAULT NULL,
|
||||
`contract_agent_signature_date` DATETIME NULL DEFAULT NULL,
|
||||
|
||||
`contract_rate_standard` DECIMAL(10,2) NULL DEFAULT NULL,
|
||||
`contract_rate_after_hours` DECIMAL(10,2) NULL DEFAULT NULL,
|
||||
|
||||
`contract_net_terms` VARCHAR(50) NULL DEFAULT NULL,
|
||||
`contract_support_hours` VARCHAR(100) NULL DEFAULT NULL,
|
||||
|
||||
`contract_start_date` DATE NULL DEFAULT NULL,
|
||||
`contract_end_date` DATE NULL DEFAULT NULL,
|
||||
`contract_renewal_frequency` VARCHAR(50) NULL DEFAULT NULL,
|
||||
|
||||
`contract_created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
`contract_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
|
||||
`contract_archived_at` DATETIME NULL DEFAULT NULL,
|
||||
|
||||
FOREIGN KEY (`contract_client_id`) REFERENCES `clients`(`client_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||
|
||||
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
|
||||
// // Then, update the database to the next sequential version
|
||||
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.3.6'");
|
||||
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.3.8'");
|
||||
// }
|
||||
|
||||
} else {
|
||||
|
||||
@@ -46,8 +46,6 @@ $systemInfo[] = [
|
||||
// Section: PHP Extensions
|
||||
$phpExtensions = [];
|
||||
$extensions = [
|
||||
'php-mailparse' => 'mailparse',
|
||||
'php-imap' => 'imap',
|
||||
'php-mysqli' => 'mysqli',
|
||||
'php-intl' => 'intl',
|
||||
'php-curl' => 'curl',
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fa fa-fw fa-file mr-2"></i>Document Templates</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addDocumentTemplateModal">
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/document_template/document_template_add.php" data-modal-size="xl">
|
||||
<i class="fas fa-plus mr-2"></i>New Template
|
||||
</button>
|
||||
</div>
|
||||
@@ -121,38 +121,4 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once "modals/document_template/document_template_add.php"; ?>
|
||||
<?php require_once "../includes/footer.php"; ?>
|
||||
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
|
||||
$('#generateAIContent').on('click', function(){
|
||||
var prompt = $('#aiPrompt').val().trim();
|
||||
if(prompt === '') {
|
||||
alert('Please enter a prompt.');
|
||||
return;
|
||||
}
|
||||
|
||||
$('#generateAIContent').prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> Generating...');
|
||||
|
||||
$.ajax({
|
||||
url: 'post.php?ai_create_document_template', // The PHP script that calls the OpenAI API
|
||||
method: 'POST',
|
||||
data: { prompt: prompt },
|
||||
dataType: 'html',
|
||||
success: function(response) {
|
||||
// Assuming you have exactly one TinyMCE instance on the page
|
||||
// and it's targeting the .tinymce textarea:
|
||||
tinymce.activeEditor.setContent(response);
|
||||
},
|
||||
error: function() {
|
||||
alert('Error generating content. Please try again.');
|
||||
},
|
||||
complete: function() {
|
||||
$('#generateAIContent').prop('disabled', false).html('<i class="fa fa-fw fa-magic mr-1"></i>Generate with AI');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php require_once "../includes/footer.php";
|
||||
|
||||
@@ -15,7 +15,13 @@ if (isset($_GET['document_template_id'])) {
|
||||
$document_template_id = intval($_GET['document_template_id']);
|
||||
}
|
||||
|
||||
$sql_document = mysqli_query($mysqli, "SELECT * FROM document_templates WHERE document_template_id = $document_template_id");
|
||||
$sql_document = mysqli_query($mysqli, "SELECT * FROM document_templates WHERE document_template_id = $document_template_id LIMIT 1");
|
||||
|
||||
if (mysqli_num_rows($sql_document) == 0) {
|
||||
echo "<center><h1 class='text-secondary mt-5'>Nothing to see here</h1><a class='btn btn-lg btn-secondary mt-3' href='javascript:history.back()'><i class='fa fa-fw fa-arrow-left'></i> Go Back</a></center>";
|
||||
require_once "../includes/footer.php";
|
||||
exit();
|
||||
}
|
||||
|
||||
$row = mysqli_fetch_array($sql_document);
|
||||
|
||||
|
||||
@@ -14,21 +14,27 @@
|
||||
<!-- Sidebar Menu -->
|
||||
<nav>
|
||||
<ul class="nav nav-pills nav-sidebar flex-column mt-2" data-widget="treeview" data-accordion="false">
|
||||
<!-- ACCESS Section -->
|
||||
<li class="nav-header">ACCESS</li>
|
||||
<li class="nav-item">
|
||||
<a href="users.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "users.php") {echo "active";} ?>">
|
||||
<a href="/admin/users.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "users.php") {echo "active";} ?>">
|
||||
<i class="nav-icon fas fa-users"></i>
|
||||
<p>Users</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="roles.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "roles.php") {echo "active";} ?>">
|
||||
<a href="/admin/roles.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "roles.php") {echo "active";} ?>">
|
||||
<i class="nav-icon fas fa-user-shield"></i>
|
||||
<p>Roles</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="api_keys.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "api_keys.php") {echo "active";} ?>">
|
||||
<a href="/admin/modules.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "modules.php") {echo "active";} ?>">
|
||||
<i class="nav-icon fas fa-puzzle-piece"></i>
|
||||
<p>Modules</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="/admin/api_keys.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "api_keys.php") {echo "active";} ?>">
|
||||
<i class="nav-icon fas fa-key"></i>
|
||||
<p>API Keys</p>
|
||||
</a>
|
||||
@@ -36,51 +42,51 @@
|
||||
<li class="nav-header">TAGS & CATEGORIES</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="tag.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'tag.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/tag.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'tag.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-tags"></i>
|
||||
<p>Tags</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="category.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'category.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/category.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'category.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-list-ul"></i>
|
||||
<p>Categories</p>
|
||||
</a>
|
||||
</li>
|
||||
<?php if ($config_module_enable_accounting) { ?>
|
||||
<li class="nav-item">
|
||||
<a href="tax.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'tax.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/tax.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'tax.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-balance-scale"></i>
|
||||
<p>Taxes</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="payment_method.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'payment_method.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/payment_method.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'payment_method.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-hand-holding-usd"></i>
|
||||
<p>Payment Methods</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="payment_provider.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'payment_provider.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/payment_provider.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'payment_provider.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon far fa-credit-card"></i>
|
||||
<p>Payment Providers</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="saved_payment_method.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'saved_payment_method.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/saved_payment_method.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'saved_payment_method.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon far fa-credit-card"></i>
|
||||
<p>Saved Payments</p>
|
||||
</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<li class="nav-item">
|
||||
<a href="ai_provider.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'ai_provider.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/ai_provider.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'ai_provider.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-robot"></i>
|
||||
<p>AI Providers</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="ai_model.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'ai_model.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/ai_model.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'ai_model.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-robot"></i>
|
||||
<p>AI Models</p>
|
||||
</a>
|
||||
@@ -88,14 +94,14 @@
|
||||
|
||||
<?php if ($config_module_enable_ticketing) { ?>
|
||||
<li class="nav-item">
|
||||
<a href="ticket_status.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'ticket_status.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/ticket_status.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'ticket_status.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-info-circle"></i>
|
||||
<p>Ticket Statuses</p>
|
||||
</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<li class="nav-item">
|
||||
<a href="custom_link.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'custom_link.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/custom_link.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'custom_link.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-external-link-alt"></i>
|
||||
<p>Custom Links</p>
|
||||
</a>
|
||||
@@ -105,31 +111,37 @@
|
||||
<li class="nav-header">TEMPLATES</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="project_template.php" class="nav-link <?php echo (in_array(basename($_SERVER['PHP_SELF']), ['project_template.php', 'project_template_details.php']) ? 'active' : ''); ?>">
|
||||
<a href="/admin/contract_templates.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'contract_templates.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-file-contract"></i>
|
||||
<p>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>
|
||||
<p>Project Templates</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="ticket_template.php" class="nav-link <?php echo (in_array(basename($_SERVER['PHP_SELF']), ['ticket_template.php', 'ticket_template_details.php']) ? 'active' : ''); ?>">
|
||||
<a href="/admin/ticket_template.php" class="nav-link <?php echo (in_array(basename($_SERVER['PHP_SELF']), ['ticket_template.php', 'ticket_template_details.php']) ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-life-ring"></i>
|
||||
<p>Ticket Templates</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="vendor_template.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'vendor_template.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/vendor_template.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'vendor_template.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-building"></i>
|
||||
<p>Vendor Templates</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="software_template.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'software_template.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/software_template.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'software_template.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-rocket"></i>
|
||||
<p>License Templates</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="document_template.php" class="nav-link <?php echo (in_array(basename($_SERVER['PHP_SELF']), ['document_template.php', 'document_template_details.php']) ? 'active' : ''); ?>">
|
||||
<a href="/admin/document_template.php" class="nav-link <?php echo (in_array(basename($_SERVER['PHP_SELF']), ['document_template.php', 'document_template_details.php']) ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-file"></i>
|
||||
<p>Document Templates</p>
|
||||
</a>
|
||||
@@ -139,37 +151,37 @@
|
||||
<li class="nav-header">MAINTENANCE</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="mail_queue.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'mail_queue.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/mail_queue.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'mail_queue.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-mail-bulk"></i>
|
||||
<p>Mail Queue</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="audit_log.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'audit_log.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/audit_log.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'audit_log.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-history"></i>
|
||||
<p>Audit Logs</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="app_log.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'app_log.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/app_log.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'app_log.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-history"></i>
|
||||
<p>App Logs</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="backup.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'backup.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/backup.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'backup.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-cloud-upload-alt"></i>
|
||||
<p>Backup</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="debug.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'debug.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/debug.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'debug.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-bug"></i>
|
||||
<p>Debug</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="update.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'update.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/update.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'update.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-download"></i>
|
||||
<p>Update</p>
|
||||
</a>
|
||||
@@ -185,56 +197,56 @@
|
||||
</a>
|
||||
<ul class="nav nav-treeview">
|
||||
<li class="nav-item">
|
||||
<a href="settings_company.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_company.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/settings_company.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_company.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fa fa-briefcase"></i>
|
||||
<p>Company Details</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="settings_localization.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_localization.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/settings_localization.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_localization.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fa fa-globe"></i>
|
||||
<p>Localization</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="settings_theme.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_theme.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/settings_theme.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_theme.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fa fa-paint-brush"></i>
|
||||
<p>Theme</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="settings_security.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_security.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/settings_security.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_security.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-shield-alt"></i>
|
||||
<p>Security</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="settings_mail.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_mail.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/settings_mail.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_mail.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon far fa-envelope"></i>
|
||||
<p>Mail</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="settings_notification.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_notification.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/settings_notification.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_notification.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon far fa-bell"></i>
|
||||
<p>Notifications</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="settings_default.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_default.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/settings_default.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_default.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-cogs"></i>
|
||||
<p>Defaults</p>
|
||||
</a>
|
||||
</li>
|
||||
<?php if ($config_module_enable_accounting) { ?>
|
||||
<li class="nav-item">
|
||||
<a href="settings_invoice.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_invoice.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/settings_invoice.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_invoice.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-file-invoice"></i>
|
||||
<p>Invoice</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="settings_quote.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_quote.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/settings_quote.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_quote.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-comment-dollar"></i>
|
||||
<p>Quote</p>
|
||||
</a>
|
||||
@@ -242,13 +254,13 @@
|
||||
<?php } ?>
|
||||
<?php if ($config_module_enable_ticketing) { ?>
|
||||
<li class="nav-item">
|
||||
<a href="settings_project.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_project.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/settings_project.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_project.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-project-diagram"></i>
|
||||
<p>Project</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="settings_ticket.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_ticket.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/settings_ticket.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_ticket.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-life-ring"></i>
|
||||
<p>Ticket</p>
|
||||
</a>
|
||||
@@ -257,20 +269,20 @@
|
||||
<!-- Currently the only integration is the client portal SSO -->
|
||||
<?php if ($config_client_portal_enable) { ?>
|
||||
<li class="nav-item">
|
||||
<a href="identity_provider.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'identity_provider.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/identity_provider.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'identity_provider.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-fingerprint"></i>
|
||||
<p>Identity Provider</p>
|
||||
</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<li class="nav-item">
|
||||
<a href="settings_telemetry.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_telemetry.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/settings_telemetry.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_telemetry.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-satellite-dish"></i>
|
||||
<p>Telemetry</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="settings_module.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_module.php' ? 'active' : ''); ?>">
|
||||
<a href="/admin/settings_module.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_module.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-cube"></i>
|
||||
<p>Modules</p>
|
||||
</a>
|
||||
|
||||
@@ -53,34 +53,15 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collapse mt-3 <?php if (!empty($_GET['dtf']) || $_GET['canned_date'] !== "custom" ) { echo "show"; } ?>" id="advancedFilter">
|
||||
<div class="collapse mt-3 <?php if (isset($_GET['dtf']) && $_GET['dtf'] !== '1970-01-01') { echo "show"; } ?>" id="advancedFilter">
|
||||
<div class="row">
|
||||
<div class="col-md-2">
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>Canned Date</label>
|
||||
<select onchange="this.form.submit()" class="form-control select2" name="canned_date">
|
||||
<option <?php if ($_GET['canned_date'] == "custom") { echo "selected"; } ?> value="">Custom</option>
|
||||
<option <?php if ($_GET['canned_date'] == "today") { echo "selected"; } ?> value="today">Today</option>
|
||||
<option <?php if ($_GET['canned_date'] == "yesterday") { echo "selected"; } ?> value="yesterday">Yesterday</option>
|
||||
<option <?php if ($_GET['canned_date'] == "thisweek") { echo "selected"; } ?> value="thisweek">This Week</option>
|
||||
<option <?php if ($_GET['canned_date'] == "lastweek") { echo "selected"; } ?> value="lastweek">Last Week</option>
|
||||
<option <?php if ($_GET['canned_date'] == "thismonth") { echo "selected"; } ?> value="thismonth">This Month</option>
|
||||
<option <?php if ($_GET['canned_date'] == "lastmonth") { echo "selected"; } ?> value="lastmonth">Last Month</option>
|
||||
<option <?php if ($_GET['canned_date'] == "thisyear") { echo "selected"; } ?> value="thisyear">This Year</option>
|
||||
<option <?php if ($_GET['canned_date'] == "lastyear") { echo "selected"; } ?> value="lastyear">Last Year</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>Date From</label>
|
||||
<input onchange="this.form.submit()" type="date" class="form-control" name="dtf" max="2999-12-31" value="<?php echo nullable_htmlentities($dtf); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>Date To</label>
|
||||
<input onchange="this.form.submit()" type="date" class="form-control" name="dtt" max="2999-12-31" value="<?php echo nullable_htmlentities($dtt); ?>">
|
||||
<label>Date range</label>
|
||||
<input type="text" id="dateFilter" class="form-control" autocomplete="off">
|
||||
<input type="hidden" name="canned_date" id="canned_date" value="<?php echo nullable_htmlentities($_GET['canned_date']) ?? ''; ?>">
|
||||
<input type="hidden" name="dtf" id="dtf" value="<?php echo nullable_htmlentities($dtf ?? ''); ?>">
|
||||
<input type="hidden" name="dtt" id="dtt" value="<?php echo nullable_htmlentities($dtt ?? ''); ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
<div class="form-group">
|
||||
<div class="modal" id="addAIModelModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<?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-robot mr-2"></i>Add AI Model</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
@@ -67,7 +71,7 @@
|
||||
<button type="submit" name="add_ai_model" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
<div class="form-group">
|
||||
<div class="modal" id="addAIProviderModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<?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-robot mr-2"></i>New AI Provider</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
@@ -48,7 +52,7 @@
|
||||
<button type="submit" name="add_ai_provider" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$key = randomString(156);
|
||||
$decryptPW = randomString(160);
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div class="modal" id="addApiKeyModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-key mr-2"></i>New Key</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<div class="modal-body">
|
||||
|
||||
<ul class="nav nav-pills nav-justified mb-3">
|
||||
@@ -115,7 +118,7 @@ $decryptPW = randomString(160);
|
||||
<button type="submit" name="add_api_key" 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="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
139
admin/modals/contract_template/contract_template_add.php
Normal file
139
admin/modals/contract_template/contract_template_add.php
Normal file
@@ -0,0 +1,139 @@
|
||||
<?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'];
|
||||
?>
|
||||
|
||||
<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">
|
||||
<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">
|
||||
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
<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>
|
||||
</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>
|
||||
<input type="number" class="form-control" name="sla_low_response_time" placeholder="e.g., 24">
|
||||
</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>
|
||||
</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>
|
||||
<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>
|
||||
</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>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Rates & Support Tab -->
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
<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>
|
||||
</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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</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>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
?>
|
||||
@@ -1,13 +1,18 @@
|
||||
<div class="modal" id="addLinkModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-external-link-alt mr-2"></i>New Custom Link</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
@@ -77,7 +82,7 @@
|
||||
<button type="submit" name="add_custom_link" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
<div class="modal" id="addDocumentTemplateModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-xl">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<?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-file-alt mr-2"></i>Creating Document 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>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
@@ -43,7 +48,40 @@
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
|
||||
$('#generateAIContent').on('click', function(){
|
||||
var prompt = $('#aiPrompt').val().trim();
|
||||
if(prompt === '') {
|
||||
alert('Please enter a prompt.');
|
||||
return;
|
||||
}
|
||||
|
||||
$('#generateAIContent').prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> Generating...');
|
||||
|
||||
$.ajax({
|
||||
url: '/agent/ajax.php?ai_create_document_template', // The PHP script that calls the OpenAI API
|
||||
method: 'POST',
|
||||
data: { prompt: prompt },
|
||||
dataType: 'html',
|
||||
success: function(response) {
|
||||
// Assuming you have exactly one TinyMCE instance on the page
|
||||
// and it's targeting the .tinymce textarea:
|
||||
tinymce.activeEditor.setContent(response);
|
||||
},
|
||||
error: function() {
|
||||
alert('Error generating content. Please try again.');
|
||||
},
|
||||
complete: function() {
|
||||
$('#generateAIContent').prop('disabled', false).html('<i class="fa fa-fw fa-magic mr-1"></i>Generate with AI');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
<div class="modal" id="addPaymentMethodModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<?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-credit-card mr-2"></i>Creating: <strong>Payment Method</strong></h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
@@ -31,7 +36,7 @@
|
||||
<button type="submit" name="add_payment_method" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
<div class="form-group">
|
||||
<div class="modal" id="addPaymentProviderModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<?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-credit-card mr-2"></i>Add Payment Provider</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
@@ -97,7 +100,7 @@
|
||||
<button type="submit" name="add_payment_provider" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Add</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
<div class="modal" id="addProjectTemplateModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-project-diagram mr-2"></i>Creating Project 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>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
@@ -35,7 +39,7 @@
|
||||
<button type="submit" name="add_project_template" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,13 +1,25 @@
|
||||
<div class="modal" id="editProjectTemplateModal<?php echo $project_template_id; ?>" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$project_template_id = intval($_GET['project_template_id']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM project_templates WHERE project_template_id = $project_template_id LIMIT 1");
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$project_template_name = nullable_htmlentities($row['project_template_name']);
|
||||
$project_template_description = nullable_htmlentities($row['project_template_description']);
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-project-diagram mr-2"></i>Editing Project Template: <strong><?php echo $project_template_name; ?></strong></h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="project_template_id" value="<?php echo $project_template_id; ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
@@ -34,11 +46,11 @@
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="edit_project_template" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</button>
|
||||
<button type="submit" name="edit_project_template" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
<div class="modal" id="addProjectTemplateTicketTemplateModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$project_template_id = intval($_GET['project_template_id']);
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-life-ring mr-2"></i>Adding 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>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="project_template_id" value="<?php echo $project_template_id; ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
@@ -58,7 +65,7 @@
|
||||
<button type="submit" name="add_ticket_template_to_project_template" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Add</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
<div class="modal" id="addRoleModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-user-shield mr-2"></i>Add new role</h5>
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-user-shield mr-2"></i>New Role</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
|
||||
</div>
|
||||
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<div class="modal-body">
|
||||
<div class="tab-content">
|
||||
@@ -52,7 +56,7 @@
|
||||
<button type="submit" name="add_role" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
<div class="modal" id="addSoftwareTemplateModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<?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-cube mr-2"></i>New License 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>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
@@ -77,7 +82,7 @@
|
||||
<button type="submit" name="add_software_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>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -17,6 +17,7 @@ if (isset($_GET['type'])) {
|
||||
$type_display = "Credential";
|
||||
}
|
||||
}
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
<div class="modal" id="addTaxModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-balance-scale mr-2"></i>New Tax</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
@@ -21,10 +26,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_tax" class="btn btn-primary text-bold"><i class="fa fa-check mr- 2"></i>Create</button>
|
||||
<button type="submit" name="add_tax" 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="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
<div class="modal" id="addTicketStatusModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<?php
|
||||
require_once '../../../includes/modal_header.php';
|
||||
ob_start();
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-info-circle mr-2"></i>New Ticket Status</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Name <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
@@ -36,7 +37,7 @@
|
||||
<button type="submit" name="add_ticket_status" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
<div class="modal" id="addUserModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-user-plus mr-2"></i>New User</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
|
||||
</div>
|
||||
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
@@ -150,7 +154,23 @@
|
||||
<button type="submit" name="add_user" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
|
||||
function generatePassword() {
|
||||
jQuery.get(
|
||||
"/agent/ajax.php", {
|
||||
get_readable_pass: 'true'
|
||||
},
|
||||
function(data) {
|
||||
const password = JSON.parse(data);
|
||||
document.getElementById("password").value = password;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<?php
|
||||
require_once "../../../includes/modal_footer.php";
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
<div class="modal" id="resetAllUserPassModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-body">
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
<div class="modal-body">
|
||||
<div class="mb-4" style="text-align: center;">
|
||||
<i class="far fas fa-10x fa-skull-crossbones text-danger mb-3 mt-3"></i>
|
||||
<h2>Incident Response: Agent Password Reset</h2>
|
||||
@@ -25,7 +29,7 @@
|
||||
</div>
|
||||
<button type="button" class="btn btn-outline-secondary btn-lg px-5 mr-4" data-dismiss="modal">Cancel</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "../../../includes/modal_footer.php";
|
||||
|
||||
@@ -94,11 +94,14 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span>
|
||||
</div>
|
||||
<input type="password" class="form-control" data-toggle="password" name="new_password"
|
||||
<input type="password" class="form-control" data-toggle="password" name="new_password" id="password"
|
||||
placeholder="Leave Blank For No Password Change" autocomplete="new-password">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span>
|
||||
</div>
|
||||
<div class="input-group-append">
|
||||
<span class="btn btn-default"><i class="fa fa-fw fa-question" onclick="generatePassword()"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -200,5 +203,23 @@ ob_start();
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
|
||||
function generatePassword() {
|
||||
// Send a GET request to ajax.php as ajax.php?get_readable_pass=true
|
||||
jQuery.get(
|
||||
"/agent/ajax.php", {
|
||||
get_readable_pass: 'true'
|
||||
},
|
||||
function(data) {
|
||||
//If we get a response from post.php, parse it as JSON
|
||||
const password = JSON.parse(data);
|
||||
document.getElementById("password").value = password;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<?php
|
||||
require_once "../../../includes/modal_footer.php";
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
<div class="modal" id="userInviteModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-user-plus"></i>Invite User</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
|
||||
</div>
|
||||
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
@@ -39,7 +43,7 @@
|
||||
<button type="submit" name="invite_user" class="btn btn-primary text-bold"><i class="fas fa-paper-plane mr-2"></i>Send Invite</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once "../../../includes/modal_footer.php";
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
<div class="modal" id="addVendorTemplateModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-building mr-2"></i>New Vendor Template</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="client_id" value="<?php if (isset($_GET['client_id'])) { echo $client_id; } else { echo 0; } ?>">
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
@@ -162,7 +165,7 @@
|
||||
<button type="submit" name="add_vendor_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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
113
admin/modules.php
Normal file
113
admin/modules.php
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
// Default Column Sortby Filter
|
||||
$sort = "module_name";
|
||||
$order = "DESC";
|
||||
|
||||
require_once "includes/inc_all_admin.php";
|
||||
|
||||
$sql = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT SQL_CALC_FOUND_ROWS * FROM modules
|
||||
WHERE (module_name LIKE '%$q%' OR module_description LIKE '%$q%')
|
||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
||||
);
|
||||
|
||||
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-puzzle-piece mr-2"></i>Access Modules</h3>
|
||||
<div class="card-tools">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/module/module_add.php">
|
||||
<i class="fas fa-fw fa-plus mr-2"></i>New Module
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form class="mb-4" autocomplete="off">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="input-group">
|
||||
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) {echo stripslashes(nullable_htmlentities($q));} ?>" placeholder="Search Modules">
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-primary"><i class="fa fa-search"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<hr>
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-striped table-borderless table-hover">
|
||||
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?> text-nowrap">
|
||||
<tr>
|
||||
<th>
|
||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=module_name&order=<?php echo $disp; ?>">
|
||||
Module <?php if ($sort == 'module_name') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th class="text-center">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
|
||||
while ($row = mysqli_fetch_array($sql)) {
|
||||
$module_id = intval($row['module_id']);
|
||||
$module_name = nullable_htmlentities($row['module_name']);
|
||||
$module_description = nullable_htmlentities($row['module_description']);
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="#" <?php if ($module_id > 6) { ?> class="ajax-modal" data-modal-url="modals/modules/module_edit.php?id=<?= $module_id ?>" <?php } ?>>
|
||||
<strong class="text-dark"><?= $module_name ?></strong>
|
||||
</a>
|
||||
<div class="text-secondary"><?= $module_description ?></div>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($module_id > 6) { ?>
|
||||
<div class="dropdown dropleft text-center">
|
||||
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
|
||||
<i class="fas fa-ellipsis-h"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/module/module_edit.php?id=<?= $module_id ?>">
|
||||
<i class="fas fa-fw fa-user-edit mr-2"></i>Edit
|
||||
</a>
|
||||
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-danger confirm-link" href="post.php?delete_module=<?= $module_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
|
||||
<i class="fas fa-fw fa-archive mr-2"></i>Delete
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<?php } else { echo "<p class='text-center'>N/A Predefined</p>"; } ?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<?php
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php require_once "../includes/filter_footer.php";
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
|
||||
require_once "../includes/footer.php";
|
||||
@@ -16,7 +16,7 @@ $num_rows = mysqli_num_rows($sql);
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-credit-card mr-2"></i>Payment Methods</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addPaymentMethodModal"><i class="fas fa-plus mr-2"></i>Add Payment Method</button>
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/payment_method/payment_method_add.php"><i class="fas fa-plus mr-2"></i>Add Payment Method</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@@ -98,5 +98,4 @@ $num_rows = mysqli_num_rows($sql);
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "modals/payment_method/payment_method_add.php";
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
@@ -21,7 +21,7 @@ $num_rows = mysqli_num_rows($sql);
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-credit-card mr-2"></i>Payment Providers</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addPaymentProviderModal"><i class="fas fa-plus mr-2"></i>Add Provider</button>
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/payment_provider/payment_provider_add.php"><i class="fas fa-plus mr-2"></i>Add Provider</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@@ -135,5 +135,4 @@ $num_rows = mysqli_num_rows($sql);
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "modals/payment_provider/payment_provider_add.php";
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
@@ -36,7 +36,4 @@ if (isset($session_is_admin) && $session_is_admin) {
|
||||
require_once "../post/logout.php";
|
||||
|
||||
// TODO: Find a home for these
|
||||
|
||||
require_once "../post/ai.php";
|
||||
require_once "../post/misc.php";
|
||||
|
||||
|
||||
@@ -2,36 +2,170 @@
|
||||
|
||||
/*
|
||||
* ITFlow - GET/POST request handler for DB / master key backup
|
||||
* Rewritten with streaming SQL dump, component checksums, safer zipping, and better headers.
|
||||
*/
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
require_once "../includes/app_version.php";
|
||||
|
||||
if (isset($_GET['download_backup'])) {
|
||||
// --- Optional performance levers for big backups ---
|
||||
@set_time_limit(0);
|
||||
if (function_exists('ini_set')) {
|
||||
@ini_set('memory_limit', '1024M');
|
||||
}
|
||||
|
||||
validateCSRFToken($_GET['csrf_token']);
|
||||
/**
|
||||
* Write a line to a file handle with newline.
|
||||
*/
|
||||
function fwrite_ln($fh, string $s): void {
|
||||
fwrite($fh, $s);
|
||||
fwrite($fh, PHP_EOL);
|
||||
}
|
||||
|
||||
$timestamp = date('YmdHis');
|
||||
$baseName = "itflow_$timestamp";
|
||||
/**
|
||||
* Stream a SQL dump of schema and data into $sqlFile.
|
||||
* - Tables first (DROP + CREATE + INSERTs)
|
||||
* - Views (DROP VIEW + CREATE VIEW)
|
||||
* - Triggers (DROP TRIGGER + CREATE TRIGGER)
|
||||
*
|
||||
* NOTE: Routines/events are not dumped here. Add if needed.
|
||||
*/
|
||||
function dump_database_streaming(mysqli $mysqli, string $sqlFile): void {
|
||||
$fh = fopen($sqlFile, 'wb');
|
||||
if (!$fh) {
|
||||
http_response_code(500);
|
||||
exit("Cannot open dump file");
|
||||
}
|
||||
|
||||
// === 0. Scoped cleanup ===
|
||||
$cleanupFiles = [];
|
||||
// Preamble
|
||||
fwrite_ln($fh, "-- UTF-8 + Foreign Key Safe Dump");
|
||||
fwrite_ln($fh, "SET NAMES 'utf8mb4';");
|
||||
fwrite_ln($fh, "SET FOREIGN_KEY_CHECKS = 0;");
|
||||
fwrite_ln($fh, "SET UNIQUE_CHECKS = 0;");
|
||||
fwrite_ln($fh, "SET AUTOCOMMIT = 0;");
|
||||
fwrite_ln($fh, "");
|
||||
|
||||
$registerTempFileForCleanup = function ($file) use (&$cleanupFiles) {
|
||||
$cleanupFiles[] = $file;
|
||||
};
|
||||
// Gather tables and views
|
||||
$tables = [];
|
||||
$views = [];
|
||||
|
||||
register_shutdown_function(function () use (&$cleanupFiles) {
|
||||
foreach ($cleanupFiles as $file) {
|
||||
if (is_file($file)) {
|
||||
@unlink($file);
|
||||
$res = $mysqli->query("SHOW FULL TABLES");
|
||||
if (!$res) {
|
||||
fclose($fh);
|
||||
error_log("MySQL Error (SHOW FULL TABLES): " . $mysqli->error);
|
||||
http_response_code(500);
|
||||
exit("Error retrieving tables.");
|
||||
}
|
||||
while ($row = $res->fetch_array(MYSQLI_NUM)) {
|
||||
$name = $row[0];
|
||||
$type = strtoupper($row[1] ?? '');
|
||||
if ($type === 'VIEW') {
|
||||
$views[] = $name;
|
||||
} else {
|
||||
$tables[] = $name;
|
||||
}
|
||||
}
|
||||
});
|
||||
$res->close();
|
||||
|
||||
// === 1. Local helper function: zipFolder
|
||||
$zipFolder = function ($folderPath, $zipFilePath) {
|
||||
// --- TABLES: structure and data ---
|
||||
foreach ($tables as $table) {
|
||||
$createRes = $mysqli->query("SHOW CREATE TABLE `{$mysqli->real_escape_string($table)}`");
|
||||
if (!$createRes) {
|
||||
error_log("MySQL Error (SHOW CREATE TABLE $table): " . $mysqli->error);
|
||||
// continue to next table
|
||||
continue;
|
||||
}
|
||||
$createRow = $createRes->fetch_assoc();
|
||||
$createSQL = array_values($createRow)[1] ?? '';
|
||||
$createRes->close();
|
||||
|
||||
fwrite_ln($fh, "-- ----------------------------");
|
||||
fwrite_ln($fh, "-- Table structure for `{$table}`");
|
||||
fwrite_ln($fh, "-- ----------------------------");
|
||||
fwrite_ln($fh, "DROP TABLE IF EXISTS `{$table}`;");
|
||||
fwrite_ln($fh, $createSQL . ";");
|
||||
fwrite_ln($fh, "");
|
||||
|
||||
// Dump data in a streaming fashion
|
||||
$dataRes = $mysqli->query("SELECT * FROM `{$mysqli->real_escape_string($table)}`", MYSQLI_USE_RESULT);
|
||||
if ($dataRes) {
|
||||
$wroteHeader = false;
|
||||
while ($row = $dataRes->fetch_assoc()) {
|
||||
if (!$wroteHeader) {
|
||||
fwrite_ln($fh, "-- Dumping data for table `{$table}`");
|
||||
$wroteHeader = true;
|
||||
}
|
||||
$cols = array_map(fn($c) => '`' . $mysqli->real_escape_string($c) . '`', array_keys($row));
|
||||
$vals = array_map(
|
||||
function ($v) use ($mysqli) {
|
||||
return is_null($v) ? "NULL" : "'" . $mysqli->real_escape_string($v) . "'";
|
||||
},
|
||||
array_values($row)
|
||||
);
|
||||
fwrite_ln($fh, "INSERT INTO `{$table}` (" . implode(", ", $cols) . ") VALUES (" . implode(", ", $vals) . ");");
|
||||
}
|
||||
$dataRes->close();
|
||||
if ($wroteHeader) fwrite_ln($fh, "");
|
||||
}
|
||||
}
|
||||
|
||||
// --- VIEWS ---
|
||||
foreach ($views as $view) {
|
||||
$escView = $mysqli->real_escape_string($view);
|
||||
$cRes = $mysqli->query("SHOW CREATE VIEW `{$escView}`");
|
||||
if ($cRes) {
|
||||
$row = $cRes->fetch_assoc();
|
||||
$createView = $row['Create View'] ?? '';
|
||||
$cRes->close();
|
||||
|
||||
fwrite_ln($fh, "-- ----------------------------");
|
||||
fwrite_ln($fh, "-- View structure for `{$view}`");
|
||||
fwrite_ln($fh, "-- ----------------------------");
|
||||
fwrite_ln($fh, "DROP VIEW IF EXISTS `{$view}`;");
|
||||
// Ensure statement ends with semicolon
|
||||
if (!str_ends_with($createView, ';')) $createView .= ';';
|
||||
fwrite_ln($fh, $createView);
|
||||
fwrite_ln($fh, "");
|
||||
}
|
||||
}
|
||||
|
||||
// --- TRIGGERS ---
|
||||
$tRes = $mysqli->query("SHOW TRIGGERS");
|
||||
if ($tRes) {
|
||||
while ($t = $tRes->fetch_assoc()) {
|
||||
$triggerName = $t['Trigger'];
|
||||
$escTrig = $mysqli->real_escape_string($triggerName);
|
||||
$crt = $mysqli->query("SHOW CREATE TRIGGER `{$escTrig}`");
|
||||
if ($crt) {
|
||||
$row = $crt->fetch_assoc();
|
||||
$createTrig = $row['SQL Original Statement'] ?? ($row['Create Trigger'] ?? '');
|
||||
$crt->close();
|
||||
|
||||
fwrite_ln($fh, "-- ----------------------------");
|
||||
fwrite_ln($fh, "-- Trigger for `{$triggerName}`");
|
||||
fwrite_ln($fh, "-- ----------------------------");
|
||||
fwrite_ln($fh, "DROP TRIGGER IF EXISTS `{$triggerName}`;");
|
||||
if (!str_ends_with($createTrig, ';')) $createTrig .= ';';
|
||||
fwrite_ln($fh, $createTrig);
|
||||
fwrite_ln($fh, "");
|
||||
}
|
||||
}
|
||||
$tRes->close();
|
||||
}
|
||||
|
||||
// Postamble
|
||||
fwrite_ln($fh, "SET FOREIGN_KEY_CHECKS = 1;");
|
||||
fwrite_ln($fh, "SET UNIQUE_CHECKS = 1;");
|
||||
fwrite_ln($fh, "COMMIT;");
|
||||
|
||||
fclose($fh);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zip a folder to $zipFilePath, skipping symlinks and dot-entries.
|
||||
*/
|
||||
function zipFolderStrict(string $folderPath, string $zipFilePath): void {
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open($zipFilePath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== TRUE) {
|
||||
error_log("Failed to open zip file: $zipFilePath");
|
||||
@@ -39,30 +173,57 @@ if (isset($_GET['download_backup'])) {
|
||||
exit("Internal Server Error: Cannot open zip archive.");
|
||||
}
|
||||
|
||||
$folderPath = realpath($folderPath);
|
||||
if (!$folderPath) {
|
||||
error_log("Invalid folder path: $folderPath");
|
||||
http_response_code(500);
|
||||
exit("Internal Server Error: Invalid folder path.");
|
||||
$folderReal = realpath($folderPath);
|
||||
if (!$folderReal || !is_dir($folderReal)) {
|
||||
// Create an empty archive if uploads folder doesn't exist yet
|
||||
$zip->close();
|
||||
return;
|
||||
}
|
||||
|
||||
$files = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($folderPath),
|
||||
new RecursiveDirectoryIterator($folderReal, FilesystemIterator::SKIP_DOTS),
|
||||
RecursiveIteratorIterator::LEAVES_ONLY
|
||||
);
|
||||
|
||||
foreach ($files as $file) {
|
||||
if (!$file->isDir()) {
|
||||
/** @var SplFileInfo $file */
|
||||
if ($file->isDir()) continue;
|
||||
if ($file->isLink()) continue; // skip symlinks
|
||||
$filePath = $file->getRealPath();
|
||||
$relativePath = substr($filePath, strlen($folderPath) + 1);
|
||||
$zip->addFile($filePath, $relativePath);
|
||||
if ($filePath === false) continue;
|
||||
|
||||
// ensure path is inside the folder boundary
|
||||
if (strpos($filePath, $folderReal . DIRECTORY_SEPARATOR) !== 0 && $filePath !== $folderReal) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$relativePath = substr($filePath, strlen($folderReal) + 1);
|
||||
$zip->addFile($filePath, $relativePath);
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
};
|
||||
}
|
||||
|
||||
// === 2. Create all temp files
|
||||
if (isset($_GET['download_backup'])) {
|
||||
|
||||
validateCSRFToken($_GET['csrf_token']);
|
||||
|
||||
$timestamp = date('YmdHis');
|
||||
$baseName = "itflow_{$timestamp}";
|
||||
$downloadName = $baseName . ".zip";
|
||||
|
||||
// === Scoped cleanup of temp files ===
|
||||
$cleanupFiles = [];
|
||||
$registerTempFileForCleanup = function ($file) use (&$cleanupFiles) {
|
||||
$cleanupFiles[] = $file;
|
||||
};
|
||||
register_shutdown_function(function () use (&$cleanupFiles) {
|
||||
foreach ($cleanupFiles as $file) {
|
||||
if (is_file($file)) { @unlink($file); }
|
||||
}
|
||||
});
|
||||
|
||||
// === Create temp files ===
|
||||
$sqlFile = tempnam(sys_get_temp_dir(), $baseName . "_sql_");
|
||||
$uploadsZip = tempnam(sys_get_temp_dir(), $baseName . "_uploads_");
|
||||
$versionFile = tempnam(sys_get_temp_dir(), $baseName . "_version_");
|
||||
@@ -70,117 +231,75 @@ if (isset($_GET['download_backup'])) {
|
||||
|
||||
foreach ([$sqlFile, $uploadsZip, $versionFile, $finalZip] as $f) {
|
||||
$registerTempFileForCleanup($f);
|
||||
chmod($f, 0600);
|
||||
@chmod($f, 0600);
|
||||
}
|
||||
|
||||
// === 3. Generate SQL Dump
|
||||
$sqlContent = "-- UTF-8 + Foreign Key Safe Dump\n";
|
||||
$sqlContent .= "SET NAMES 'utf8mb4';\n";
|
||||
$sqlContent .= "SET foreign_key_checks = 0;\n\n";
|
||||
// === Generate SQL Dump (streaming) ===
|
||||
dump_database_streaming($mysqli, $sqlFile);
|
||||
|
||||
$tables = [];
|
||||
$res = $mysqli->query("SHOW TABLES");
|
||||
if (!$res) {
|
||||
error_log("MySQL Error: " . $mysqli->error);
|
||||
exit("Error retrieving tables.");
|
||||
}
|
||||
// === Zip the uploads folder (strict) ===
|
||||
zipFolderStrict("../uploads", $uploadsZip);
|
||||
|
||||
while ($row = $res->fetch_row()) {
|
||||
$tables[] = $row[0];
|
||||
}
|
||||
// === Gather metadata & checksums ===
|
||||
$commitHash = (function_exists('shell_exec') ? trim(shell_exec('git log -1 --format=%H 2>/dev/null')) : '') ?: 'N/A';
|
||||
$gitBranch = (function_exists('shell_exec') ? trim(shell_exec('git rev-parse --abbrev-ref HEAD 2>/dev/null')) : '') ?: 'N/A';
|
||||
|
||||
foreach ($tables as $table) {
|
||||
$createRes = $mysqli->query("SHOW CREATE TABLE `$table`");
|
||||
if (!$createRes) {
|
||||
error_log("MySQL Error: " . $mysqli->error);
|
||||
continue;
|
||||
}
|
||||
|
||||
$createRow = $createRes->fetch_assoc();
|
||||
$createSQL = array_values($createRow)[1];
|
||||
|
||||
$sqlContent .= "\n-- ----------------------------\n";
|
||||
$sqlContent .= "-- Table structure for `$table`\n";
|
||||
$sqlContent .= "-- ----------------------------\n";
|
||||
$sqlContent .= "DROP TABLE IF EXISTS `$table`;\n";
|
||||
$sqlContent .= $createSQL . ";\n\n";
|
||||
|
||||
$dataRes = $mysqli->query("SELECT * FROM `$table`");
|
||||
if ($dataRes && $dataRes->num_rows > 0) {
|
||||
$sqlContent .= "-- Dumping data for table `$table`\n";
|
||||
while ($row = $dataRes->fetch_assoc()) {
|
||||
$columns = array_map(fn($col) => '`' . $mysqli->real_escape_string($col) . '`', array_keys($row));
|
||||
$values = array_map(function ($val) use ($mysqli) {
|
||||
return is_null($val) ? "NULL" : "'" . $mysqli->real_escape_string($val) . "'";
|
||||
}, array_values($row));
|
||||
$sqlContent .= "INSERT INTO `$table` (" . implode(", ", $columns) . ") VALUES (" . implode(", ", $values) . ");\n";
|
||||
}
|
||||
$sqlContent .= "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$sqlContent .= "SET foreign_key_checks = 1;\n";
|
||||
file_put_contents($sqlFile, $sqlContent);
|
||||
|
||||
// === 4. Zip the uploads folder
|
||||
$zipFolder("../uploads", $uploadsZip);
|
||||
|
||||
// === 5. Create version.txt
|
||||
$commitHash = trim(shell_exec('git log -1 --format=%H')) ?: 'N/A';
|
||||
$gitBranch = trim(shell_exec('git rev-parse --abbrev-ref HEAD')) ?: 'N/A';
|
||||
$dbSha = hash_file('sha256', $sqlFile) ?: 'N/A';
|
||||
$upSha = hash_file('sha256', $uploadsZip) ?: 'N/A';
|
||||
|
||||
$versionContent = "ITFlow Backup Metadata\n";
|
||||
$versionContent .= "-----------------------------\n";
|
||||
$versionContent .= "Generated: " . date('Y-m-d H:i:s') . "\n";
|
||||
$versionContent .= "Backup File: " . basename($finalZip) . "\n";
|
||||
$versionContent .= "Generated By: $session_name\n";
|
||||
$versionContent .= "Backup File: " . $downloadName . "\n";
|
||||
$versionContent .= "Generated By: " . ($session_name ?? 'Unknown User') . "\n";
|
||||
$versionContent .= "Host: " . gethostname() . "\n";
|
||||
$versionContent .= "Git Branch: $gitBranch\n";
|
||||
$versionContent .= "Git Commit: $commitHash\n";
|
||||
$versionContent .= "ITFlow Version: " . (defined('APP_VERSION') ? APP_VERSION : 'Unknown') . "\n";
|
||||
$versionContent .= "Database Version: " . (defined('CURRENT_DATABASE_VERSION') ? CURRENT_DATABASE_VERSION : 'Unknown') . "\n";
|
||||
$versionContent .= "Checksum (SHA256): \n";
|
||||
$versionContent .= "Checksums (SHA256):\n";
|
||||
$versionContent .= " db.sql: $dbSha\n";
|
||||
$versionContent .= " uploads.zip: $upSha\n";
|
||||
|
||||
file_put_contents($versionFile, $versionContent);
|
||||
@chmod($versionFile, 0600);
|
||||
|
||||
// === 6. Build final ZIP
|
||||
// === Build final ZIP ===
|
||||
$final = new ZipArchive();
|
||||
if ($final->open($finalZip, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== TRUE) {
|
||||
error_log("Failed to create final zip: $finalZip");
|
||||
http_response_code(500);
|
||||
exit("Internal Server Error: Unable to create backup archive.");
|
||||
}
|
||||
|
||||
$final->addFile($sqlFile, "db.sql");
|
||||
$final->addFile($uploadsZip, "uploads.zip");
|
||||
$final->addFile($versionFile, "version.txt");
|
||||
$final->close();
|
||||
|
||||
chmod($finalZip, 0600);
|
||||
@chmod($finalZip, 0600);
|
||||
|
||||
$checksum = hash_file('sha256', $finalZip);
|
||||
file_put_contents($versionFile, $versionContent . "$checksum\n");
|
||||
|
||||
// === 7. Serve final ZIP
|
||||
// === Serve final ZIP with a stable filename ===
|
||||
header('Content-Type: application/zip');
|
||||
header('Content-Disposition: attachment; filename="' . basename($finalZip) . '"');
|
||||
header('X-Content-Type-Options: nosniff');
|
||||
header('Content-Disposition: attachment; filename="' . $downloadName . '"');
|
||||
header('Content-Length: ' . filesize($finalZip));
|
||||
header('Pragma: public');
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
|
||||
// Push file
|
||||
flush();
|
||||
$fp = fopen($finalZip, 'rb');
|
||||
fpassthru($fp);
|
||||
fclose($fp);
|
||||
|
||||
logAction("System", "Backup Download", "$session_name downloaded full backup.");
|
||||
// Log + UX
|
||||
logAction("System", "Backup Download", ($session_name ?? 'Unknown User') . " downloaded full backup.");
|
||||
flash_alert("Full backup downloaded.");
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
if (isset($_POST['backup_master_key'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
63
admin/post/contract_template.php
Normal file
63
admin/post/contract_template.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ITFlow - GET/POST request handler for Contract Templates
|
||||
*/
|
||||
|
||||
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']);
|
||||
|
||||
// Numeric fields cast to integer
|
||||
$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']);
|
||||
$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']);
|
||||
|
||||
// Insert into database (numbers not quoted)
|
||||
mysqli_query($mysqli, "
|
||||
INSERT INTO contract_templates SET
|
||||
contract_template_name = '$name',
|
||||
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_support_hours = '$support_hours',
|
||||
contract_template_net_terms = $net_terms,
|
||||
contract_template_created_by = $session_user_id,
|
||||
contract_template_created_at = NOW()
|
||||
");
|
||||
|
||||
$contract_template_id = mysqli_insert_id($mysqli);
|
||||
|
||||
// Log action
|
||||
logAction("Contract Template", "Create", "$session_name created contract template $name", 0, $contract_template_id);
|
||||
|
||||
// Flash message
|
||||
flash_alert("Contract Template <strong>$name</strong> created");
|
||||
|
||||
// Redirect back
|
||||
redirect();
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -22,7 +22,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-project-diagram mr-2"></i>Project Templates</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addProjectTemplateModal"><i class="fas fa-plus mr-2"></i>New Project Template</button>
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/project_template/project_template_add.php"><i class="fas fa-plus mr-2"></i>New Project Template</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@@ -87,7 +87,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<a class="text-dark" href="#" data-toggle="modal" data-target="#editProjectTemplateModal<?php echo $project_template_id; ?>">
|
||||
<a class="text-dark ajax-modal" href="#" data-modal-url="modals/project_template/project_template_edit.php?project_template_id=<?= $project_template_id ?>">
|
||||
<div class="media">
|
||||
<i class="fa fa-fw fa-2x fa-project-diagram mr-3"></i>
|
||||
<div class="media-body">
|
||||
@@ -109,7 +109,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<i class="fas fa-ellipsis-h"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#editProjectTemplateModal<?php echo $project_template_id; ?>">
|
||||
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/project_template/project_template_edit.php?project_template_id=<?= $project_template_id ?>">
|
||||
<i class="fas fa-fw fa-edit mr-2"></i>Edit
|
||||
</a>
|
||||
<?php if($session_user_role == 3) { ?>
|
||||
@@ -125,8 +125,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
|
||||
<?php
|
||||
|
||||
require "modals/project_template/project_template_edit.php";
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -134,12 +132,9 @@ $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>
|
||||
|
||||
<?php
|
||||
require_once "modals/project_template/project_template_add.php";
|
||||
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
@@ -13,9 +13,9 @@ if (isset($_GET['project_template_id'])) {
|
||||
);
|
||||
|
||||
if (mysqli_num_rows($sql_project_templates) == 0) {
|
||||
echo "<center><h1 class='text-secondary mt-5'>Nothing to see here</h1><a class='btn btn-lg btn-secondary mt-3' href='admin_project_template.php'><i class='fa fa-fw fa-arrow-left'></i> Go Back</a></center>";
|
||||
echo "<center><h1 class='text-secondary mt-5'>Nothing to see here</h1><a class='btn btn-lg btn-secondary mt-3' href='javascript:history.back()'><i class='fa fa-fw fa-arrow-left'></i> Go Back</a></center>";
|
||||
|
||||
include_once "footer.php";
|
||||
require_once "../includes/footer.php";
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ if (isset($_GET['project_template_id'])) {
|
||||
|
||||
<div class="col-sm-2">
|
||||
<div class="btn-group float-right">
|
||||
<button type="button" class="btn btn-primary btn-sm" href="#" data-toggle="modal" data-target="#addProjectTemplateTicketTemplateModal">
|
||||
<button type="button" class="btn btn-primary btn-sm ajax-modal" href="#" data-modal-url="modals/project_template/project_template_ticket_template_add.php?project_template_id=<?= $project_template_id ?>">
|
||||
<i class="fas fa-fw fa-plus mr-2"></i>Add Ticket Template
|
||||
</button>
|
||||
<div class="dropdown dropleft text-center ml-3">
|
||||
@@ -99,7 +99,7 @@ if (isset($_GET['project_template_id'])) {
|
||||
<i class="fas fa-fw fa-ellipsis-v"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#editProjectTemplateModal<?php echo $project_template_id; ?>">
|
||||
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/project_template/project_template_edit.php?project_template_id=<?= $project_template_id ?>">
|
||||
<i class="fas fa-fw fa-edit mr-2"></i>Edit Template
|
||||
</a>
|
||||
<?php if ($session_user_role == 3) { ?>
|
||||
@@ -221,9 +221,6 @@ if (isset($_GET['project_template_id'])) {
|
||||
|
||||
<?php
|
||||
|
||||
require_once "modals/project_template/project_template_edit.php";
|
||||
require_once "modals/project_template/project_template_ticket_template_add.php";
|
||||
|
||||
}
|
||||
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
@@ -24,7 +24,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-user-shield mr-2"></i>Roles</h3>
|
||||
<div class="card-tools">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addRoleModal">
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/role/role_add.php">
|
||||
<i class="fas fa-fw fa-user-plus mr-2"></i>New Role
|
||||
</button>
|
||||
</div>
|
||||
@@ -143,6 +143,4 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</div>
|
||||
|
||||
<?php
|
||||
|
||||
require_once "modals/role/role_add.php";
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
@@ -21,7 +21,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-cube mr-2"></i>License Templates</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addSoftwareTemplateModal"><i class="fas fa-plus mr-2"></i>New License Template</button>
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/software_template/software_template_add.php"><i class="fas fa-plus mr-2"></i>New License Template</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@@ -127,5 +127,4 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "modals/software_template/software_template_add.php";
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
@@ -17,11 +17,11 @@ $num_rows = mysqli_num_rows($sql);
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-balance-scale mr-2"></i>Taxes</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addTaxModal"><i class="fas fa-plus mr-2"></i>New Tax</button>
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/tax/tax_add.php"><i class="fas fa-plus mr-2"></i>New Tax</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@@ -93,8 +93,7 @@ $num_rows = mysqli_num_rows($sql);
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "modals/tax/tax_add.php";
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
@@ -21,7 +21,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-info-circle mr-2"></i>Tickets Statuses</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addTicketStatusModal"><i class="fas fa-plus mr-2"></i>New Ticket Status</button>
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/ticket_status/ticket_status_add.php"><i class="fas fa-plus mr-2"></i>New Ticket Status</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -120,13 +120,9 @@ $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>
|
||||
|
||||
<?php
|
||||
require_once "modals/ticket_status/ticket_status_add.php";
|
||||
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
|
||||
@@ -8,10 +8,15 @@ require_once "includes/inc_all_admin.php";
|
||||
|
||||
$sql = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT SQL_CALC_FOUND_ROWS * FROM ticket_templates
|
||||
"SELECT SQL_CALC_FOUND_ROWS *,
|
||||
COUNT(task_template_id) AS task_count
|
||||
FROM ticket_templates
|
||||
LEFT JOIN task_templates ON task_template_ticket_template_id = ticket_template_id
|
||||
WHERE (ticket_template_name LIKE '%$q%' OR ticket_template_description LIKE '%$q%')
|
||||
AND ticket_template_archived_at IS NULL
|
||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
||||
GROUP BY ticket_template_id
|
||||
ORDER BY $sort $order
|
||||
LIMIT $record_from, $record_to"
|
||||
);
|
||||
|
||||
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
@@ -46,14 +51,18 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<hr>
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-striped table-borderless table-hover">
|
||||
<thead class="text-dark <?php if($num_rows[0] == 0){ echo "d-none"; } ?>">
|
||||
<thead class="text-dark <?php if($num_rows[0] == 0) { echo "d-none"; } ?>">
|
||||
<tr>
|
||||
<th>
|
||||
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=ticket_template_name&order=<?php echo $disp; ?>">
|
||||
<a class="text-secondary" href="?<?= $url_query_strings_sort ?>&sort=ticket_template_name&order=<?= $disp ?>">
|
||||
Template <?php if ($sort == 'ticket_template_name') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th>Tasks</th>
|
||||
<th>
|
||||
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=task_count&order=<?php echo $disp; ?>">
|
||||
Tasks <?php if ($sort == 'task_count') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th class="text-center">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -66,6 +75,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
$ticket_template_description = nullable_htmlentities($row['ticket_template_description']);
|
||||
$ticket_template_subject = nullable_htmlentities($row['ticket_template_subject']);
|
||||
$ticket_template_created_at = nullable_htmlentities($row['ticket_template_created_at']);
|
||||
$task_count = intval($row['task_count']);
|
||||
|
||||
?>
|
||||
<tr>
|
||||
@@ -75,23 +85,23 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<i class="fa fa-fw fa-2x fa-life-ring mr-3"></i>
|
||||
<div class="media-body">
|
||||
<div>
|
||||
<a href="ticket_template_details.php?ticket_template_id=<?php echo $ticket_template_id; ?>">
|
||||
<?php echo $ticket_template_name; ?>
|
||||
<a href="ticket_template_details.php?ticket_template_id=<?= $ticket_template_id ?>">
|
||||
<?= $ticket_template_name ?>
|
||||
</a>
|
||||
</div>
|
||||
<div><small class="text-secondary"><?php echo $ticket_template_description; ?></small></div>
|
||||
<div><small class="text-secondary"><?= $ticket_template_description ?></small></div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</td>
|
||||
<td>0</td>
|
||||
<td><?= $task_count ?></td>
|
||||
<td>
|
||||
<div class="dropdown dropleft text-center">
|
||||
<button class="btn btn-secondary btn-sm" data-toggle="dropdown">
|
||||
<i class="fas fa-ellipsis-h"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_ticket_template=<?php echo $ticket_template_id; ?>">
|
||||
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_ticket_template=<?= $ticket_template_id ?>">
|
||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||
</a>
|
||||
</div>
|
||||
@@ -112,4 +122,3 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<?php
|
||||
require_once "modals/ticket_template/ticket_template_add.php";
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
|
||||
@@ -15,9 +15,15 @@ if (isset($_GET['ticket_template_id'])) {
|
||||
$ticket_template_id = intval($_GET['ticket_template_id']);
|
||||
}
|
||||
|
||||
$sql_ticket_templates = mysqli_query($mysqli, "SELECT * FROM ticket_templates WHERE ticket_template_id = $ticket_template_id");
|
||||
$sql_ticket_template = mysqli_query($mysqli, "SELECT * FROM ticket_templates WHERE ticket_template_id = $ticket_template_id LIMIT 1");
|
||||
|
||||
$row = mysqli_fetch_array($sql_ticket_templates);
|
||||
if (mysqli_num_rows($sql_ticket_template) == 0) {
|
||||
echo "<center><h1 class='text-secondary mt-5'>Nothing to see here</h1><a class='btn btn-lg btn-secondary mt-3' href='javascript:history.back()'><i class='fa fa-fw fa-arrow-left'></i> Go Back</a></center>";
|
||||
require_once "../includes/footer.php";
|
||||
exit();
|
||||
}
|
||||
|
||||
$row = mysqli_fetch_array($sql_ticket_template);
|
||||
|
||||
$ticket_template_name = nullable_htmlentities($row['ticket_template_name']);
|
||||
$ticket_template_description = nullable_htmlentities($row['ticket_template_description']);
|
||||
|
||||
@@ -26,16 +26,16 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-users mr-2"></i>Users</h3>
|
||||
<div class="card-tools">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addUserModal">
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/user/user_add.php">
|
||||
<i class="fas fa-fw fa-user-plus mr-2"></i>New User
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
|
||||
<div class="dropdown-menu">
|
||||
<!--<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#userInviteModal"><i class="fas fa-paper-plane mr-2"></i>Invite User</a>-->
|
||||
<!--<a class="dropdown-item text-dark ajax-modal" href="#" data-modal-url="modals/user/user_invite.php"><i class="fas fa-paper-plane mr-2"></i>Invite User</a>-->
|
||||
<?php if ($num_rows[0] > 1) { ?>
|
||||
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#exportUserModal"><i class="fa fa-fw fa-download mr-2"></i>Export</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-danger" href="#" data-toggle="modal" data-target="#resetAllUserPassModal"><i class="fas fa-skull-crossbones mr-2"></i>IR</a>
|
||||
<a class="dropdown-item text-danger ajax-modal" href="#" data-modal-url="modals/user/user_all_reset_password.php" data-modal-size="lg"><i class="fas fa-skull-crossbones mr-2"></i>IR</a>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -233,15 +233,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function generatePassword() {
|
||||
document.getElementById("password").value = "<?php echo randomString() ?>"
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php
|
||||
require_once "modals/user/user_add.php";
|
||||
require_once "modals/user/user_invite.php";
|
||||
require_once "modals/user/user_export.php";
|
||||
require_once "modals/user/user_all_reset_password.php";
|
||||
require_once "../includes/footer.php";
|
||||
@@ -16,13 +16,13 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2">
|
||||
<i class="fas fa-fw fa-building mr-2"></i>Vendor Templates
|
||||
</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addVendorTemplateModal">
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/vendor_template/vendor_template_add.php">
|
||||
<i class="fas fa-plus mr-2"></i>New Vendor Template
|
||||
</button>
|
||||
</div>
|
||||
@@ -158,11 +158,9 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php require_once "../includes/filter_footer.php";
|
||||
?>
|
||||
</div>
|
||||
<?php require_once "../includes/filter_footer.php"; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "modals/vendor_template/vendor_template_add.php";
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
@@ -25,7 +25,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="fa fa-fw fa-piggy-bank mr-2"></i>Accounts</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addAccountModal"><i class="fas fa-plus mr-2"></i>New Account</button>
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/account/account_add.php"><i class="fas fa-plus mr-2"></i>New Account</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@@ -123,6 +123,4 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</div>
|
||||
|
||||
<?php
|
||||
|
||||
require_once "modals/account/account_add.php";
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
319
agent/ajax.php
319
agent/ajax.php
@@ -432,7 +432,7 @@ if (isset($_GET['get_totp_token_via_id'])) {
|
||||
}
|
||||
|
||||
if (isset($_GET['get_readable_pass'])) {
|
||||
echo json_encode(GenerateReadablePassword(4));
|
||||
echo json_encode(GenerateReadablePassword(1));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -675,3 +675,320 @@ if (isset($_POST['update_recurring_invoice_items_order'])) {
|
||||
echo json_encode(['status' => 'success']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (isset($_GET['client_duplicate_check'])) {
|
||||
enforceUserPermission('module_client', 2);
|
||||
|
||||
$name = sanitizeInput($_GET['name']);
|
||||
|
||||
$response['message'] = ""; // default
|
||||
|
||||
if (strlen($name) >= 5) {
|
||||
$sql_clients = mysqli_query($mysqli, "SELECT client_name FROM clients
|
||||
WHERE client_archived_at IS NULL
|
||||
AND client_name LIKE '%$name%'
|
||||
ORDER BY client_id DESC LIMIT 1"
|
||||
);
|
||||
|
||||
if (mysqli_num_rows($sql_clients) > 0) {
|
||||
while ($row = mysqli_fetch_array($sql_clients)) {
|
||||
$response['message'] = "<i class='fas fa-fw fa-copy mr-2'></i> Potential duplicate: <i>" . nullable_htmlentities($row['client_name']) . "</i> already exists.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode($response);
|
||||
}
|
||||
|
||||
if (isset($_GET['contact_email_check'])) {
|
||||
enforceUserPermission('module_client', 2);
|
||||
|
||||
$email = sanitizeInput($_GET['email']);
|
||||
$domain = sanitizeInput(substr($_GET['email'], strpos($_GET['email'], '@') + 1));
|
||||
|
||||
$response['message'] = ""; // default
|
||||
|
||||
if (strlen($email) >= 3) {
|
||||
|
||||
// 1. Duplicate check
|
||||
$sql_contacts = mysqli_query($mysqli, "SELECT contact_email FROM contacts WHERE contact_email = '$email' LIMIT 1");
|
||||
if (mysqli_num_rows($sql_contacts) > 0) {
|
||||
while ($row = mysqli_fetch_array($sql_contacts)) {
|
||||
$response['message'] = "<i class='fas fa-fw fa-copy mr-2'></i> Potential duplicate: <i>" . nullable_htmlentities($row['contact_email']) . "</i> already exists.";
|
||||
}
|
||||
}
|
||||
|
||||
// 2. MX record check
|
||||
if (!checkdnsrr($domain, 'MX')) {
|
||||
$response['message'] = "<i class='fas fa-fw fa-exclamation-triangle mr-2'></i> E-mail domain invalid.";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
echo json_encode($response);
|
||||
}
|
||||
|
||||
if (isset($_GET['ai_reword'])) {
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id WHERE ai_model_use_case = 'General' LIMIT 1");
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$model_name = $row['ai_model_name'];
|
||||
$promptText = $row['ai_model_prompt'];
|
||||
$url = $row['ai_provider_api_url'];
|
||||
$key = $row['ai_provider_api_key'];
|
||||
|
||||
// Collecting the input data from the AJAX request.
|
||||
$inputJSON = file_get_contents('php://input');
|
||||
$input = json_decode($inputJSON, TRUE); // Convert JSON into array.
|
||||
|
||||
$userText = $input['text'];
|
||||
|
||||
// Preparing the data for the OpenAI Chat API request.
|
||||
$data = [
|
||||
"model" => "$model_name", // Specify the model
|
||||
"messages" => [
|
||||
["role" => "system", "content" => $promptText],
|
||||
["role" => "user", "content" => $userText],
|
||||
],
|
||||
"temperature" => 0.5
|
||||
];
|
||||
|
||||
// Initialize cURL session to the OpenAI Chat API.
|
||||
$ch = curl_init("$url");
|
||||
|
||||
// Set cURL options for the request.
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/json',
|
||||
'Authorization: Bearer ' . $key,
|
||||
]);
|
||||
|
||||
// Execute the cURL session and capture the response.
|
||||
$response = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
// Decode the JSON response.
|
||||
$responseData = json_decode($response, true);
|
||||
|
||||
// Check if the response contains the expected data and return it.
|
||||
if (isset($responseData['choices'][0]['message']['content'])) {
|
||||
// Get the response content.
|
||||
$content = $responseData['choices'][0]['message']['content'];
|
||||
|
||||
// Clean any leading "html" word or other unwanted text at the beginning.
|
||||
$content = preg_replace('/^html/i', '', $content); // Remove any occurrence of 'html' at the start
|
||||
|
||||
// Clean the response content to remove backticks or code block markers.
|
||||
$cleanedContent = str_replace('```', '', $content); // Remove backticks if they exist.
|
||||
|
||||
// Trim any leading/trailing whitespace.
|
||||
$cleanedContent = trim($cleanedContent);
|
||||
|
||||
// Return the cleaned response.
|
||||
echo json_encode(['rewordedText' => $cleanedContent]);
|
||||
} else {
|
||||
// Handle errors or unexpected response structure.
|
||||
echo json_encode(['rewordedText' => 'Failed to get a response from the AI API.']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['ai_create_document_template'])) {
|
||||
// get_ai_document_template.php
|
||||
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id WHERE ai_model_use_case = 'General' LIMIT 1");
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$model_name = $row['ai_model_name'];
|
||||
$url = $row['ai_provider_api_url'];
|
||||
$key = $row['ai_provider_api_key'];
|
||||
|
||||
$prompt = $_POST['prompt'] ?? '';
|
||||
|
||||
// Basic validation
|
||||
if(empty($prompt)){
|
||||
echo "No prompt provided.";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Prepare prompt
|
||||
$system_message = "You are a helpful IT documentation assistant. You will create a well-structured HTML template for IT documentation based on a given prompt. Include headings, subheadings, bullet points, and possibly tables for clarity. No Lorem Ipsum, use realistic placeholders and professional language.";
|
||||
$user_message = "Create an HTML formatted IT documentation template based on the following request:\n\n\"$prompt\"\n\nThe template should be structured, professional, and useful for IT staff. Include relevant sections, instructions, prerequisites, and best practices.";
|
||||
|
||||
$post_data = [
|
||||
"model" => "$model_name",
|
||||
"messages" => [
|
||||
["role" => "system", "content" => $system_message],
|
||||
["role" => "user", "content" => $user_message]
|
||||
],
|
||||
"temperature" => 0.5
|
||||
];
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/json',
|
||||
'Authorization: Bearer ' . $key
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
|
||||
|
||||
$response = curl_exec($ch);
|
||||
if (curl_errno($ch)) {
|
||||
echo "Error: " . curl_error($ch);
|
||||
exit;
|
||||
}
|
||||
curl_close($ch);
|
||||
|
||||
$response_data = json_decode($response, true);
|
||||
$template = $response_data['choices'][0]['message']['content'] ?? "<p>No content returned from AI.</p>";
|
||||
|
||||
// Print the generated HTML template directly
|
||||
echo $template;
|
||||
}
|
||||
|
||||
if (isset($_GET['ai_ticket_summary'])) {
|
||||
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id WHERE ai_model_use_case = 'General' LIMIT 1");
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$model_name = $row['ai_model_name'];
|
||||
$url = $row['ai_provider_api_url'];
|
||||
$key = $row['ai_provider_api_key'];
|
||||
|
||||
// Retrieve the ticket_id from POST
|
||||
$ticket_id = intval($_POST['ticket_id']);
|
||||
|
||||
// Query the database for ticket details
|
||||
$sql = mysqli_query($mysqli, "
|
||||
SELECT ticket_subject, ticket_details, ticket_source, ticket_priority, ticket_status_name, category_name
|
||||
FROM tickets
|
||||
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
|
||||
LEFT JOIN categories ON ticket_category = category_id
|
||||
WHERE ticket_id = $ticket_id
|
||||
LIMIT 1
|
||||
");
|
||||
$row = mysqli_fetch_assoc($sql);
|
||||
$ticket_subject = $row['ticket_subject'];
|
||||
$ticket_details = strip_tags($row['ticket_details']); // strip HTML for cleaner prompt
|
||||
$ticket_status = $row['ticket_status_name'];
|
||||
$ticket_category = $row['category_name'];
|
||||
$ticket_source = $row['ticket_source'];
|
||||
$ticket_priority = $row['ticket_priority'];
|
||||
|
||||
// Get ticket replies
|
||||
$sql_replies = mysqli_query($mysqli, "
|
||||
SELECT ticket_reply, ticket_reply_type, user_name
|
||||
FROM ticket_replies
|
||||
LEFT JOIN users ON ticket_reply_by = user_id
|
||||
WHERE ticket_reply_ticket_id = $ticket_id
|
||||
AND ticket_reply_archived_at IS NULL
|
||||
ORDER BY ticket_reply_id ASC
|
||||
");
|
||||
|
||||
$all_replies_text = "";
|
||||
while ($reply = mysqli_fetch_assoc($sql_replies)) {
|
||||
$reply_type = $reply['ticket_reply_type'];
|
||||
$reply_text = strip_tags($reply['ticket_reply']);
|
||||
$reply_by = $reply['user_name'];
|
||||
$all_replies_text .= "\nReply Type: $reply_type Reply By: $reply_by: Reply Text: $reply_text";
|
||||
}
|
||||
|
||||
$prompt = "
|
||||
Summarize the following IT support ticket and its responses in a concise, clear, and professional manner.
|
||||
The summary should include:
|
||||
|
||||
1. Main Issue: What was the problem reported by the user?
|
||||
2. Actions Taken: What steps were taken to address the issue?
|
||||
3. Resolution or Next Steps: Was the issue resolved or is it ongoing?
|
||||
|
||||
Please ensure:
|
||||
- If there are multiple issues, summarize each separately.
|
||||
- Urgency: If the ticket or replies express urgency or escalation, highlight it.
|
||||
- Attachments: If mentioned in the ticket, note any relevant attachments or files.
|
||||
- Avoid extra explanations or unnecessary information.
|
||||
|
||||
Ticket Data:
|
||||
- Ticket Source: $ticket_source
|
||||
- Current Ticket Status: $ticket_status
|
||||
- Ticket Priority: $ticket_priority
|
||||
- Ticket Category: $ticket_category
|
||||
- Ticket Subject: $ticket_subject
|
||||
- Ticket Details: $ticket_details
|
||||
- Replies:
|
||||
$all_replies_text
|
||||
|
||||
Formatting instructions:
|
||||
- Use valid HTML tags only.
|
||||
- Use <h3> for section headers (Main Issue, Actions Taken, Resolution).
|
||||
- Use <ul><li> for bullet points under each section.
|
||||
- Do NOT wrap the output in ```html or any other code fences.
|
||||
- Do NOT include <html>, <head>, or <body>.
|
||||
- Output only the summary content in pure HTML.
|
||||
If any part of the ticket or replies is unclear or ambiguous, mention it in the summary and suggest if further clarification is needed.
|
||||
";
|
||||
|
||||
// Prepare the POST data
|
||||
$post_data = [
|
||||
"model" => "$model_name",
|
||||
"messages" => [
|
||||
["role" => "system", "content" => "Your task is to summarize IT support tickets with clear, concise details."],
|
||||
["role" => "user", "content" => $prompt]
|
||||
],
|
||||
"temperature" => 0.3
|
||||
];
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/json',
|
||||
'Authorization: Bearer ' . $key
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
|
||||
|
||||
$response = curl_exec($ch);
|
||||
if (curl_errno($ch)) {
|
||||
echo "Error: " . curl_error($ch);
|
||||
exit;
|
||||
}
|
||||
curl_close($ch);
|
||||
|
||||
$response_data = json_decode($response, true);
|
||||
$summary = $response_data['choices'][0]['message']['content'] ?? "No summary available.";
|
||||
|
||||
|
||||
echo $summary; // nl2br to convert newlines to <br>, htmlspecialchars to prevent XSS
|
||||
}
|
||||
|
||||
// Stops people trying to use sub-domains in the domains tracker
|
||||
if (isset($_GET['apex_domain_check'])) {
|
||||
enforceUserPermission('module_support', 2);
|
||||
|
||||
$domain = sanitizeInput($_GET['domain']);
|
||||
|
||||
$response['message'] = ""; // default
|
||||
|
||||
if (strlen($domain) >= 4) {
|
||||
|
||||
// SOA record check
|
||||
// This isn't 100%, as sub-domains can have their own SOA but will capture 99%
|
||||
if (!checkdnsrr($domain, 'SOA')) {
|
||||
$response['message'] = "<i class='fas fa-fw fa-exclamation-triangle mr-2'></i> Domain name is invalid.";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
echo json_encode($response);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
if (isset($_GET['client_id'])) {
|
||||
require_once "includes/inc_all_client.php";
|
||||
$client_query = "AND asset_client_id = $client_id";
|
||||
$client_url = "AND client_id=$client_id&";
|
||||
$client_url = "client_id=$client_id&";
|
||||
} else {
|
||||
require_once "includes/inc_client_overview_all.php";
|
||||
$client_query = '';
|
||||
@@ -21,8 +21,14 @@ if (isset($_GET['asset_id'])) {
|
||||
LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1
|
||||
WHERE asset_id = $asset_id
|
||||
$client_query
|
||||
LIMIT 1
|
||||
");
|
||||
|
||||
if (mysqli_num_rows($sql) == 0) {
|
||||
echo "<center><h1 class='text-secondary mt-5'>Nothing to see here</h1><a class='btn btn-lg btn-secondary mt-3' href='javascript:history.back()'><i class='fa fa-fw fa-arrow-left'></i> Go Back</a></center>";
|
||||
|
||||
} else {
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$client_id = intval($row['client_id']);
|
||||
$client_name = nullable_htmlentities($row['client_name']);
|
||||
@@ -355,23 +361,23 @@ if (isset($_GET['asset_id'])) {
|
||||
<div class="dropdown dropleft mr-2">
|
||||
<button type="button" class="btn btn-primary" data-toggle="dropdown"><i class="fas fa-plus mr-2"></i>New</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#addTicketModal">
|
||||
<a class="dropdown-item text-dark ajax-modal" href="#" data-modal-url="modals/ticket/ticket_add.php?<?= $client_url ?>&asset_id=<?= $asset_id ?>" data-modal-size="lg">
|
||||
<i class="fa fa-fw fa-life-ring mr-2"></i>New Ticket
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#addRecurringTicketModal">
|
||||
<a class="dropdown-item text-dark ajax-modal" href="#" data-modal-url="modals/recurring_ticket/recurring_ticket_add.php?<?= $client_url ?>&asset_id=<?= $asset_id ?>" data-modal-size="lg">
|
||||
<i class="fa fa-fw fa-recycle mr-2"></i>New Recurring Ticket
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#addCredentialModal">
|
||||
<a class="dropdown-item text-dark ajax-modal" href="#" data-modal-url="modals/credential/credential_add.php?<?= $client_url ?>asset_id=<?= $asset_id ?>">
|
||||
<i class="fa fa-fw fa-key mr-2"></i>New Credential
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#addDocumentModal">
|
||||
<a class="dropdown-item text-dark ajax-modal" href="#" data-modal-url="modals/document/document_add.php?<?= $client_url ?>&asset_id=<?= $asset_id ?>" data-modal-size="lg">
|
||||
<i class="fa fa-fw fa-file-alt mr-2"></i>New Document
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#uploadFilesModal">
|
||||
<a class="dropdown-item text-dark ajax-modal" href="#" data-modal-url="modals/file/file_upload.php?<?= $client_url ?>&asset_id=<?= $asset_id ?>">
|
||||
<i class="fa fa-fw fa-upload mr-2"></i>Upload file(s)
|
||||
</a>
|
||||
</div>
|
||||
@@ -413,7 +419,7 @@ if (isset($_GET['asset_id'])) {
|
||||
<h3 class="card-title mt-2"><i class="fa fa-fw fa-ethernet mr-2"></i>Interfaces</h3>
|
||||
<div class="card-tools">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addAssetInterfaceModal">
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/asset/asset_interface_add.php?&asset_id=<?= $asset_id ?>">
|
||||
<i class="fas fa-plus mr-2"></i>New Interface
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
|
||||
@@ -1001,7 +1007,7 @@ if (isset($_GET['asset_id'])) {
|
||||
<?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_recurring_ticket=<?= $recurring_ticket_id; ?>">
|
||||
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_recurring_ticket=<?= $recurring_ticket_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
|
||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||
</a>
|
||||
</div>
|
||||
@@ -1177,7 +1183,7 @@ if (isset($_GET['asset_id'])) {
|
||||
|
||||
?>
|
||||
|
||||
<script>
|
||||
<script>
|
||||
function updateAssetNotes(asset_id) {
|
||||
var notes = document.getElementById("assetNotes").value;
|
||||
|
||||
@@ -1191,10 +1197,10 @@ if (isset($_GET['asset_id'])) {
|
||||
}
|
||||
)
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
||||
<!-- JavaScript to Show/Hide Password Form Group -->
|
||||
<script>
|
||||
<!-- JavaScript to Show/Hide Password Form Group -->
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('.authMethod').on('change', function() {
|
||||
var $form = $(this).closest('.authForm');
|
||||
@@ -1206,23 +1212,18 @@ if (isset($_GET['asset_id'])) {
|
||||
});
|
||||
$('.authMethod').trigger('change');
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
|
||||
<!-- Include script to get TOTP code via the credential ID -->
|
||||
<script src="js/credential_show_otp_via_id.js"></script>
|
||||
<!-- Include script to get TOTP code via the credential ID -->
|
||||
<script src="js/credential_show_otp_via_id.js"></script>
|
||||
|
||||
<script src="../js/bulk_actions.js"></script>
|
||||
<script src="../js/bulk_actions.js"></script>
|
||||
|
||||
<?php
|
||||
<?php
|
||||
require_once "modals/asset/asset_interface_multiple_add.php";
|
||||
require_once "modals/asset/asset_interface_import.php";
|
||||
require_once "modals/asset/asset_interface_export.php";
|
||||
|
||||
require_once "modals/asset/asset_interface_add.php";
|
||||
require_once "modals/asset/asset_interface_multiple_add.php";
|
||||
require_once "modals/asset/asset_interface_import.php";
|
||||
require_once "modals/asset/asset_interface_export.php";
|
||||
require_once "modals/ticket/ticket_add.php";
|
||||
require_once "modals/recurring_ticket/recurring_ticket_add.php";
|
||||
require_once "modals/credential/credential_add.php";
|
||||
require_once "modals/document/document_add.php";
|
||||
require_once "modals/file/file_upload.php";
|
||||
}
|
||||
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
@@ -37,17 +37,23 @@ enforceUserPermission('module_support');
|
||||
//Asset Type from GET
|
||||
if (isset($_GET['type']) && ($_GET['type']) == 'workstation') {
|
||||
$type_query = "asset_type = 'desktop' OR asset_type = 'laptop'";
|
||||
$type_filter = "workstation";
|
||||
} elseif (isset($_GET['type']) && ($_GET['type']) == 'server') {
|
||||
$type_query = "asset_type = 'server'";
|
||||
$type_filter = "server";
|
||||
} elseif (isset($_GET['type']) && ($_GET['type']) == 'virtual') {
|
||||
$type_query = "asset_type = 'Virtual Machine'";
|
||||
$type_filter = "virtual";
|
||||
} elseif (isset($_GET['type']) && ($_GET['type']) == 'network') {
|
||||
$type_query = "asset_type = 'Firewall/Router' OR asset_type = 'Switch' OR asset_type = 'Access Point'";
|
||||
$type_filter = "network";
|
||||
} elseif (isset($_GET['type']) && ($_GET['type']) == 'other') {
|
||||
$type_query = "asset_type NOT LIKE 'laptop' AND asset_type NOT LIKE 'desktop' AND asset_type NOT LIKE 'server' AND asset_type NOT LIKE 'virtual machine' AND asset_type NOT LIKE 'firewall/router' AND asset_type NOT LIKE 'switch' AND asset_type NOT LIKE 'access point'";
|
||||
$type_filter = "other";
|
||||
} else {
|
||||
$type_query = "asset_type LIKE '%'";
|
||||
$_GET['type'] = '';
|
||||
$type_filter = '';
|
||||
}
|
||||
|
||||
if (!$client_url) {
|
||||
@@ -133,19 +139,6 @@ $sql = mysqli_query(
|
||||
|
||||
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
|
||||
|
||||
// OS typeahead suggestions
|
||||
$os_sql = mysqli_query($mysqli, "SELECT DISTINCT asset_os AS label FROM assets WHERE asset_archived_at IS NULL");
|
||||
if ($os_sql && mysqli_num_rows($os_sql) > 0) {
|
||||
$os_arr = [];
|
||||
while ($row = mysqli_fetch_assoc($os_sql)) {
|
||||
// jQuery UI Autocomplete expects {label: "...", value: "..."}
|
||||
$label = $row['label'];
|
||||
$os_arr[] = ['label' => $label, 'value' => $label];
|
||||
}
|
||||
$json_os = json_encode($os_arr);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<div class="col-sm-12 mb-3">
|
||||
@@ -185,8 +178,8 @@ if ($os_sql && mysqli_num_rows($os_sql) > 0) {
|
||||
<div class="card-tools">
|
||||
<?php if (lookupUserPermission("module_support") >= 2) { ?>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addAssetModal">
|
||||
<i class="fas fa-plus mr-2"></i>New <?php if (!empty($_GET['type'])) { echo ucwords(strip_tags(nullable_htmlentities($_GET['type']))); } else { echo "Asset"; } ?>
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/asset/asset_add.php?<?= $client_url ?>&type=<?= $type_filter ?>">
|
||||
<i class="fas fa-plus mr-2"></i>New <?php if ($type_filter) { echo ucwords($type_filter); } else { echo "Asset"; } ?>
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
|
||||
<div class="dropdown-menu">
|
||||
@@ -310,27 +303,40 @@ if ($os_sql && mysqli_num_rows($os_sql) > 0) {
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<?php if ($client_url) { ?>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkAssignContactModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/asset/asset_bulk_assign_contact.php?<?= $client_url ?>"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-user mr-2"></i>Assign Contact
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkAssignLocationModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/asset/asset_bulk_assign_location.php?<?= $client_url ?>"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-map-marker-alt mr-2"></i>Assign Location
|
||||
</a>
|
||||
<?php } ?>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkAssignPhysicalLocationModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/asset/asset_bulk_assign_physical_location.php"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-map-marker-alt mr-2"></i>Set Physical Location
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkEditStatusModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/asset/asset_bulk_edit_status.php"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-info mr-2"></i>Set Status
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkAddTicketModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/asset/asset_bulk_add_ticket.php"
|
||||
data-modal-size="lg"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-life-ring mr-2"></i>Create Tickets
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkTransferAssetClientModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/asset/asset_bulk_transfer_client.php?<?= $client_url ?>"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-arrow-right mr-2"></i>Transfer to Client
|
||||
</a>
|
||||
<?php if ($archived) { ?>
|
||||
@@ -699,16 +705,6 @@ if ($os_sql && mysqli_num_rows($os_sql) > 0) {
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
if ($client_url) {
|
||||
require_once "modals/asset/asset_bulk_assign_contact.php";
|
||||
require_once "modals/asset/asset_bulk_assign_location.php";
|
||||
}
|
||||
?>
|
||||
<?php require_once "modals/asset/asset_bulk_assign_physical_location.php"; ?>
|
||||
<?php require_once "modals/asset/asset_bulk_transfer_client.php"; ?>
|
||||
<?php require_once "modals/asset/asset_bulk_edit_status.php"; ?>
|
||||
<?php require_once "modals/asset/asset_bulk_add_ticket.php"; ?>
|
||||
</form>
|
||||
<?php require_once "../includes/filter_footer.php"; ?>
|
||||
</div>
|
||||
@@ -716,24 +712,7 @@ if ($os_sql && mysqli_num_rows($os_sql) > 0) {
|
||||
|
||||
<script src="../js/bulk_actions.js"></script>
|
||||
|
||||
<!-- JSON Autocomplete / type ahead -->
|
||||
<link rel="stylesheet" href="../plugins/jquery-ui/jquery-ui.min.css">
|
||||
<script src="../plugins/jquery-ui/jquery-ui.min.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
var operatingSystems = <?php echo $json_os; ?>;
|
||||
$("#os").autocomplete({
|
||||
source: operatingSystems, // Should be an array of objects with 'label' and 'value'
|
||||
select: function(event, ui) {
|
||||
$("#os").val(ui.item.label); // Set the input field value to the selected label
|
||||
return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php
|
||||
require_once "modals/asset/asset_add.php";
|
||||
require_once "modals/asset/asset_export.php";
|
||||
if ($client_url) {
|
||||
require_once "modals/asset/asset_import.php";
|
||||
|
||||
113
agent/budget.php
113
agent/budget.php
@@ -1,113 +0,0 @@
|
||||
<?php
|
||||
|
||||
require_once "includes/inc_all.php";
|
||||
|
||||
// Perms
|
||||
enforceUserPermission('module_financial');
|
||||
|
||||
// Fetch categories
|
||||
$query = "SELECT category_id, category_name FROM categories WHERE category_type ='Expense' AND category_archived_at IS NULL";
|
||||
$result = mysqli_query($mysqli, $query);
|
||||
$categories = [];
|
||||
while($row = mysqli_fetch_assoc($result)) {
|
||||
$categories[] = $row;
|
||||
}
|
||||
|
||||
// Fetch years with budget
|
||||
$query = "SELECT DISTINCT budget_year FROM budget ORDER BY budget_year ASC";
|
||||
$result = mysqli_query($mysqli, $query);
|
||||
$years = [];
|
||||
while ($row = mysqli_fetch_assoc($result)) {
|
||||
$years[] = $row['budget_year'];
|
||||
}
|
||||
|
||||
// Fetch current year budgets
|
||||
$currentYear = date("Y");
|
||||
if (isset($_GET['year'])) {
|
||||
$currentYear = intval($_GET['year']);
|
||||
}
|
||||
|
||||
$query = "SELECT * FROM budget WHERE budget_year = $currentYear";
|
||||
$result = mysqli_query($mysqli, $query);
|
||||
$budgets = [];
|
||||
while ($row = mysqli_fetch_assoc($result)) {
|
||||
$budgets[] = $row;
|
||||
}
|
||||
|
||||
$months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
||||
$columnTotals = array_fill(0, 12, 0);
|
||||
$grandTotal = 0;
|
||||
|
||||
?>
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-balance-scale mr-2"></i>Budget for <span id="currentYear"><?php echo $currentYear; ?></span></h3>
|
||||
<div class="card-tools">
|
||||
<a href="budget_edit.php" class="btn btn-primary">
|
||||
<i class="fas fa-edit mr-2"></i>Edit Budget
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="yearForm" method="GET" action="budget.php">
|
||||
<div class="form-group">
|
||||
<select class="form-control" name="year" id="yearSelect" onchange="submit();">
|
||||
<?php foreach ($years as $year): ?>
|
||||
<option value="<?php echo $year; ?>" <?php if ($year == $currentYear) { echo 'selected'; } ?>><?php echo $year; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
<table class="table table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Expense</th>
|
||||
<?php foreach ($months as $month): ?>
|
||||
<th><?php echo $month; ?></th>
|
||||
<?php endforeach; ?>
|
||||
<th>Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($categories as $category): ?>
|
||||
<tr>
|
||||
<td><?php echo nullable_htmlentities($category['category_name']); ?></td>
|
||||
<?php
|
||||
$rowTotal = 0;
|
||||
foreach ($months as $index => $month):
|
||||
$amount = getBudgetAmount($budgets, $category['category_id'], $index + 1);
|
||||
$rowTotal += $amount;
|
||||
$columnTotals[$index] += $amount;
|
||||
?>
|
||||
<td><?php echo $amount; ?></td>
|
||||
<?php endforeach; ?>
|
||||
<td><?php echo $rowTotal; ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
$grandTotal += $rowTotal;
|
||||
endforeach; ?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th>Total</th>
|
||||
<?php foreach ($columnTotals as $total): ?>
|
||||
<th><?php echo $total; ?></th>
|
||||
<?php endforeach; ?>
|
||||
<th><?php echo $grandTotal; ?></th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
function getBudgetAmount($budgets, $categoryId, $month) {
|
||||
foreach ($budgets as $budget) {
|
||||
if ($budget['budget_category_id'] == $categoryId && $budget['budget_month'] == $month) {
|
||||
return intval($budget['budget_amount']);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
require_once "../includes/footer.php";
|
||||
?>
|
||||
@@ -1,114 +0,0 @@
|
||||
<?php
|
||||
|
||||
require_once "includes/inc_all.php";
|
||||
|
||||
enforceUserPermission('module_financial', 2);
|
||||
|
||||
// Fetch categories
|
||||
$query = "SELECT category_id, category_name FROM categories WHERE category_type ='Expense' AND category_archived_at IS NULL";
|
||||
$result = mysqli_query($mysqli, $query);
|
||||
$categories = [];
|
||||
while($row = mysqli_fetch_assoc($result)) {
|
||||
$categories[] = $row;
|
||||
}
|
||||
|
||||
// Fetch current year budgets
|
||||
$currentYear = date("Y");
|
||||
if(isset($_GET['year'])) {
|
||||
$currentYear = intval($_GET['year']);
|
||||
}
|
||||
|
||||
$query = "SELECT * FROM budget WHERE budget_year = $currentYear";
|
||||
$result = mysqli_query($mysqli, $query);
|
||||
$budgets = [];
|
||||
while($row = mysqli_fetch_assoc($result)) {
|
||||
$budgets[] = $row;
|
||||
}
|
||||
|
||||
$months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
||||
$columnTotals = array_fill(0, 12, 0);
|
||||
$grandTotal = 0;
|
||||
|
||||
?>
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-balance-scale mr-2"></i>Editing Budget for <span id="currentYear"><?php echo $currentYear; ?></span></h3>
|
||||
<div class="card-tools">
|
||||
<a href="budget.php" class="btn btn-default text-dark">
|
||||
<i class="fas fa-eye mr-2"></i>View Budget
|
||||
</a>
|
||||
<button type="submit" name="save_budget" form="budgetForm" class="btn btn-primary"><i class="fas fa-fw fa-check mr-2"></i>Save Budget</button>
|
||||
<button type="submit" name="delete_budget" form="budgetForm" class="btn btn-danger"><i class="fas fa-fw fa-trash mr-2"></i>Delete Budget</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<form id="yearForm" method="GET" action="budget.php">
|
||||
<div class="form-group">
|
||||
<select class="form-control" name="year" id="yearSelect" onchange="submit();">
|
||||
<?php for ($i = $currentYear - 10; $i <= $currentYear + 5; $i++): ?>
|
||||
<option value="<?php echo $i; ?>" <?php if ($i == $currentYear) echo 'selected'; ?>><?php echo $i; ?></option>
|
||||
<?php endfor; ?>
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
<form id="budgetForm" method="POST" action="post.php">
|
||||
<input type="hidden" name="year" value="<?php echo $currentYear; ?>">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
|
||||
<table class="table table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Expense</th>
|
||||
<?php foreach ($months as $month): ?>
|
||||
<th><?php echo $month; ?></th>
|
||||
<?php endforeach; ?>
|
||||
<th>Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($categories as $category): ?>
|
||||
<tr>
|
||||
<td><?php echo nullable_htmlentities($category['category_name']); ?></td>
|
||||
<?php
|
||||
$rowTotal = 0;
|
||||
foreach ($months as $index => $month):
|
||||
$amount = getBudgetAmount($budgets, $category['category_id'], $index + 1);
|
||||
$rowTotal += $amount;
|
||||
$columnTotals[$index] += $amount;
|
||||
?>
|
||||
<td><input type='text' inputmode='numeric' pattern='[0-9]*' class="form-control" name="budget[<?php echo intval($category['category_id']); ?>][<?php echo $index + 1; ?>]" value="<?php echo $amount; ?>"></td>
|
||||
<?php endforeach; ?>
|
||||
<td><?php echo $rowTotal; ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
$grandTotal += $rowTotal;
|
||||
endforeach; ?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th>Total</th>
|
||||
<?php foreach ($columnTotals as $total): ?>
|
||||
<th><?php echo $total; ?></th>
|
||||
<?php endforeach; ?>
|
||||
<th><?php echo $grandTotal; ?></th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<?php
|
||||
function getBudgetAmount($budgets, $categoryId, $month) {
|
||||
foreach ($budgets as $budget) {
|
||||
if ($budget['budget_category_id'] == $categoryId && $budget['budget_month'] == $month) {
|
||||
return intval($budget['budget_amount']);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
require_once "../includes/footer.php";
|
||||
?>
|
||||
@@ -33,7 +33,7 @@ if (isset($_GET['calendar_id'])) {
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-1">Calendars</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-dark btn-sm" data-toggle="modal" data-target="#addCalendarModal"><i class="fas fa-plus"></i></button>
|
||||
<button type="button" class="btn btn-dark btn-sm ajax-modal" data-modal-url="modals/calendar/calendar_add.php"><i class="fas fa-plus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@@ -82,8 +82,6 @@ if (isset($_GET['calendar_id'])) {
|
||||
<?php
|
||||
|
||||
require_once "modals/calendar/calendar_event_add.php";
|
||||
require_once "modals/calendar/calendar_add.php";
|
||||
|
||||
|
||||
//loop through IDs and create a modal for each
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM calendar_events LEFT JOIN calendars ON event_calendar_id = calendar_id $client_event_query");
|
||||
|
||||
@@ -64,7 +64,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-lock mr-2"></i>Certificates</h3>
|
||||
<div class="card-tools">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addCertificateModal"><i class="fas fa-plus mr-2"></i>New Certificate</button>
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/certificate/certificate_add.php?<?= $client_url ?>"><i class="fas fa-plus mr-2"></i>New Certificate</button>
|
||||
<?php if ($num_rows[0] > 0) { ?>
|
||||
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
|
||||
<div class="dropdown-menu">
|
||||
@@ -249,8 +249,10 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<td><?php echo $certificate_issued_by; ?></td>
|
||||
|
||||
<td>
|
||||
<div><?php echo $certificate_expire; ?></div>
|
||||
<div><?php echo $certificate_expire ?: '-'; ?></div>
|
||||
<?php if (!empty($certificate_expire)) { ?>
|
||||
<div><small><?php echo $certificate_expire_ago; ?></small></div>
|
||||
<?php } ?>
|
||||
</td>
|
||||
<?php if (!$client_url) { ?>
|
||||
<td><a href="certificates.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
|
||||
@@ -303,11 +305,9 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "modals/certificate/certificate_add.php";
|
||||
require_once "modals/certificate/certificate_export.php";
|
||||
?>
|
||||
|
||||
<script src="../js/bulk_actions.js"></script>
|
||||
<script src="js/certificate_fetch_ssl.js"></script>
|
||||
|
||||
<?php require_once "../includes/footer.php";
|
||||
@@ -86,7 +86,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<div class="card-tools">
|
||||
<?php if (lookupUserPermission("module_client") >= 2) { ?>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addClientModal">
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/client/client_add.php<?php if ($leads_filter) { echo "?lead=1"; } ?>">
|
||||
<i class="fas fa-plus mr-2"></i>New
|
||||
<?php if ($leads_filter == 0) { echo "Client"; } else { echo "Lead"; } ?>
|
||||
</button>
|
||||
@@ -137,23 +137,41 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<i class="fas fa-fw fa-layer-group"></i><span class="d-none d-sm-inline ml-2">Action</span> (<span id="selectedCount">0</span>)
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkEditHourlyRateModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/client/client_bulk_add_ticket.php"
|
||||
data-modal-size="lg"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-life-ring mr-2"></i>Open Tickets
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/client/client_bulk_edit_hourly_rate.php"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-clock mr-2"></i>Set Hourly Rate
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkEditIndustryModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/client/client_bulk_edit_industry.php"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-briefcase mr-2"></i>Set Industry
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkEditReferralModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/client/client_bulk_edit_referral.php"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-link mr-2"></i>Set Referral
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkAssignTagsModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/client/client_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" href="#" data-toggle="modal" data-target="#bulkSendEmailModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/client/client_bulk_email.php"
|
||||
data-modal-size="lg"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-paper-plane mr-2"></i>Send Email
|
||||
</a>
|
||||
<?php if ($archived) { ?>
|
||||
@@ -178,49 +196,27 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<div
|
||||
class="collapse
|
||||
<?php
|
||||
if (
|
||||
isset($_GET['dtf'])
|
||||
if (isset($_GET['dtf']) && $_GET['dtf'] !== '1970-01-01'
|
||||
|| $industry_filter
|
||||
|| $referral_filter
|
||||
|| (isset($_GET['tags']) && is_array($_GET['tags']))
|
||||
|| $_GET['canned_date'] !== "custom" )
|
||||
{
|
||||
echo "show";
|
||||
}
|
||||
)
|
||||
{ echo "show"; }
|
||||
?>
|
||||
"
|
||||
id="advancedFilter"
|
||||
>
|
||||
<div class="row">
|
||||
<div class="col-md-2">
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>Canned date</label>
|
||||
<select onchange="this.form.submit()" class="form-control select2" name="canned_date">
|
||||
<option <?php if ($_GET['canned_date'] == "custom") { echo "selected"; } ?> value="custom">Custom</option>
|
||||
<option <?php if ($_GET['canned_date'] == "today") { echo "selected"; } ?> value="today">Today</option>
|
||||
<option <?php if ($_GET['canned_date'] == "yesterday") { echo "selected"; } ?> value="yesterday">Yesterday</option>
|
||||
<option <?php if ($_GET['canned_date'] == "thisweek") { echo "selected"; } ?> value="thisweek">This Week</option>
|
||||
<option <?php if ($_GET['canned_date'] == "lastweek") { echo "selected"; } ?> value="lastweek">Last Week</option>
|
||||
<option <?php if ($_GET['canned_date'] == "thismonth") { echo "selected"; } ?> value="thismonth">This Month</option>
|
||||
<option <?php if ($_GET['canned_date'] == "lastmonth") { echo "selected"; } ?> value="lastmonth">Last Month</option>
|
||||
<option <?php if ($_GET['canned_date'] == "thisyear") { echo "selected"; } ?> value="thisyear">This Year</option>
|
||||
<option <?php if ($_GET['canned_date'] == "lastyear") { echo "selected"; } ?> value="lastyear">Last Year</option>
|
||||
</select>
|
||||
<label>Date range</label>
|
||||
<input type="text" id="dateFilter" class="form-control" autocomplete="off">
|
||||
<input type="hidden" name="canned_date" id="canned_date" value="<?php echo nullable_htmlentities($_GET['canned_date']) ?? ''; ?>">
|
||||
<input type="hidden" name="dtf" id="dtf" value="<?php echo nullable_htmlentities($dtf ?? ''); ?>">
|
||||
<input type="hidden" name="dtt" id="dtt" value="<?php echo nullable_htmlentities($dtt ?? ''); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>Date from</label>
|
||||
<input onchange="this.form.submit()" type="date" class="form-control" name="dtf" max="2999-12-31" value="<?php echo nullable_htmlentities($dtf); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>Date to</label>
|
||||
<input onchange="this.form.submit()" type="date" class="form-control" name="dtt" max="2999-12-31" value="<?php echo nullable_htmlentities($dtt); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>Tag</label>
|
||||
<select onchange="this.form.submit()" class="form-control select2" name="tags[]" data-placeholder="- Select Tags -" multiple>
|
||||
@@ -286,7 +282,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<form id="bulkActions" action="post.php" method="post" enctype="multipart/form-data">
|
||||
<form id="bulkActions" action="post.php" method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-hover mb-0 text-nowrap">
|
||||
@@ -618,13 +614,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
require_once "modals/client/client_bulk_edit_industry.php";
|
||||
require_once "modals/client/client_bulk_edit_referral.php";
|
||||
require_once "modals/client/client_bulk_edit_hourly_rate.php";
|
||||
require_once "modals/client/client_bulk_assign_tags.php";
|
||||
require_once "modals/client/client_bulk_email.php";
|
||||
?>
|
||||
</form>
|
||||
<!-- Ends Card Body -->
|
||||
<?php require_once "../includes/filter_footer.php"; ?>
|
||||
@@ -634,7 +623,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<script src="../js/bulk_actions.js"></script>
|
||||
|
||||
<?php
|
||||
require_once "modals/client/client_add.php";
|
||||
require_once "modals/client/client_import.php";
|
||||
require_once "modals/client/client_export.php";
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
@@ -20,8 +20,15 @@ if (isset($_GET['contact_id'])) {
|
||||
LEFT JOIN users ON user_id = contact_user_id
|
||||
WHERE contact_id = $contact_id
|
||||
$client_query
|
||||
LIMIT 1
|
||||
");
|
||||
|
||||
if (mysqli_num_rows($sql) == 0) {
|
||||
echo "<center><h1 class='text-secondary mt-5'>Nothing to see here</h1><a class='btn btn-lg btn-secondary mt-3' href='javascript:history.back()'><i class='fa fa-fw fa-arrow-left'></i> Go Back</a></center>";
|
||||
require_once "../includes/footer.php";
|
||||
exit();
|
||||
}
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$client_id = intval($row['client_id']);
|
||||
$client_name = nullable_htmlentities($row['client_name']);
|
||||
@@ -255,27 +262,27 @@ if (isset($_GET['contact_id'])) {
|
||||
<div class="dropdown dropleft mr-2">
|
||||
<button type="button" class="btn btn-primary" data-toggle="dropdown"><i class="fas fa-plus mr-2"></i>New</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#addTicketModal">
|
||||
<a class="dropdown-item text-dark ajax-modal" href="#" data-modal-url="modals/ticket/ticket_add.php?<?= $client_url ?>&contact_id=<?= $contact_id ?>" data-modal-size="lg">
|
||||
<i class="fa fa-fw fa-life-ring mr-2"></i>New Ticket
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#addRecurringTicketModal">
|
||||
<a class="dropdown-item text-dark ajax-modal" href="#" data-modal-url="modals/recurring_ticket/recurring_ticket_add.php?<?= $client_url ?>&contact_id=<?= $contact_id ?>" data-modal-size="lg">
|
||||
<i class="fa fa-fw fa-recycle mr-2"></i>New Recurring Ticket
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#addAssetModal">
|
||||
<a class="dropdown-item text-dark ajax-modal" href="#" data-modal-url="modals/asset/asset_add.php?<?= $client_url ?>&contact_id=<?= $contact_id ?>">
|
||||
<i class="fa fa-fw fa-desktop mr-2"></i>New Asset
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#addCredentialModal">
|
||||
<a class="dropdown-item text-dark ajax-modal" href="#" data-modal-url="modals/credential/credential_add.php?<?= $client_url ?>&contact_id=<?= $contact_id ?>">
|
||||
<i class="fa fa-fw fa-key mr-2"></i>New Credential
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#addDocumentModal">
|
||||
<a class="dropdown-item text-dark ajax-modal" href="#" data-modal-url="modals/document/document_add.php?<?= $client_url ?>&contact_id=<?= $contact_id ?>" data-modal-size="lg">
|
||||
<i class="fa fa-fw fa-file-alt mr-2"></i>New Document
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#uploadFilesModal">
|
||||
<a class="dropdown-item text-dark ajax-modal" href="#" data-modal-url="modals/file/file_upload.php?<?= $client_url ?>&contact_id=<?= $contact_id ?>">
|
||||
<i class="fa fa-fw fa-upload mr-2"></i>Upload file(s)
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
@@ -1172,12 +1179,4 @@ if (isset($_GET['contact_id'])) {
|
||||
<script src="js/credential_show_otp_via_id.js"></script>
|
||||
|
||||
<?php
|
||||
|
||||
require_once "modals/ticket/ticket_add.php";
|
||||
require_once "modals/recurring_ticket/recurring_ticket_add.php";
|
||||
require_once "modals/asset/asset_add.php";
|
||||
require_once "modals/credential/credential_add.php";
|
||||
require_once "modals/document/document_add.php";
|
||||
require_once "modals/file/file_upload.php";
|
||||
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
@@ -90,7 +90,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<h3 class="card-title mt-2"><i class="fa fa-fw fa-address-book mr-2"></i>Contacts</h3>
|
||||
<div class="card-tools">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addContactModal">
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/contact/contact_add.php?client_id=<?= $client_id ?>">
|
||||
<i class="fas fa-plus mr-2"></i>New Contact
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
|
||||
@@ -220,28 +220,41 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<?php if ($client_url) { ?>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkAssignLocationModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/contact/contact_bulk_assign_location.php?<?= $client_url ?>"
|
||||
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" href="#" data-toggle="modal" data-target="#bulkEditPhoneModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/contact/contact_bulk_edit_phone.php"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-phone-alt mr-2"></i>Set Phone Number
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkEditDepartmentModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/contact/contact_bulk_edit_department.php"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-users mr-2"></i>Set Department
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkEditRoleModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/contact/contact_bulk_edit_role.php"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-user-shield mr-2"></i>Set Roles
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkAssignTagsModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/contact/contact_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" href="#" data-toggle="modal" data-target="#bulkSendEmailModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/contact/contact_bulk_email.php"
|
||||
data-modal-size="lg"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-paper-plane mr-2"></i>Send Email
|
||||
</a>
|
||||
<?php if ($archived) { ?>
|
||||
@@ -545,63 +558,18 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php if ($client_url) { require_once "modals/contact/contact_bulk_assign_location.php"; } ?>
|
||||
<?php require_once "modals/contact/contact_bulk_edit_phone.php"; ?>
|
||||
<?php require_once "modals/contact/contact_bulk_edit_department.php"; ?>
|
||||
<?php require_once "modals/contact/contact_bulk_edit_role.php"; ?>
|
||||
<?php require_once "modals/contact/contact_bulk_assign_tags.php"; ?>
|
||||
<?php require_once "modals/contact/contact_bulk_email.php"; ?>
|
||||
</form>
|
||||
<?php require_once "../includes/filter_footer.php";
|
||||
?>
|
||||
<?php require_once "../includes/filter_footer.php"; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- JavaScript to Show/Hide Password Form Group -->
|
||||
<script>
|
||||
|
||||
function generatePassword(type, id) {
|
||||
// Send a GET request to ajax.php as ajax.php?get_readable_pass=true
|
||||
jQuery.get(
|
||||
"ajax.php", {
|
||||
get_readable_pass: 'true'
|
||||
},
|
||||
function(data) {
|
||||
//If we get a response from post.php, parse it as JSON
|
||||
const password = JSON.parse(data);
|
||||
|
||||
// Set the password value to the correct modal, based on the type
|
||||
if (type == "add") {
|
||||
document.getElementById("password-add").value = password;
|
||||
} else if (type == "edit") {
|
||||
document.getElementById("password-edit-"+id.toString()).value = password;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$('.authMethod').on('change', function() {
|
||||
var $form = $(this).closest('.authForm');
|
||||
if ($(this).val() === 'local') {
|
||||
$form.find('.passwordGroup').show();
|
||||
} else {
|
||||
$form.find('.passwordGroup').hide();
|
||||
}
|
||||
});
|
||||
$('.authMethod').trigger('change');
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
<script src="../js/bulk_actions.js"></script>
|
||||
|
||||
<?php
|
||||
|
||||
require_once "modals/contact/contact_add.php";
|
||||
require_once "modals/contact/contact_export.php";
|
||||
if ($client_url) {
|
||||
require_once "modals/contact/contact_invite.php";
|
||||
//require_once "modals/contact/contact_invite.php";
|
||||
require_once "modals/contact/contact_import.php";
|
||||
}
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
@@ -106,7 +106,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<div class="card-tools">
|
||||
<?php if (lookupUserPermission("module_credential") >= 2) { ?>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addCredentialModal" <?php if (!isset($_COOKIE['user_encryption_session_key'])) { echo "disabled"; } ?>>
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/credential/credential_add.php?<?= $client_url ?>" <?php if (!isset($_COOKIE['user_encryption_session_key'])) { echo "disabled"; } ?>>
|
||||
<i class="fas fa-plus mr-2"></i>New Credential
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
|
||||
@@ -241,7 +241,9 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||
</button>
|
||||
<?php } else { ?>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkAssignTagsModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/credential/credential_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>
|
||||
@@ -519,10 +521,8 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php require_once "modals/credential/credential_bulk_assign_tags.php"; ?>
|
||||
</form>
|
||||
<?php require_once "../includes/filter_footer.php";
|
||||
?>
|
||||
<?php require_once "../includes/filter_footer.php"; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -534,7 +534,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
|
||||
<?php
|
||||
|
||||
require_once "modals/credential/credential_add.php";
|
||||
require_once "modals/credential/credential_export.php";
|
||||
if ($client_url) {
|
||||
require_once "modals/credential/credential_import.php";
|
||||
|
||||
@@ -660,7 +660,7 @@ if ($user_config_dashboard_technical_enable == 1) {
|
||||
<a class="small-box bg-warning" href="domains.php?sort=domain_expire&order=ASC">
|
||||
<div class="inner">
|
||||
<h3><?php echo $expiring_domains; ?></h3>
|
||||
<p>Expiring Domains</p>
|
||||
<p>Expiring Domains <small>30 Day</small></p>
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="fa fa-globe"></i>
|
||||
@@ -673,7 +673,7 @@ if ($user_config_dashboard_technical_enable == 1) {
|
||||
<a class="small-box bg-primary" href="certificates.php?sort=certificate_expire&order=ASC">
|
||||
<div class="inner">
|
||||
<h3><?php echo $expiring_certificates; ?></h3>
|
||||
<p>Expiring Certificates</p>
|
||||
<p>Expiring Certificates<small>30 Day</small></p>
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="fa fa-lock"></i>
|
||||
@@ -734,8 +734,8 @@ if ($user_config_dashboard_technical_enable == 1) {
|
||||
$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?ticket_id=<?php echo $ticket_id; ?>"><?php echo "$ticket_prefix$ticket_number"; ?></a></td>
|
||||
<td><a href="ticket.php?ticket_id=<?php echo $ticket_id; ?>"><?php echo $ticket_subject; ?></a></td>
|
||||
<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 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>
|
||||
|
||||
@@ -20,9 +20,16 @@ $folder_location = 0;
|
||||
$sql_document = mysqli_query($mysqli, "SELECT * FROM documents
|
||||
LEFT JOIN folders ON document_folder_id = folder_id
|
||||
LEFT JOIN users ON document_created_by = user_id
|
||||
WHERE document_client_id = $client_id AND document_id = $document_id"
|
||||
WHERE document_client_id = $client_id AND document_id = $document_id
|
||||
LIMIT 1"
|
||||
);
|
||||
|
||||
if (mysqli_num_rows($sql_document) == 0) {
|
||||
echo "<center><h1 class='text-secondary mt-5'>Nothing to see here</h1><a class='btn btn-lg btn-secondary mt-3' href='javascript:history.back()'><i class='fa fa-fw fa-arrow-left'></i> Go Back</a></center>";
|
||||
require_once "../includes/footer.php";
|
||||
exit();
|
||||
}
|
||||
|
||||
$row = mysqli_fetch_array($sql_document);
|
||||
|
||||
$folder_name = nullable_htmlentities($row['folder_name']);
|
||||
@@ -163,17 +170,19 @@ $page_title = $row['document_name'];
|
||||
<div class="col-md-3 d-print-none">
|
||||
<div class="row">
|
||||
<div class="col-12 mb-3">
|
||||
<button type="button" class="btn btn-primary ajax-modal mr-2"
|
||||
<button type="button" class="btn btn-primary ajax-modal mr-1"
|
||||
data-modal-size="lg"
|
||||
data-modal-url="modals/document/document_edit.php?id=<?= $document_id ?>">
|
||||
<i class="fas fa-fw fa-edit"></i>
|
||||
<i class="fas fa-fw fa-edit" title="Edit"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-secondary mr-2" data-toggle="modal" data-target="#shareModal"
|
||||
<button type="button" class="btn btn-secondary mr-1" data-toggle="modal" data-target="#shareModal"
|
||||
onclick="populateShareModal(<?php echo "$client_id, 'Document', $document_id"; ?>)">
|
||||
<i class="fas fa-fw fa-share"></i>
|
||||
<i class="fas fa-fw fa-share" title="Share"></i>
|
||||
</button>
|
||||
<a class="btn btn-success mr-2" href="post.php?export_document=<?php echo $document_id; ?>"><i class='fas fa-fw fa-file-pdf'></i></a>
|
||||
<button type="button" class="btn btn-secondary" onclick="window.print();"><i class="fas fa-fw fa-print"></i></button>
|
||||
<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>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card card-body bg-light">
|
||||
|
||||
@@ -92,12 +92,12 @@ while ($folder_id > 0) {
|
||||
<div class="card-tools">
|
||||
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addDocumentModal">
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/document/document_add.php?client_id=<?= $client_id ?>&folder_id=<?= $get_folder_id ?>" data-modal-size="lg">
|
||||
<i class="fas fa-plus mr-2"></i>New Document
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#createFolderModal">
|
||||
<a class="dropdown-item text-dark ajax-modal" href="#" data-modal-url="modals/folder/folder_add.php?client_id=<?= $client_id ?>&folder_location=0¤t_folder_id=<?= $get_folder_id ?>">
|
||||
<i class="fa fa-fw fa-folder-plus mr-2"></i>New Folder
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
@@ -130,7 +130,9 @@ while ($folder_id > 0) {
|
||||
<i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>)
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkMoveDocumentModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/document/document_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>
|
||||
@@ -276,7 +278,6 @@ while ($folder_id > 0) {
|
||||
display_folders(0, $client_id);
|
||||
?>
|
||||
</ul>
|
||||
<?php require_once "modals/folder/folder_add.php"; ?>
|
||||
</div>
|
||||
|
||||
<div class="col-md-9">
|
||||
@@ -466,10 +467,8 @@ while ($folder_id > 0) {
|
||||
</table>
|
||||
<br>
|
||||
</div>
|
||||
<?php require_once "modals/document/document_bulk_move.php"; ?>
|
||||
</form>
|
||||
<?php require_once "../includes/filter_footer.php";
|
||||
?>
|
||||
<?php require_once "../includes/filter_footer.php"; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -479,6 +478,5 @@ while ($folder_id > 0) {
|
||||
|
||||
<?php
|
||||
require_once "modals/share_modal.php";
|
||||
require_once "modals/document/document_add.php";
|
||||
require_once "modals/document/document_add_from_template.php";
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
@@ -76,7 +76,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<h3 class="card-title mt-2"><i class="fa fa-fw fa-globe mr-2"></i>Domains</h3>
|
||||
<div class="card-tools">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addDomainModal"><i class="fas fa-plus mr-2"></i>New Domain</button>
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/domain/domain_add.php?<?= $client_url ?>"><i class="fas fa-plus mr-2"></i>New Domain</button>
|
||||
<?php if ($num_rows[0] > 0) { ?>
|
||||
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
|
||||
<div class="dropdown-menu">
|
||||
@@ -307,8 +307,10 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<td><?php echo $domain_dnshost_name_display; ?></td>
|
||||
<td><?php echo $domain_mailhost_name_display; ?></td>
|
||||
<td>
|
||||
<div><?php echo $domain_expire; ?></div>
|
||||
<div><?php echo $domain_expire ?: '-'; ?></div>
|
||||
<?php if (!empty($domain_expire)) { ?>
|
||||
<div><small><?php echo $domain_expire_ago; ?></small></div>
|
||||
<?php } ?>
|
||||
</td>
|
||||
<?php if (!$client_url) { ?>
|
||||
<td><a href="domains.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
|
||||
@@ -361,7 +363,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "modals/domain/domain_add.php";
|
||||
require_once "modals/domain/domain_export.php";
|
||||
?>
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-shopping-cart mr-2"></i>Expenses</h3>
|
||||
<div class="card-tools">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addExpenseModal"><i class="fas fa-plus mr-2"></i>New Expense</button>
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/expense/expense_add.php" data-modal-size="lg"><i class="fas fa-plus mr-2"></i>New Expense</button>
|
||||
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#exportExpensesModal">
|
||||
@@ -94,57 +94,45 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>)
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkEditCategoryModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/expense/expense_bulk_edit_category.php"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-list mr-2"></i>Set Category
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkEditAccountModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/expense/expense_bulk_edit_account.php"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-piggy-bank mr-2"></i>Set Account
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkEditClientModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/expense/expense_bulk_edit_client.php"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-user mr-2"></i>Set Client
|
||||
</a>
|
||||
<?php if ($session_user_role == 3) { ?>
|
||||
<div class="dropdown-divider"></div>
|
||||
<button class="dropdown-item text-danger text-bold"
|
||||
type="submit" form="bulkActions" name="bulk_delete_expenses">
|
||||
<a class="dropdown-item text-danger text-bold ajax-modal" href="#"
|
||||
data-modal-url="modals/expense/expense_bulk_delete.php"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||
</button>
|
||||
</a>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collapse mt-3 <?php if (isset($_GET['dtf']) || $_GET['canned_date'] !== "custom" || $account_filter || $vendor_filter || $category_filter) { echo "show"; } ?>" id="advancedFilter">
|
||||
<div class="collapse mt-3 <?php if (isset($_GET['dtf']) && $_GET['dtf'] !== '1970-01-01' || $account_filter || $vendor_filter || $category_filter) { echo "show"; } ?>" id="advancedFilter">
|
||||
<div class="row">
|
||||
<div class="col-md-2">
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>Canned Date</label>
|
||||
<select onchange="this.form.submit()" class="form-control select2" name="canned_date">
|
||||
<option <?php if ($_GET['canned_date'] == "custom") { echo "selected"; } ?> value="">Custom</option>
|
||||
<option <?php if ($_GET['canned_date'] == "today") { echo "selected"; } ?> value="today">Today</option>
|
||||
<option <?php if ($_GET['canned_date'] == "yesterday") { echo "selected"; } ?> value="yesterday">Yesterday</option>
|
||||
<option <?php if ($_GET['canned_date'] == "thisweek") { echo "selected"; } ?> value="thisweek">This Week</option>
|
||||
<option <?php if ($_GET['canned_date'] == "lastweek") { echo "selected"; } ?> value="lastweek">Last Week</option>
|
||||
<option <?php if ($_GET['canned_date'] == "thismonth") { echo "selected"; } ?> value="thismonth">This Month</option>
|
||||
<option <?php if ($_GET['canned_date'] == "lastmonth") { echo "selected"; } ?> value="lastmonth">Last Month</option>
|
||||
<option <?php if ($_GET['canned_date'] == "thisyear") { echo "selected"; } ?> value="thisyear">This Year</option>
|
||||
<option <?php if ($_GET['canned_date'] == "lastyear") { echo "selected"; } ?> value="lastyear">Last Year</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>Date From</label>
|
||||
<input onchange="this.form.submit()" type="date" class="form-control" name="dtf" max="2999-12-31" value="<?php echo nullable_htmlentities($dtf); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>Date To</label>
|
||||
<input onchange="this.form.submit()" type="date" class="form-control" name="dtt" max="2999-12-31" value="<?php echo nullable_htmlentities($dtt); ?>">
|
||||
<label>Date range</label>
|
||||
<input type="text" id="dateFilter" class="form-control" autocomplete="off">
|
||||
<input type="hidden" name="canned_date" id="canned_date" value="<?php echo nullable_htmlentities($_GET['canned_date']) ?? ''; ?>">
|
||||
<input type="hidden" name="dtf" id="dtf" value="<?php echo nullable_htmlentities($dtf ?? ''); ?>">
|
||||
<input type="hidden" name="dtt" id="dtt" value="<?php echo nullable_htmlentities($dtt ?? ''); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
@@ -212,8 +200,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</div>
|
||||
</form>
|
||||
<hr>
|
||||
<form id="bulkActions" action="post.php" method="post" enctype="multipart/form-data">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-striped table-borderless table-hover">
|
||||
@@ -300,7 +286,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<tr>
|
||||
<td class="pr-0 bg-light">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input bulk-select" type="checkbox" name="expense_ids[]" value="<?php echo $expense_id ?>">
|
||||
<input class="form-check-input bulk-select" type="checkbox" name="selected_ids[]" value="<?= $expense_id ?>">
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
@@ -364,19 +350,12 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php require_once "modals/expense/expense_bulk_edit_category.php"; ?>
|
||||
<?php require_once "modals/expense/expense_bulk_edit_account.php"; ?>
|
||||
<?php require_once "modals/expense/expense_bulk_edit_client.php"; ?>
|
||||
</form>
|
||||
<?php require_once "../includes/filter_footer.php";
|
||||
?>
|
||||
<?php require_once "../includes/filter_footer.php"; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../js/bulk_actions.js"></script>
|
||||
<script src="/js/bulk_actions.js"></script>
|
||||
|
||||
<?php
|
||||
require_once "modals/expense/expense_add.php";
|
||||
require_once "modals/expense/expense_export.php";
|
||||
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
@@ -99,12 +99,12 @@ while ($folder_id > 0) {
|
||||
|
||||
<div class="card-tools">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#uploadFilesModal">
|
||||
<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" href="#" data-toggle="modal" data-target="#createFolderModal">
|
||||
<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>
|
||||
@@ -228,7 +228,7 @@ while ($folder_id > 0) {
|
||||
display_folders(0, $client_id);
|
||||
?>
|
||||
</ul>
|
||||
<?php require_once "modals/folder/folder_add.php"; ?>
|
||||
<?php //require_once "modals/folder/folder_add.php"; ?>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -257,7 +257,9 @@ while ($folder_id > 0) {
|
||||
<i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>)
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkMoveFilesModal">
|
||||
<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>
|
||||
@@ -581,13 +583,11 @@ while ($folder_id > 0) {
|
||||
|
||||
</table>
|
||||
</div>
|
||||
<?php require_once "modals/file/file_bulk_move.php"; ?>
|
||||
</form>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
<?php require_once "../includes/filter_footer.php";
|
||||
?>
|
||||
<?php require_once "../includes/filter_footer.php"; ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -620,7 +620,6 @@ function prevFile() {
|
||||
<script src="../js/bulk_actions.js"></script>
|
||||
|
||||
<?php
|
||||
require_once "modals/file/file_upload.php";
|
||||
require_once "modals/share_modal.php";
|
||||
require_once "modals/file/file_delete.php";
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
@@ -85,6 +85,8 @@ if (isset($_GET['query'])) {
|
||||
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
|
||||
WHERE ticket_archived_at IS NULL
|
||||
AND (ticket_subject LIKE '%$query%'
|
||||
OR ticket_details LIKE '%$query%'
|
||||
OR CONCAT(ticket_prefix,ticket_number) LIKE '%$query%'
|
||||
OR ticket_number = '$ticket_num_query')
|
||||
$access_permission_query
|
||||
ORDER BY ticket_id DESC LIMIT 5"
|
||||
@@ -107,11 +109,20 @@ if (isset($_GET['query'])) {
|
||||
ORDER BY credential_id DESC LIMIT 5"
|
||||
);
|
||||
|
||||
$sql_quotes = mysqli_query($mysqli, "SELECT * FROM quotes
|
||||
LEFT JOIN clients ON quote_client_id = client_id
|
||||
LEFT JOIN categories ON quote_category_id = category_id
|
||||
WHERE quote_archived_at IS NULL
|
||||
AND (CONCAT(quote_prefix,quote_number) LIKE '%$query%' OR quote_number LIKE '%$query%' OR quote_scope LIKE '%$query%')
|
||||
$access_permission_query
|
||||
ORDER BY quote_number DESC LIMIT 5"
|
||||
);
|
||||
|
||||
$sql_invoices = mysqli_query($mysqli, "SELECT * FROM invoices
|
||||
LEFT JOIN clients ON invoice_client_id = client_id
|
||||
LEFT JOIN categories ON invoice_category_id = category_id
|
||||
WHERE invoice_archived_at IS NULL
|
||||
AND (CONCAT(invoice_prefix,invoice_number) LIKE '%$query%' OR invoice_scope LIKE '%$query%')
|
||||
AND (CONCAT(invoice_prefix,invoice_number) LIKE '%$query%' OR invoice_number LIKE '%$query%' OR invoice_scope LIKE '%$query%')
|
||||
$access_permission_query
|
||||
ORDER BY invoice_number DESC LIMIT 5"
|
||||
);
|
||||
@@ -507,10 +518,10 @@ if (isset($_GET['query'])) {
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<td><a href="ticket.php?ticket_id=<?php echo $ticket_id ?>"><?php echo $ticket_prefix . $ticket_number; ?></a></td>
|
||||
<td><?php echo $ticket_subject; ?></td>
|
||||
<td><?php echo $ticket_status_name; ?></td>
|
||||
<td><a href="tickets.php?client_id=<?php echo $client_id ?>"><?php echo $client_name; ?></a></td>
|
||||
<td><a href="ticket.php?client_id=<?= $client_id ?>&ticket_id=<?= $ticket_id ?>"><?= $ticket_prefix . $ticket_number ?></a></td>
|
||||
<td><?= $ticket_subject ?></td>
|
||||
<td><?= $ticket_status_name ?></td>
|
||||
<td><a href="tickets.php?client_id=<?= $client_id ?>"><?= $client_name ?></a></td>
|
||||
</tr>
|
||||
|
||||
<?php } ?>
|
||||
@@ -626,6 +637,57 @@ if (isset($_GET['query'])) {
|
||||
|
||||
<?php } ?>
|
||||
|
||||
<?php if (mysqli_num_rows($sql_quotes) > 0) { ?>
|
||||
|
||||
<!-- Contacts-->
|
||||
|
||||
<div class="col-sm-6">
|
||||
<div class="card card-dark mb-3">
|
||||
<div class="card-header">
|
||||
<h6 class="card-title"><i class="fas fa-fw fa-file-invoice mr-2"></i>Quotes</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table table-striped table-borderless">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Number</th>
|
||||
<th>Status</th>
|
||||
<th>Amount</th>
|
||||
<th>Client</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
|
||||
while ($row = mysqli_fetch_array($sql_quotes)) {
|
||||
$quote_id = intval($row['quote_id']);
|
||||
$quote_prefix = nullable_htmlentities($row['quote_prefix']);
|
||||
$quote_number = intval($row['quote_number']);
|
||||
$quote_amount = floatval($row['quote_amount']);
|
||||
$quote_currency_code = nullable_htmlentities($row['quote_currency_code']);
|
||||
$quote_status = nullable_htmlentities($row['quote_status']);
|
||||
$client_id = intval($row['client_id']);
|
||||
$client_name = nullable_htmlentities($row['client_name']);
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<td><a href="quote.php?client_id=<?= $client_id ?>"e_id=<?php echo $quote_id; ?>"><?php echo "$quote_prefix$quote_number"; ?></a></td>
|
||||
<td><?php echo $quote_status; ?></td>
|
||||
<td><?php echo numfmt_format_currency($currency_format, $quote_amount, $quote_currency_code); ?></td>
|
||||
<td><a href="client_overview.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
|
||||
</tr>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
<?php if (mysqli_num_rows($sql_invoices) > 0) { ?>
|
||||
|
||||
<!-- Contacts-->
|
||||
@@ -660,7 +722,7 @@ if (isset($_GET['query'])) {
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<td><a href="invoice.php?invoice_id=<?php echo $invoice_id; ?>"><?php echo "$invoice_prefix$invoice_number"; ?></a></td>
|
||||
<td><a href="invoice.php?client_id=<?= $client_id ?>&invoice_id=<?php echo $invoice_id; ?>"><?php echo "$invoice_prefix$invoice_number"; ?></a></td>
|
||||
<td><?php echo $invoice_status; ?></td>
|
||||
<td><?php echo numfmt_format_currency($currency_format, $invoice_amount, $invoice_currency_code); ?></td>
|
||||
<td><a href="client_overview.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
|
||||
@@ -805,7 +867,7 @@ if (isset($_GET['query'])) {
|
||||
<?php echo "$client_name - $ticket_prefix$ticket_number - $ticket_subject"; ?>
|
||||
</h3>
|
||||
<div class="card-tools">
|
||||
<a href="ticket.php?ticket_id=<?php echo $ticket_id; ?>" target="_blank">Open <i class="fa fa-fw fa-external-link-alt"></i></a>
|
||||
<a href="ticket.php?client_id=<?= $client_id ?>&ticket_id=<?= $ticket_id ?>" target="_blank">Open <i class="fa fa-fw fa-external-link-alt"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body prettyContent">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!-- Main Sidebar Container -->
|
||||
<aside class="main-sidebar sidebar-dark-<?php if (isset($_GET['client_id'])) { echo "gray"; } else { echo nullable_htmlentities($config_theme); } ?> d-print-none">
|
||||
|
||||
<a class="brand-link pb-1 mt-1" href="clients.php">
|
||||
<a class="brand-link pb-1 mt-1" href="/agent/clients.php">
|
||||
<p class="h5">
|
||||
<i class="nav-icon fas fa-arrow-left ml-3 mr-2"></i>
|
||||
<span class="brand-text">
|
||||
@@ -19,14 +19,14 @@
|
||||
<ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
|
||||
|
||||
<li class="nav-item mt-3">
|
||||
<a href="client_overview.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "client_overview.php") { echo "active"; } ?>">
|
||||
<a href="/agent/client_overview.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "client_overview.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-tachometer-alt"></i>
|
||||
<p>Overview</p>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="contacts.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "contacts.php" || basename($_SERVER["PHP_SELF"]) == "contact_details.php") { echo "active"; } ?>">
|
||||
<a href="/agent/contacts.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "contacts.php" || basename($_SERVER["PHP_SELF"]) == "contact_details.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-address-book"></i>
|
||||
<p>
|
||||
Contacts
|
||||
@@ -39,7 +39,7 @@
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="locations.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "locations.php") { echo "active"; } ?>">
|
||||
<a href="/agent/locations.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "locations.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-map-marker-alt"></i>
|
||||
<p>
|
||||
Locations
|
||||
@@ -55,7 +55,7 @@
|
||||
<li class="nav-header mt-3">SUPPORT</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="tickets.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "tickets.php" || basename($_SERVER["PHP_SELF"]) == "ticket.php") { echo "active"; } ?>">
|
||||
<a href="/agent/tickets.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "tickets.php" || basename($_SERVER["PHP_SELF"]) == "ticket.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-life-ring"></i>
|
||||
<p>
|
||||
Tickets
|
||||
@@ -69,7 +69,7 @@
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="recurring_tickets.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "recurring_tickets.php") { echo "active"; } ?>">
|
||||
<a href="/agent/recurring_tickets.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "recurring_tickets.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-redo-alt"></i>
|
||||
<p>
|
||||
Recurring Tickets
|
||||
@@ -83,7 +83,7 @@
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="projects.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "projects.php" || basename($_SERVER["PHP_SELF"]) == "project_details.php") { echo "active"; } ?>">
|
||||
<a href="/agent/projects.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "projects.php" || basename($_SERVER["PHP_SELF"]) == "project_details.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-project-diagram"></i>
|
||||
<p>
|
||||
Projects
|
||||
@@ -97,7 +97,7 @@
|
||||
<?php } ?>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="vendors.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "vendors.php") { echo "active"; } ?>">
|
||||
<a href="/agent/vendors.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "vendors.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-building"></i>
|
||||
<p>
|
||||
Vendors
|
||||
@@ -110,7 +110,7 @@
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="calendar.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "calendar.php") { echo "active"; } ?>">
|
||||
<a href="/agent/calendar.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "calendar.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-calendar-alt"></i>
|
||||
<p>
|
||||
Calendar
|
||||
@@ -128,7 +128,7 @@
|
||||
|
||||
<?php if (lookupUserPermission("module_support") >= 1) { ?>
|
||||
<li class="nav-item">
|
||||
<a href="assets.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "assets.php" || basename($_SERVER["PHP_SELF"]) == "client_asset_details.php") { echo "active"; } ?>">
|
||||
<a href="/agent/assets.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "assets.php" || basename($_SERVER["PHP_SELF"]) == "client_asset_details.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-desktop"></i>
|
||||
<p>
|
||||
Assets
|
||||
@@ -141,7 +141,7 @@
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="software.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "software.php") { echo "active"; } ?>">
|
||||
<a href="/agent/software.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "software.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-cube"></i>
|
||||
<p>
|
||||
Licenses
|
||||
@@ -155,7 +155,7 @@
|
||||
|
||||
<?php if (lookupUserPermission("module_credential") >= 1) { ?>
|
||||
<li class="nav-item">
|
||||
<a href="credentials.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "credentials.php") { echo "active"; } ?>">
|
||||
<a href="/agent/credentials.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "credentials.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-key"></i>
|
||||
<p>
|
||||
Credentials
|
||||
@@ -169,7 +169,7 @@
|
||||
<?php } ?>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="networks.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "networks.php") { echo "active"; } ?>">
|
||||
<a href="/agent/networks.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "networks.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-network-wired"></i>
|
||||
<p>
|
||||
Networks
|
||||
@@ -182,7 +182,7 @@
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="racks.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "racks.php") { echo "active"; } ?>">
|
||||
<a href="/agent/racks.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "racks.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-server"></i>
|
||||
<p>
|
||||
Racks
|
||||
@@ -195,7 +195,7 @@
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="certificates.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "certificates.php") { echo "active"; } ?>">
|
||||
<a href="/agent/certificates.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "certificates.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-lock"></i>
|
||||
<p>
|
||||
Certificates
|
||||
@@ -209,7 +209,7 @@
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="domains.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "domains.php") { echo "active"; } ?>">
|
||||
<a href="/agent/domains.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "domains.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-globe"></i>
|
||||
<p>
|
||||
Domains
|
||||
@@ -223,7 +223,7 @@
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="services.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "services.php") { echo "active"; } ?>">
|
||||
<a href="/agent/services.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "services.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-stream"></i>
|
||||
<p>
|
||||
Services
|
||||
@@ -236,7 +236,7 @@
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="documents.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "documents.php" || basename($_SERVER["PHP_SELF"]) == "document_details.php") { echo "active"; } ?>">
|
||||
<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
|
||||
@@ -252,7 +252,7 @@
|
||||
|
||||
<!-- Allow files even without module_support for things like contracts, etc. ) -->
|
||||
<li class="nav-item">
|
||||
<a href="files.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "files.php") { echo "active"; } ?>">
|
||||
<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>
|
||||
<p>
|
||||
Files
|
||||
@@ -273,7 +273,7 @@
|
||||
<?php if (lookupUserPermission("module_sales") >= 1) { ?>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="invoices.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "invoices.php" || basename($_SERVER["PHP_SELF"]) == "invoice.php") { echo "active"; } ?>">
|
||||
<a href="/agent/invoices.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "invoices.php" || basename($_SERVER["PHP_SELF"]) == "invoice.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-file-invoice"></i>
|
||||
<p>
|
||||
Invoices
|
||||
@@ -286,7 +286,7 @@
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="recurring_invoices.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "recurring_invoices.php" || basename($_SERVER["PHP_SELF"]) == "recurring_invoice.php") { echo "active"; } ?>">
|
||||
<a href="/agent/recurring_invoices.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "recurring_invoices.php" || basename($_SERVER["PHP_SELF"]) == "recurring_invoice.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-redo-alt"></i>
|
||||
<p>
|
||||
Recurring Invoices
|
||||
@@ -299,7 +299,7 @@
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="quotes.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "quotes.php" || basename($_SERVER["PHP_SELF"]) == "quote.php") { echo "active"; } ?>">
|
||||
<a href="/agent/quotes.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "quotes.php" || basename($_SERVER["PHP_SELF"]) == "quote.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-comment-dollar"></i>
|
||||
<p>
|
||||
Quotes
|
||||
@@ -315,7 +315,7 @@
|
||||
|
||||
<?php if (lookupUserPermission("module_financial") >= 1) { ?>
|
||||
<li class="nav-item">
|
||||
<a href="payments.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "payments.php") { echo "active"; } ?>">
|
||||
<a href="/agent/payments.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "payments.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-credit-card"></i>
|
||||
<p>
|
||||
Payments
|
||||
@@ -329,7 +329,7 @@
|
||||
<?php } ?>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="trips.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "trips.php") { echo "active"; } ?>">
|
||||
<a href="/agent/trips.php?client_id=<?php echo $client_id; ?>" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "trips.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-route"></i>
|
||||
<p>
|
||||
Trips
|
||||
|
||||
@@ -37,7 +37,8 @@ if (isset($_GET['client_id'])) {
|
||||
if (mysqli_num_rows($sql) == 0) {
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/header.php';
|
||||
|
||||
echo "<center><h1 class='text-secondary mt-5'>Nothing to see here</h1></center>";
|
||||
echo "<center><h1 class='text-secondary mt-5'>Nothing to see here</h1><a class='btn btn-lg btn-secondary mt-3' href='javascript:history.back()'><i class='fa fa-fw fa-arrow-left'></i> Go Back</a></center>";
|
||||
exit;
|
||||
} else {
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!-- Main Sidebar Container -->
|
||||
<aside class="main-sidebar sidebar-dark-<?php echo nullable_htmlentities($config_theme); ?> d-print-none">
|
||||
|
||||
<a class="brand-link" href="dashboard.php">
|
||||
<a class="brand-link" href="/agent/dashboard.php">
|
||||
<div class="brand-image"></div>
|
||||
<span class="brand-text h4"><?php echo nullable_htmlentities($session_company_name); ?></span>
|
||||
</a>
|
||||
@@ -13,14 +13,14 @@
|
||||
<nav>
|
||||
<ul class="nav nav-pills nav-sidebar flex-column mt-3" data-widget="treeview" data-accordion="false">
|
||||
<li class="nav-item">
|
||||
<a href="dashboard.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "dashboard.php") { echo "active"; } ?>">
|
||||
<a href="/agent/dashboard.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "dashboard.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-tachometer-alt"></i>
|
||||
<p>Dashboard</p>
|
||||
</a>
|
||||
</li>
|
||||
<?php if (lookupUserPermission("module_client") >= 1) { ?>
|
||||
<li class="nav-item">
|
||||
<a href="clients.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "clients.php") { echo "active"; } ?>">
|
||||
<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
|
||||
@@ -36,7 +36,7 @@
|
||||
<?php if ($config_module_enable_ticketing == 1) { ?>
|
||||
<li class="nav-header mt-3">SUPPORT</li>
|
||||
<li class="nav-item">
|
||||
<a href="tickets.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "tickets.php" || basename($_SERVER["PHP_SELF"]) == "ticket.php") { echo "active"; } ?>">
|
||||
<a href="/agent/tickets.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "tickets.php" || basename($_SERVER["PHP_SELF"]) == "ticket.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-life-ring"></i>
|
||||
<p>
|
||||
Tickets
|
||||
@@ -47,7 +47,7 @@
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="recurring_tickets.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "recurring_tickets.php") { echo "active"; } ?>">
|
||||
<a href="/agent/recurring_tickets.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "recurring_tickets.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-redo-alt"></i>
|
||||
<p>
|
||||
Recurring Tickets
|
||||
@@ -58,7 +58,7 @@
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="projects.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "projects.php" || basename($_SERVER["PHP_SELF"]) == "project_details.php") { echo "active"; } ?>">
|
||||
<a href="/agent/projects.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "projects.php" || basename($_SERVER["PHP_SELF"]) == "project_details.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-project-diagram"></i>
|
||||
<p>
|
||||
Projects
|
||||
@@ -72,7 +72,7 @@
|
||||
<?php } ?>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="calendar.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "calendar.php") { echo "active"; } ?>">
|
||||
<a href="/agent/calendar.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "calendar.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-calendar-alt"></i>
|
||||
<p>Calendar</p>
|
||||
</a>
|
||||
@@ -80,7 +80,7 @@
|
||||
<?php if ($config_module_enable_accounting == 1 && lookupUserPermission("module_sales") >= 1) { ?>
|
||||
<li class="nav-header mt-3">BILLING</li>
|
||||
<li class="nav-item">
|
||||
<a href="quotes.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "quotes.php" || basename($_SERVER["PHP_SELF"]) == "quote.php") { echo "active"; } ?>">
|
||||
<a href="/agent/quotes.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "quotes.php" || basename($_SERVER["PHP_SELF"]) == "quote.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-comment-dollar"></i>
|
||||
<p>
|
||||
Quotes
|
||||
@@ -91,7 +91,7 @@
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="invoices.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "invoices.php" || basename($_SERVER["PHP_SELF"]) == "invoice.php") { echo "active"; } ?>">
|
||||
<a href="/agent/invoices.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "invoices.php" || basename($_SERVER["PHP_SELF"]) == "invoice.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-file-invoice"></i>
|
||||
<p>
|
||||
Invoices
|
||||
@@ -102,7 +102,7 @@
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="recurring_invoices.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "recurring_invoices.php" || basename($_SERVER["PHP_SELF"]) == "recurring_invoice.php") { echo "active"; } ?>">
|
||||
<a href="/agent/recurring_invoices.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "recurring_invoices.php" || basename($_SERVER["PHP_SELF"]) == "recurring_invoice.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-redo-alt"></i>
|
||||
<p>
|
||||
Recurring Invoices
|
||||
@@ -113,13 +113,13 @@
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="revenues.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "revenues.php") { echo "active"; } ?>">
|
||||
<a href="/agent/revenues.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "revenues.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-hand-holding-usd"></i>
|
||||
<p>Revenues</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="products.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "products.php") { echo "active"; } ?>">
|
||||
<a href="/agent/products.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "products.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-box-open"></i>
|
||||
<p>Products</p>
|
||||
</a>
|
||||
@@ -128,25 +128,25 @@
|
||||
<?php if ($config_module_enable_accounting == 1 && lookupUserPermission("module_financial") >= 1) { ?>
|
||||
<li class="nav-header mt-3">FINANCE</li>
|
||||
<li class="nav-item">
|
||||
<a href="payments.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "payments.php") { echo "active"; } ?>">
|
||||
<a href="/agent/payments.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "payments.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-credit-card"></i>
|
||||
<p>Payments</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="vendors.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "vendors.php") { echo "active"; } ?>">
|
||||
<a href="/agent/vendors.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "vendors.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-building"></i>
|
||||
<p>Vendors</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="expenses.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "expenses.php") { echo "active"; } ?>">
|
||||
<a href="/agent/expenses.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "expenses.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-shopping-cart"></i>
|
||||
<p>Expenses</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="recurring_expenses.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "recurring_expenses.php") { echo "active"; } ?>">
|
||||
<a href="/agent/recurring_expenses.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "recurring_expenses.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-redo-alt"></i>
|
||||
<p>
|
||||
Recurring Expenses
|
||||
@@ -157,19 +157,19 @@
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="accounts.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "accounts.php") { echo "active"; } ?>">
|
||||
<a href="/agent/accounts.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "accounts.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-piggy-bank"></i>
|
||||
<p>Accounts</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="transfers.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "transfers.php") { echo "active"; } ?>">
|
||||
<a href="/agent/transfers.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "transfers.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-exchange-alt"></i>
|
||||
<p>Transfers</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="trips.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "trips.php") { echo "active"; } ?>">
|
||||
<a href="/agent/trips.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "trips.php") { echo "active"; } ?>">
|
||||
<i class="nav-icon fas fa-route"></i>
|
||||
<p>Trips</p>
|
||||
</a>
|
||||
@@ -178,7 +178,7 @@
|
||||
|
||||
<?php if (lookupUserPermission("module_client") >= 1) { ?>
|
||||
<li class="nav-item mt-3">
|
||||
<a href="contacts.php" class="nav-link">
|
||||
<a href="/agent/contacts.php" class="nav-link">
|
||||
<i class="fas fa-users nav-icon"></i>
|
||||
<p>Client Overview</p>
|
||||
<i class="fas fa-angle-right nav-icon float-right"></i>
|
||||
@@ -188,7 +188,7 @@
|
||||
|
||||
<?php if (lookupUserPermission("module_reporting") >= 1) { ?>
|
||||
<li class="nav-item mt-3">
|
||||
<a href="reports/" class="nav-link">
|
||||
<a href="/agent/reports/" class="nav-link">
|
||||
<i class="fas fa-chart-line nav-icon"></i>
|
||||
<p>Reports</p>
|
||||
<i class="fas fa-angle-right nav-icon float-right"></i>
|
||||
|
||||
@@ -163,7 +163,9 @@ if (isset($_GET['invoice_id'])) {
|
||||
//Product autocomplete
|
||||
$products_sql = mysqli_query($mysqli, "
|
||||
SELECT
|
||||
product_name AS label,
|
||||
CONCAT(product_code, ' - ', product_name) AS label,
|
||||
product_name,
|
||||
product_code,
|
||||
product_type AS type,
|
||||
product_description AS description,
|
||||
product_price AS price,
|
||||
@@ -197,21 +199,12 @@ if (isset($_GET['invoice_id'])) {
|
||||
?>
|
||||
|
||||
<ol class="breadcrumb d-print-none">
|
||||
<?php if (isset($_GET['client_id'])) { ?>
|
||||
<li class="breadcrumb-item">
|
||||
<a href="client_overview.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a>
|
||||
<a href="invoices.php">All Invoices</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item">
|
||||
<a href="invoices.php?client_id=<?php echo $client_id; ?>">Invoices</a>
|
||||
<a href="invoices.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?> Invoices</a>
|
||||
</li>
|
||||
<?php } else { ?>
|
||||
<li class="breadcrumb-item">
|
||||
<a href="invoices.php">Invoices</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item">
|
||||
<a href="invoices.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<li class="breadcrumb-item active"><?php echo "$invoice_prefix$invoice_number"; ?></li>
|
||||
<?php if (isset($invoice_overdue)) { ?>
|
||||
<span class="p-2 ml-2 badge badge-danger"><?php echo $invoice_overdue; ?></span>
|
||||
@@ -247,12 +240,12 @@ if (isset($_GET['invoice_id'])) {
|
||||
<?php if ($invoice_status !== 'Paid' && $invoice_status !== 'Cancelled' && $invoice_status !== 'Draft' && $invoice_status !== 'Non-Billable' && $invoice_amount != 0) { ?>
|
||||
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-success ajax-modal" data-modal-url="modals/invoice/invoice_pay.php?id=<?= $invoice_id ?>"><i class="fa fa-fw fa-credit-card mr-2"></i>Add Payment</button>
|
||||
<button type="button" class="btn btn-success ajax-modal" data-modal-url="modals/payment/payment_add.php?id=<?= $invoice_id ?>"><i class="fa fa-fw fa-credit-card mr-2"></i>Add Payment</button>
|
||||
|
||||
<?php if (mysqli_num_rows($sql_saved_payment_methods) > 0 && ($invoice_status === 'Sent' || $invoice_status === 'Viewed')) { ?>
|
||||
<button type="button" class="btn btn-success dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item ajax-modal" href="#" data-modal-url="modals/invoice/invoice_saved_method_pay.php?id=<?= $invoice_id ?>"><i class="fas fa-fw fa-wallet mr-2"></i>Pay with Saved Card</a>
|
||||
<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 } ?>
|
||||
|
||||
@@ -747,12 +740,20 @@ require_once "../includes/footer.php";
|
||||
<script>
|
||||
|
||||
$(function() {
|
||||
|
||||
var availableProducts = <?php echo $json_products ?? '[]'?>;
|
||||
|
||||
$("#name").autocomplete({
|
||||
source: availableProducts,
|
||||
minLength: 1,
|
||||
delay: 0,
|
||||
source: function(request, response) {
|
||||
var term = $.ui.autocomplete.escapeRegex(request.term.toLowerCase());
|
||||
var matcher = new RegExp(term, "i");
|
||||
var matches = $.grep(availableProducts, function(item) {
|
||||
return matcher.test(item.label) || matcher.test(item.product_name) || matcher.test(item.product_code);
|
||||
});
|
||||
response(matches);
|
||||
},
|
||||
select: function (event, ui) {
|
||||
$("#name").val(ui.item.label);
|
||||
$("#desc").val(ui.item.description);
|
||||
|
||||
@@ -97,6 +97,7 @@ $sql = mysqli_query(
|
||||
"SELECT SQL_CALC_FOUND_ROWS * FROM invoices
|
||||
LEFT JOIN clients ON invoice_client_id = client_id
|
||||
LEFT JOIN categories ON invoice_category_id = category_id
|
||||
LEFT JOIN recurring_invoices ON invoice_recurring_invoice_id = recurring_invoice_id
|
||||
WHERE ($status_query)
|
||||
$overdue_query
|
||||
$category_query
|
||||
@@ -161,7 +162,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<h3 class="card-title mt-2"><i class="fa fa-fw fa-file-invoice mr-2"></i>Invoices</h3>
|
||||
<div class="card-tools">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addInvoiceModal"><i class="fas fa-plus mr-2"></i>New Invoice</button>
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/invoice/invoice_add.php?<?= $client_url ?>"><i class="fas fa-plus mr-2"></i>New Invoice</button>
|
||||
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#exportInvoicesModal">
|
||||
@@ -217,12 +218,15 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<?php if ($client_url && $balance > 0) { ?>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#addBulkPaymentModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/payment/payment_bulk_add.php?<?= $client_url ?>">
|
||||
<i class="fa fa-credit-card mr-2"></i>Batch Payment
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<?php } ?>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkEditCategoryModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/invoice/invoice_bulk_edit_category.php"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-list-ul mr-2"></i>Set Category
|
||||
</a>
|
||||
</div>
|
||||
@@ -230,41 +234,22 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collapse mt-3 <?php if (!empty($_GET['dtf']) || $_GET['canned_date'] !== "custom" ) { echo "show"; } ?>" id="advancedFilter">
|
||||
<div class="collapse mt-3 <?php if (isset($_GET['dtf']) && $_GET['dtf'] !== '1970-01-01') { echo "show"; } ?>" id="advancedFilter">
|
||||
<div class="row">
|
||||
<div class="col-md-2">
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>Canned Date</label>
|
||||
<select onchange="this.form.submit()" class="form-control select2" name="canned_date">
|
||||
<option <?php if ($_GET['canned_date'] == "custom") { echo "selected"; } ?> value="custom">Custom</option>
|
||||
<option <?php if ($_GET['canned_date'] == "today") { echo "selected"; } ?> value="today">Today</option>
|
||||
<option <?php if ($_GET['canned_date'] == "yesterday") { echo "selected"; } ?> value="yesterday">Yesterday</option>
|
||||
<option <?php if ($_GET['canned_date'] == "thisweek") { echo "selected"; } ?> value="thisweek">This Week</option>
|
||||
<option <?php if ($_GET['canned_date'] == "lastweek") { echo "selected"; } ?> value="lastweek">Last Week</option>
|
||||
<option <?php if ($_GET['canned_date'] == "thismonth") { echo "selected"; } ?> value="thismonth">This Month</option>
|
||||
<option <?php if ($_GET['canned_date'] == "lastmonth") { echo "selected"; } ?> value="lastmonth">Last Month</option>
|
||||
<option <?php if ($_GET['canned_date'] == "thisyear") { echo "selected"; } ?> value="thisyear">This Year</option>
|
||||
<option <?php if ($_GET['canned_date'] == "lastyear") { echo "selected"; } ?> value="lastyear">Last Year</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>Date From</label>
|
||||
<input onchange="this.form.submit()" type="date" class="form-control" name="dtf" max="2999-12-31" value="<?php echo $dtf; ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>Date To</label>
|
||||
<input onchange="this.form.submit()" type="date" class="form-control" name="dtt" max="2999-12-31" value="<?php echo $dtt; ?>">
|
||||
<label>Date range</label>
|
||||
<input type="text" id="dateFilter" class="form-control" autocomplete="off">
|
||||
<input type="hidden" name="canned_date" id="canned_date" value="<?php echo nullable_htmlentities($_GET['canned_date']) ?? ''; ?>">
|
||||
<input type="hidden" name="dtf" id="dtf" value="<?php echo nullable_htmlentities($dtf ?? ''); ?>">
|
||||
<input type="hidden" name="dtt" id="dtt" value="<?php echo nullable_htmlentities($dtt ?? ''); ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<hr>
|
||||
<form id="bulkActions" action="post.php" method="post" enctype="multipart/form-data">
|
||||
<form id="bulkActions" action="post.php" method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-striped table-borderless table-hover">
|
||||
@@ -317,6 +302,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
Status <?php if ($sort == 'invoice_status') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th>Recurring</th>
|
||||
<th class="text-center">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -349,6 +335,16 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
if ($client_net_terms == 0) {
|
||||
$client_net_terms = $config_default_net_terms;
|
||||
}
|
||||
$recurring_invoice_id = intval($row['recurring_invoice_id']);
|
||||
$recurring_invoice_prefix = nullable_htmlentities($row['recurring_invoice_prefix']);
|
||||
$recurring_invoice_number = nullable_htmlentities($row['recurring_invoice_number']);
|
||||
if($recurring_invoice_id) {
|
||||
$recurring_invoice_display = "<i class='fas fa-fw fa-redo-alt text-secondary mr-1'></i><a href='recurring_invoice.php?recurring_invoice_id=$recurring_invoice_id'>$recurring_invoice_prefix$recurring_invoice_number</a>";
|
||||
} else {
|
||||
$recurring_invoice_display = "-";
|
||||
}
|
||||
|
||||
|
||||
|
||||
$now = time();
|
||||
|
||||
@@ -369,7 +365,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-bold">
|
||||
<a href="invoice.php?<?php echo $client_url; ?>invoice_id=<?php echo $invoice_id; ?>">
|
||||
<a href="invoice.php?client_id=<?= $client_id ?>&invoice_id=<?= $invoice_id ?>">
|
||||
<?php echo "$invoice_prefix$invoice_number"; ?>
|
||||
</a>
|
||||
</td>
|
||||
@@ -386,6 +382,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<?php echo $invoice_status; ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><?= $recurring_invoice_display ?></td>
|
||||
<td>
|
||||
<div class="dropdown dropleft text-center">
|
||||
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
|
||||
@@ -394,7 +391,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<div class="dropdown-menu">
|
||||
<?php if ($invoice_status !== 'Paid' && $invoice_status !== 'Cancelled' && $invoice_status !== 'Draft' && $invoice_status !== 'Non-Billable' && $invoice_amount != 0) { ?>
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/invoice/invoice_pay.php?id=<?= $invoice_id ?>">
|
||||
data-modal-url="modals/payment/payment_add.php?id=<?= $invoice_id ?>">
|
||||
<i class="fa fa-fw fa-credit-card mr-2"></i>Add Payment
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
@@ -443,17 +440,13 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php require_once "modals/invoice/invoice_bulk_edit_category.php"; ?>
|
||||
</form>
|
||||
<?php require_once "../includes/filter_footer.php";
|
||||
?>
|
||||
<?php require_once "../includes/filter_footer.php"; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../js/bulk_actions.js"></script>
|
||||
|
||||
<?php
|
||||
require_once "modals/invoice/invoice_add.php";
|
||||
if ($client_url) { require_once "modals/invoice/invoice_payment_add_bulk.php"; }
|
||||
require_once "modals/invoice/invoice_export.php";
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
@@ -1,94 +1,55 @@
|
||||
/*
|
||||
* LISTENERS
|
||||
*/
|
||||
$(document).ready(function() {
|
||||
|
||||
// Modal loaded listener - populate client select
|
||||
const changeClientModalLoad = document.getElementById('clientChangeTicketModalLoad');
|
||||
changeClientModalLoad.addEventListener('click', function() {
|
||||
populateChangeClientModal_Clients();
|
||||
})
|
||||
// Function to load contacts for a given client
|
||||
function loadContacts(clientId) {
|
||||
if (!clientId) return;
|
||||
|
||||
// Client selected listener - populate contact select
|
||||
// We seem to have to use jQuery to listen for events, as the client input is a select2 component?
|
||||
const clientSelectDropdown = document.getElementById("changeClientSelect");
|
||||
$(clientSelectDropdown).on('select2:select', function (e) {
|
||||
let client_id = $(this).find(':selected').val();
|
||||
populateChangeClientModal_Contacts(client_id);
|
||||
var $contactSelect = $('#contact_select');
|
||||
$contactSelect.html('<option value="">Loading...</option>');
|
||||
|
||||
$.ajax({
|
||||
url: 'ajax.php',
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
get_client_contacts: 1,
|
||||
client_id: clientId
|
||||
},
|
||||
success: function(response) {
|
||||
$contactSelect.empty();
|
||||
if (response.contacts && response.contacts.length > 0) {
|
||||
$contactSelect.append('<option value="">Select a contact</option>');
|
||||
$.each(response.contacts, function(i, contact) {
|
||||
$contactSelect.append(
|
||||
$('<option>', {
|
||||
value: contact.contact_id,
|
||||
text: contact.contact_name
|
||||
})
|
||||
);
|
||||
});
|
||||
} else {
|
||||
$contactSelect.append('<option value="">No contacts found</option>');
|
||||
}
|
||||
|
||||
// Refresh Select2
|
||||
if ($.fn.select2) {
|
||||
$contactSelect.trigger('change.select2');
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error('AJAX Error:', error);
|
||||
$contactSelect.html('<option value="">Failed to load contacts</option>');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Load contacts for the currently selected client when modal opens
|
||||
var initialClientId = $('#client_select').val();
|
||||
loadContacts(initialClientId);
|
||||
|
||||
// Load contacts when client changes
|
||||
$('#client_select').on('change', function() {
|
||||
var clientId = $(this).val();
|
||||
loadContacts(clientId);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTIONS
|
||||
*/
|
||||
|
||||
// Populate client list function
|
||||
function populateChangeClientModal_Clients() {
|
||||
|
||||
// Get current client ID
|
||||
let current_client_id = document.getElementById("client_id").value;
|
||||
|
||||
// Send a GET request to ajax.php as ajax.php?get_active_clients=true
|
||||
jQuery.get(
|
||||
"ajax.php",
|
||||
{get_active_clients: 'true'},
|
||||
function(data) {
|
||||
|
||||
// If we get a response from ajax.php, parse it as JSON
|
||||
const response = JSON.parse(data);
|
||||
|
||||
// Access the data for clients (multiple)
|
||||
const clients = response.clients;
|
||||
|
||||
// Client dropdown already defined in listeners as clientSelectDropdown
|
||||
|
||||
// Clear dropdown
|
||||
let i, L = clientSelectDropdown.options.length - 1;
|
||||
for (i = L; i >= 0; i--) {
|
||||
clientSelectDropdown.remove(i);
|
||||
}
|
||||
clientSelectDropdown[clientSelectDropdown.length] = new Option('- Client -', '0');
|
||||
|
||||
// Populate dropdown
|
||||
clients.forEach(client => {
|
||||
if (parseInt(current_client_id) !== parseInt(client.client_id)) {
|
||||
// Show clients returned (excluding the current client ID - we can't change a ticket client to itself)
|
||||
clientSelectDropdown[clientSelectDropdown.length] = new Option(client.client_name, client.client_id);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Populate client contact function (after a client is selected)
|
||||
function populateChangeClientModal_Contacts(client_id) {
|
||||
// Send a GET request to ajax.php as ajax.php?get_client_contacts=true&client_id=NUM
|
||||
jQuery.get(
|
||||
"ajax.php",
|
||||
{get_client_contacts: 'true', client_id: client_id},
|
||||
function(data) {
|
||||
|
||||
// If we get a response from ajax.php, parse it as JSON
|
||||
const response = JSON.parse(data);
|
||||
|
||||
// Access the data for contacts (multiple)
|
||||
const contacts = response.contacts;
|
||||
|
||||
// Contacts dropdown
|
||||
const contactSelectDropdown = document.getElementById("changeContactSelect");
|
||||
|
||||
// Clear Category dropdown
|
||||
let i, L = contactSelectDropdown.options.length - 1;
|
||||
for (i = L; i >= 0; i--) {
|
||||
contactSelectDropdown.remove(i);
|
||||
}
|
||||
contactSelectDropdown[contactSelectDropdown.length] = new Option('- Contact -', '0');
|
||||
|
||||
// Populate dropdown
|
||||
contacts.forEach(contact => {
|
||||
contactSelectDropdown[contactSelectDropdown.length] = new Option(contact.contact_name, contact.contact_id);
|
||||
});
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
(function() {
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
// Initialize variables
|
||||
var timerInterval = null;
|
||||
var ticketID = getCurrentTicketID();
|
||||
var elapsedSecs = getElapsedSeconds();
|
||||
@@ -22,24 +21,41 @@
|
||||
return pausedTime + timeSinceStart;
|
||||
}
|
||||
|
||||
function pad(val) {
|
||||
return val < 10 ? "0" + val : val;
|
||||
}
|
||||
|
||||
function displayTime() {
|
||||
|
||||
// Show hrs, mins, sec input placeholders if auto-start is off
|
||||
if (elapsedSecs === 0) {
|
||||
document.getElementById("hours").value = "";
|
||||
document.getElementById("minutes").value = "";
|
||||
document.getElementById("seconds").value = "";
|
||||
return;
|
||||
}
|
||||
|
||||
let totalSeconds = elapsedSecs;
|
||||
let hours = Math.floor(totalSeconds / 3600);
|
||||
totalSeconds %= 3600;
|
||||
let minutes = Math.floor(totalSeconds / 60);
|
||||
let seconds = totalSeconds % 60;
|
||||
|
||||
document.getElementById("hours").value = pad(hours);
|
||||
document.getElementById("minutes").value = pad(minutes);
|
||||
document.getElementById("seconds").value = pad(seconds);
|
||||
}
|
||||
let hoursEl = document.getElementById("hours");
|
||||
let minutesEl = document.getElementById("minutes");
|
||||
let secondsEl = document.getElementById("seconds");
|
||||
|
||||
function pad(val) {
|
||||
return val < 10 ? "0" + val : val;
|
||||
if (hoursEl && minutesEl && secondsEl) {
|
||||
hoursEl.value = pad(hours);
|
||||
minutesEl.value = pad(minutes);
|
||||
secondsEl.value = pad(seconds);
|
||||
} else {
|
||||
console.warn("Timer input elements not found");
|
||||
}
|
||||
}
|
||||
|
||||
function countTime() {
|
||||
elapsedSecs++;
|
||||
elapsedSecs = getElapsedSeconds();
|
||||
displayTime();
|
||||
}
|
||||
|
||||
@@ -48,7 +64,8 @@
|
||||
localStorage.setItem(getLocalStorageKey("startTime"), Date.now().toString());
|
||||
}
|
||||
timerInterval = setInterval(countTime, 1000);
|
||||
document.getElementById("startStopTimer").innerHTML = "<i class='fas fa-pause'></i>";
|
||||
let btn = document.getElementById("startStopTimer");
|
||||
if (btn) btn.innerHTML = "<i class='fas fa-pause'></i>";
|
||||
localStorage.setItem("ticket-timer-running-" + ticketID, "true");
|
||||
}
|
||||
|
||||
@@ -60,7 +77,8 @@
|
||||
let currentElapsed = getElapsedSeconds();
|
||||
localStorage.setItem(getLocalStorageKey("pausedTime"), currentElapsed.toString());
|
||||
localStorage.removeItem(getLocalStorageKey("startTime"));
|
||||
document.getElementById("startStopTimer").innerHTML = "<i class='fas fa-play'></i>";
|
||||
let btn = document.getElementById("startStopTimer");
|
||||
if (btn) btn.innerHTML = "<i class='fas fa-play'></i>";
|
||||
localStorage.setItem("ticket-timer-running-" + ticketID, "false");
|
||||
}
|
||||
|
||||
@@ -77,7 +95,8 @@
|
||||
elapsedSecs = 0;
|
||||
clearTimeStorage();
|
||||
displayTime();
|
||||
document.getElementById("startStopTimer").innerHTML = "<i class='fas fa-play'></i>";
|
||||
let btn = document.getElementById("startStopTimer");
|
||||
if (btn) btn.innerHTML = "<i class='fas fa-play'></i>";
|
||||
}
|
||||
localStorage.setItem("ticket-timer-running-" + ticketID, "false");
|
||||
}
|
||||
@@ -88,7 +107,8 @@
|
||||
elapsedSecs = 0;
|
||||
clearTimeStorage();
|
||||
displayTime();
|
||||
document.getElementById("startStopTimer").innerHTML = "<i class='fas fa-play'></i>";
|
||||
let btn = document.getElementById("startStopTimer");
|
||||
if (btn) btn.innerHTML = "<i class='fas fa-play'></i>";
|
||||
}
|
||||
|
||||
function handleInputFocus() {
|
||||
@@ -96,9 +116,9 @@
|
||||
}
|
||||
|
||||
function updateTimeFromInput() {
|
||||
const hours = parseInt(document.getElementById("hours").value, 10) || 0;
|
||||
const minutes = parseInt(document.getElementById("minutes").value, 10) || 0;
|
||||
const seconds = parseInt(document.getElementById("seconds").value, 10) || 0;
|
||||
const hours = parseInt(document.getElementById("hours")?.value, 10) || 0;
|
||||
const minutes = parseInt(document.getElementById("minutes")?.value, 10) || 0;
|
||||
const seconds = parseInt(document.getElementById("seconds")?.value, 10) || 0;
|
||||
elapsedSecs = (hours * 3600) + (minutes * 60) + seconds;
|
||||
|
||||
if (!timerInterval) {
|
||||
@@ -111,61 +131,93 @@
|
||||
}
|
||||
|
||||
function checkStatusAndPauseTimer() {
|
||||
var status = document.querySelector('select[name="status"]').value;
|
||||
var statusEl = document.querySelector('select[name="status"]');
|
||||
if (statusEl) {
|
||||
var status = statusEl.value;
|
||||
if (status.includes("Pending") || status.includes("Close")) {
|
||||
pauseTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Attach input listeners
|
||||
document.getElementById("hours").addEventListener('change', updateTimeFromInput);
|
||||
document.getElementById("minutes").addEventListener('change', updateTimeFromInput);
|
||||
document.getElementById("seconds").addEventListener('change', updateTimeFromInput);
|
||||
// Update on tab visibility change to handle background sleep
|
||||
document.addEventListener('visibilitychange', function() {
|
||||
if (!document.hidden) {
|
||||
elapsedSecs = getElapsedSeconds();
|
||||
displayTime();
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById("hours").addEventListener('focus', handleInputFocus);
|
||||
document.getElementById("minutes").addEventListener('focus', handleInputFocus);
|
||||
document.getElementById("seconds").addEventListener('focus', handleInputFocus);
|
||||
// Attach input listeners with null checks
|
||||
const hoursEl = document.getElementById("hours");
|
||||
if (hoursEl) {
|
||||
hoursEl.addEventListener('change', updateTimeFromInput);
|
||||
hoursEl.addEventListener('focus', handleInputFocus);
|
||||
}
|
||||
|
||||
document.querySelector('select[name="status"]').addEventListener('change', checkStatusAndPauseTimer);
|
||||
const minutesEl = document.getElementById("minutes");
|
||||
if (minutesEl) {
|
||||
minutesEl.addEventListener('change', updateTimeFromInput);
|
||||
minutesEl.addEventListener('focus', handleInputFocus);
|
||||
}
|
||||
|
||||
document.getElementById("startStopTimer").addEventListener('click', function() {
|
||||
const secondsEl = document.getElementById("seconds");
|
||||
if (secondsEl) {
|
||||
secondsEl.addEventListener('change', updateTimeFromInput);
|
||||
secondsEl.addEventListener('focus', handleInputFocus);
|
||||
}
|
||||
|
||||
const statusEl = document.querySelector('select[name="status"]');
|
||||
if (statusEl) {
|
||||
statusEl.addEventListener('change', checkStatusAndPauseTimer);
|
||||
}
|
||||
|
||||
const startStopBtn = document.getElementById("startStopTimer");
|
||||
if (startStopBtn) {
|
||||
startStopBtn.addEventListener('click', function() {
|
||||
if (timerInterval === null) {
|
||||
startTimer();
|
||||
} else {
|
||||
pauseTimer();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById("resetTimer").addEventListener('click', function() {
|
||||
const resetBtn = document.getElementById("resetTimer");
|
||||
if (resetBtn) {
|
||||
resetBtn.addEventListener('click', function() {
|
||||
resetTimer();
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById("ticket_add_reply").addEventListener('click', function() {
|
||||
const addReplyBtn = document.getElementById("ticket_add_reply");
|
||||
if (addReplyBtn) {
|
||||
addReplyBtn.addEventListener('click', function() {
|
||||
setTimeout(forceResetTimer, 100);
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById("ticket_close").addEventListener('click', function() {
|
||||
const closeBtn = document.getElementById("ticket_close");
|
||||
if (closeBtn) {
|
||||
closeBtn.addEventListener('click', function() {
|
||||
setTimeout(clearTimeStorage, 100);
|
||||
});
|
||||
}
|
||||
|
||||
// Final initialization logic
|
||||
try {
|
||||
displayTime();
|
||||
|
||||
// If no timer state, respect ticketAutoStart
|
||||
if (!localStorage.getItem(getLocalStorageKey("startTime")) && !localStorage.getItem(getLocalStorageKey("pausedTime"))) {
|
||||
if (ticketAutoStart === 1) {
|
||||
if (typeof ticketAutoStart !== "undefined" && ticketAutoStart === 1) {
|
||||
startTimer();
|
||||
} else {
|
||||
pauseTimer();
|
||||
}
|
||||
}
|
||||
// If timer already running, resume it
|
||||
else if (localStorage.getItem(getLocalStorageKey("startTime"))) {
|
||||
} else if (localStorage.getItem(getLocalStorageKey("startTime"))) {
|
||||
startTimer();
|
||||
}
|
||||
|
||||
// Check and pause timer if status is pending
|
||||
checkStatusAndPauseTimer();
|
||||
|
||||
} catch (error) {
|
||||
|
||||
@@ -79,7 +79,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<h3 class="card-title mt-2"><i class="fa fa-fw fa-map-marker-alt mr-2"></i>Locations</h3>
|
||||
<div class="card-tools">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addLocationModal">
|
||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/location/location_add.php?<?= $client_url ?>">
|
||||
<i class="fas fa-plus mr-2"></i>New Location
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
|
||||
@@ -180,7 +180,9 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>)
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#bulkAssignTagsModal">
|
||||
<a class="dropdown-item ajax-modal" href="#"
|
||||
data-modal-url="modals/location/location_bulk_assign_tags.php"
|
||||
data-bulk="true">
|
||||
<i class="fas fa-fw fa-tags mr-2"></i>Assign Tags
|
||||
</a>
|
||||
<?php if ($archived) { ?>
|
||||
@@ -393,10 +395,8 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php require_once "modals/location/location_bulk_assign_tags.php"; ?>
|
||||
</form>
|
||||
<?php require_once "../includes/filter_footer.php";
|
||||
?>
|
||||
<?php require_once "../includes/filter_footer.php"; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -404,7 +404,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
|
||||
<?php
|
||||
|
||||
require_once "modals/location/location_add.php";
|
||||
require_once "modals/location/location_import.php";
|
||||
require_once "modals/location/location_export.php";
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
<div class="modal" id="addAccountModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<?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-piggy-bank mr-2"></i>New Account</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
@@ -57,7 +61,7 @@
|
||||
<button type="submit" name="add_account" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,15 +1,44 @@
|
||||
<div class="modal" id="addAssetModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-desktop mr-2"></i>New <?php if (!empty($_GET['type'])) { echo ucwords(strip_tags($_GET['type'])); }else{ echo "Asset"; } ?></h5>
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$client_id = intval($_GET['client_id'] ?? 0);
|
||||
$contact_id = intval($_GET['contact_id'] ?? 0);
|
||||
$type = nullable_htmlentities($_GET['type'] ?? '');
|
||||
|
||||
if ($client_id) {
|
||||
$sql_network_select = mysqli_query($mysqli, "SELECT * FROM networks WHERE network_archived_at IS NULL AND network_client_id = $client_id ORDER BY network_name ASC");
|
||||
$sql_vendor_select = mysqli_query($mysqli, "SELECT * FROM vendors WHERE vendor_archived_at IS NULL AND vendor_client_id = $client_id ORDER BY vendor_name ASC");
|
||||
$sql_location_select = mysqli_query($mysqli, "SELECT location_id, location_name FROM locations WHERE location_archived_at IS NULL AND location_client_id = $client_id ORDER BY location_name ASC");
|
||||
$sql_contact_select = mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_archived_at IS NULL AND contact_client_id = $client_id ORDER BY contact_name ASC");
|
||||
} else {
|
||||
$sql_client_select = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE client_archived_at IS NULL $access_permission_query ORDER BY client_name ASC");
|
||||
}
|
||||
|
||||
// OS typeahead suggestions
|
||||
$os_sql = mysqli_query($mysqli, "SELECT DISTINCT asset_os AS label FROM assets WHERE asset_archived_at IS NULL");
|
||||
if ($os_sql && mysqli_num_rows($os_sql) > 0) {
|
||||
$os_arr = [];
|
||||
while ($row = mysqli_fetch_assoc($os_sql)) {
|
||||
// jQuery UI Autocomplete expects {label: "...", value: "..."}
|
||||
$label = $row['label'];
|
||||
$os_arr[] = ['label' => $label, 'value' => $label];
|
||||
}
|
||||
$json_os = json_encode($os_arr);
|
||||
}
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-desktop mr-2"></i>New <?php if ($type) { echo ucwords($type); } else { echo "Asset"; } ?></h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||
|
||||
<div class="modal-body ui-front">
|
||||
|
||||
@@ -40,8 +69,8 @@
|
||||
|
||||
<div class="tab-pane fade show active" id="pills-asset-details">
|
||||
|
||||
<?php if ($client_url) { ?>
|
||||
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
|
||||
<?php if ($client_id) { ?>
|
||||
<input type="hidden" name="client_id" value="<?= $client_id ?>">
|
||||
<?php } else { ?>
|
||||
|
||||
<div class="form-group">
|
||||
@@ -54,11 +83,10 @@
|
||||
<option value="">- Select Client -</option>
|
||||
<?php
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE client_archived_at IS NULL $access_permission_query ORDER BY client_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql)) {
|
||||
$client_id = intval($row['client_id']);
|
||||
while ($row = mysqli_fetch_array($sql_client_select)) {
|
||||
$client_id_select = intval($row['client_id']);
|
||||
$client_name = nullable_htmlentities($row['client_name']); ?>
|
||||
<option <?php if ($client_id == isset($_GET['client'])) { echo "selected"; } ?> value="<?php echo $client_id; ?>"><?php echo $client_name; ?></option>
|
||||
<option <?php if ($client_id == $client_id_select) { echo "selected"; } ?> value="<?= $client_id_select ?>"><?= $client_name ?></option>
|
||||
|
||||
<?php } ?>
|
||||
</select>
|
||||
@@ -96,14 +124,14 @@
|
||||
<select class="form-control select2" name="type" required>
|
||||
<option value="">- Select Type -</option>
|
||||
<?php foreach($asset_types_array as $asset_type => $asset_icon) { ?>
|
||||
<option><?php echo $asset_type; ?></option>
|
||||
<option><?= $asset_type ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php //Do not display Make Model or Serial if Virtual is selected
|
||||
if ($_GET['type'] !== 'virtual') { ?>
|
||||
if ($type !== 'virtual') { ?>
|
||||
<div class="form-group">
|
||||
<label>Make</label>
|
||||
<div class="input-group">
|
||||
@@ -135,7 +163,7 @@
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<?php if ($_GET['type'] !== 'network' && $_GET['type'] !== 'other') { ?>
|
||||
<?php if ($type !== 'network' && $type !== 'other') { ?>
|
||||
<div class="form-group">
|
||||
<label>Operating System</label>
|
||||
<div class="input-group">
|
||||
@@ -150,7 +178,7 @@
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-asset-network">
|
||||
<?php if ($client_url) { ?>
|
||||
<?php if ($client_id) { ?>
|
||||
<div class="form-group">
|
||||
<label>Network</label>
|
||||
<div class="input-group">
|
||||
@@ -161,14 +189,13 @@
|
||||
<option value="">- Select Network -</option>
|
||||
<?php
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM networks WHERE network_archived_at IS NULL AND network_client_id = $client_id ORDER BY network_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql)) {
|
||||
while ($row = mysqli_fetch_array($sql_network_select)) {
|
||||
$network_id = intval($row['network_id']);
|
||||
$network_name = nullable_htmlentities($row['network_name']);
|
||||
$network = nullable_htmlentities($row['network']);
|
||||
|
||||
?>
|
||||
<option value="<?php echo $network_id; ?>"><?php echo $network_name; ?> - <?php echo $network; ?></option>
|
||||
<option value="<?= $network_id ?>"><?= $network_name ?> - <?= $network ?></option>
|
||||
|
||||
<?php } ?>
|
||||
</select>
|
||||
@@ -265,7 +292,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($client_url) { ?>
|
||||
<?php if ($client_id) { ?>
|
||||
<div class="form-group">
|
||||
<label>Location</label>
|
||||
<div class="input-group">
|
||||
@@ -276,12 +303,11 @@
|
||||
<option value="">- Select Location -</option>
|
||||
<?php
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM locations WHERE location_archived_at IS NULL AND location_client_id = $client_id ORDER BY location_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql)) {
|
||||
while ($row = mysqli_fetch_array($sql_location_select)) {
|
||||
$location_id = intval($row['location_id']);
|
||||
$location_name = nullable_htmlentities($row['location_name']);
|
||||
?>
|
||||
<option value="<?php echo $location_id; ?>"><?php echo $location_name; ?></option>
|
||||
<option value="<?= $location_id ?>"><?= $location_name ?></option>
|
||||
<?php } ?>
|
||||
|
||||
</select>
|
||||
@@ -298,16 +324,15 @@
|
||||
<option value="">- Select Contact -</option>
|
||||
<?php
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_archived_at IS NULL AND contact_client_id = $client_id ORDER BY contact_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql)) {
|
||||
$contact_id = intval($row['contact_id']);
|
||||
while ($row = mysqli_fetch_array($sql_contact_select)) {
|
||||
$contact_id_select = intval($row['contact_id']);
|
||||
$contact_name = nullable_htmlentities($row['contact_name']);
|
||||
?>
|
||||
<option
|
||||
<?php if (isset($_GET['contact_id']) && $contact_id == intval($_GET['contact_id'])) {
|
||||
<?php if ($contact_id == $contact_id_select) {
|
||||
echo "selected"; }
|
||||
?>
|
||||
value="<?php echo $contact_id; ?>"><?php echo $contact_name; ?>
|
||||
value="<?= $contact_id_select ?>"><?= $contact_name ?>
|
||||
</option>
|
||||
|
||||
<?php } ?>
|
||||
@@ -336,7 +361,7 @@
|
||||
|
||||
<div class="tab-pane fade" id="pills-asset-purchase">
|
||||
|
||||
<?php if ($client_url) { ?>
|
||||
<?php if ($client_id) { ?>
|
||||
<div class="form-group">
|
||||
<label>Vendor</label>
|
||||
<div class="input-group">
|
||||
@@ -347,8 +372,7 @@
|
||||
<option value="">- Select Vendor -</option>
|
||||
<?php
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM vendors WHERE vendor_archived_at IS NULL AND vendor_client_id = $client_id ORDER BY vendor_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql)) {
|
||||
while ($row = mysqli_fetch_array($sql_vendor_select)) {
|
||||
$vendor_id = intval($row['vendor_id']);
|
||||
$vendor_name = nullable_htmlentities($row['vendor_name']);
|
||||
?>
|
||||
@@ -360,7 +384,7 @@
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<?php if ($_GET['type'] !== 'virtual') { ?>
|
||||
<?php if ($type !== 'virtual') { ?>
|
||||
<div class="form-group">
|
||||
<label>Purchase Reference</label>
|
||||
<div class="input-group">
|
||||
@@ -392,7 +416,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($_GET['type'] !== 'virtual') { ?>
|
||||
<?php if ($type !== 'virtual') { ?>
|
||||
<div class="form-group">
|
||||
<label>Warranty Expire</label>
|
||||
<div class="input-group">
|
||||
@@ -449,7 +473,24 @@
|
||||
<button type="submit" name="add_asset" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- JSON Autocomplete / type ahead -->
|
||||
<link rel="stylesheet" href="/plugins/jquery-ui/jquery-ui.min.css">
|
||||
<script src="/plugins/jquery-ui/jquery-ui.min.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
var operatingSystems = <?php echo $json_os; ?>;
|
||||
$("#os").autocomplete({
|
||||
source: operatingSystems, // Should be an array of objects with 'label' and 'value'
|
||||
select: function(event, ui) {
|
||||
$("#os").val(ui.item.label); // Set the input field value to the selected label
|
||||
return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,12 +1,25 @@
|
||||
<div class="modal" id="bulkAddTicketModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-life-ring mr-2"></i>Creating Tickets for Assets</h5>
|
||||
<?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="fas fa-fw fa-life-ring mr-2"></i>Create Tickets for <strong><?= $count ?></strong> Assets</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
</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">
|
||||
|
||||
@@ -16,12 +29,12 @@
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="bulk_subject" placeholder="Asset Name will be prepended to Subject" maxlength="200">
|
||||
<input type="text" class="form-control" name="bulk_subject" placeholder="Asset Name will be prepended to Subject" maxlength="200" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<textarea class="form-control tinymceTicket<?php if($config_ai_enable) { echo "AI"; } ?>" id="textInput" name="bulk_details"></textarea>
|
||||
<textarea class="form-control tinymceTicket" id="textInput" name="bulk_details"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
@@ -33,7 +46,7 @@
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-thermometer-half"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="bulk_priority">
|
||||
<select class="form-control select2" name="bulk_priority" required>
|
||||
<option>Low</option>
|
||||
<option>Medium</option>
|
||||
<option>High</option>
|
||||
@@ -52,7 +65,7 @@
|
||||
<select class="form-control select2" name="bulk_category">
|
||||
<option value="0">- Not Categorized -</option>
|
||||
<?php
|
||||
$sql_categories = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Ticket' AND category_archived_at IS NULL");
|
||||
$sql_categories = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Ticket' AND category_archived_at IS NULL ORDER BY category_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_categories)) {
|
||||
$category_id = intval($row['category_id']);
|
||||
$category_name = nullable_htmlentities($row['category_name']);
|
||||
@@ -81,7 +94,7 @@
|
||||
$sql = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT user_id, user_name FROM users
|
||||
WHERE user_role_id > 1 AND user_status = 1 AND user_archived_at IS NULL ORDER BY user_name ASC"
|
||||
WHERE user_type = 1 AND user_status = 1 AND user_archived_at IS NULL ORDER BY user_name ASC"
|
||||
);
|
||||
while ($row = mysqli_fetch_array($sql)) {
|
||||
$user_id = intval($row['user_id']);
|
||||
@@ -125,10 +138,10 @@
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="bulk_add_asset_ticket" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</button>
|
||||
<button type="submit" name="bulk_add_asset_ticket" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create Tickets</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,17 +1,30 @@
|
||||
<div class="modal" id="bulkAssignContactModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-user-check mr-2"></i>Bulk Assign Contact</h5>
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$client_id = intval($_GET['client_id']);
|
||||
$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-user-check mr-2"></i>Assign Contact to <strong><?= $count ?></strong> Assets</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
</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">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Assign To</label>
|
||||
<label>Contact</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
|
||||
@@ -36,9 +49,10 @@
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="bulk_assign_asset_contact" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Assign</button>
|
||||
<button type="submit" name="bulk_assign_asset_contact" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Assign Contact</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,12 +1,26 @@
|
||||
<div class="modal" id="bulkAssignLocationModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-map-marker-alt mr-2"></i>Bulk Assign Location</h5>
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$client_id = intval($_GET['client_id']);
|
||||
$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-map-marker-alt mr-2"></i>Assign Location to <strong><?= $count ?></strong> Assets</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
</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">
|
||||
|
||||
@@ -35,9 +49,10 @@
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="bulk_assign_asset_location" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Assign</button>
|
||||
<button type="submit" name="bulk_assign_asset_location" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Assign Location</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,13 +1,24 @@
|
||||
<div class="modal" id="bulkAssignPhysicalLocationModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-map-marker-alt mr-2"></i>Bulk Set Physical Location</h5>
|
||||
<?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-map-marker-alt mr-2"></i>Set Physical Location for <strong><?= $count ?></strong> Assets</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</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">
|
||||
|
||||
<div class="form-group">
|
||||
@@ -23,9 +34,10 @@
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="bulk_assign_asset_physical_location" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Assign</button>
|
||||
<button type="submit" name="bulk_assign_asset_physical_location" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Set Physical Location</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,13 +1,25 @@
|
||||
<div class="modal" id="bulkEditStatusModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-info mr-2"></i>Bulk Edit Status</h5>
|
||||
<?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-info mr-2"></i>Set Status for <strong><?= $count ?></strong> Assets</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
</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">
|
||||
|
||||
<div class="form-group">
|
||||
@@ -28,9 +40,10 @@
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="bulk_edit_asset_status" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Set</button>
|
||||
<button type="submit" name="bulk_edit_asset_status" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Set Status</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,25 +1,36 @@
|
||||
<?php
|
||||
if ($client_url) {
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
|
||||
$count = count($selected_ids);
|
||||
|
||||
$client_id = intval($_GET['client_id'] ?? 0);
|
||||
if ($client_id) {
|
||||
$client_select_query = "AND client_id != $client_id";
|
||||
} else {
|
||||
$client_select_query = '';
|
||||
}
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
|
||||
<div class="modal" id="bulkTransferAssetClientModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-exchange mr-2"></i>Transferring Asset(s)</h5>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-exchange-alt mr-2"></i>Transfer <strong><?= $count ?></strong> Asset(s) to Client</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
</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">
|
||||
|
||||
<div class="form-group">
|
||||
<label>New Client <strong class="text-danger">*</strong></label>
|
||||
<label>Client <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-users"></i></span>
|
||||
@@ -48,9 +59,10 @@ if ($client_url) {
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="bulk_transfer_client_asset" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Transfer</button>
|
||||
<button type="submit" name="bulk_transfer_client_asset" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Transfer to Client</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -53,37 +53,38 @@ $sql_asset_history = mysqli_query($mysqli, "SELECT * FROM asset_history
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class='fa fa-fw fa-<?php echo $device_icon; ?> mr-2'></i>Editing asset: <strong><?php echo $asset_name; ?></strong></h5>
|
||||
<h5 class="modal-title"><i class='fa fa-fw fa-<?= $device_icon ?> mr-2'></i>Editing asset: <strong><?= $asset_name ?></strong></h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<input type="hidden" name="asset_id" value="<?php echo $asset_id; ?>">
|
||||
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
|
||||
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||
<input type="hidden" name="asset_id" value="<?= $asset_id ?>">
|
||||
<input type="hidden" name="client_id" value="<?= $client_id ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<ul class="nav nav-pills nav-justified mb-3">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-toggle="pill" href="#pills-details<?php echo $asset_id; ?>">Details</a>
|
||||
<a class="nav-link active" data-toggle="pill" href="#pills-details">Details</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-network<?php echo $asset_id; ?>">Network</a>
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-network">Network</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-assignment<?php echo $asset_id; ?>">Assignment</a>
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-assignment">Assignment</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-purchase<?php echo $asset_id; ?>">Purchase</a>
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-purchase">Purchase</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-notes<?php echo $asset_id; ?>">Notes</a>
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-notes">Notes</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-history<?php echo $asset_id; ?>">History</a>
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-history">History</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -91,7 +92,7 @@ ob_start();
|
||||
|
||||
<div class="tab-content" <?php if (lookupUserPermission('module_support') <= 1) { echo 'inert'; } ?>>
|
||||
|
||||
<div class="tab-pane fade show active" id="pills-details<?php echo $asset_id; ?>">
|
||||
<div class="tab-pane fade show active" id="pills-details">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Name <strong class="text-danger">*</strong></label>
|
||||
@@ -99,7 +100,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" placeholder="Name the asset" maxlength="200" value="<?php echo $asset_name; ?>" required>
|
||||
<input type="text" class="form-control" name="name" placeholder="Name the asset" maxlength="200" value="<?= $asset_name ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -109,7 +110,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="description" placeholder="Description of the asset" maxlength="255" value="<?php echo $asset_description; ?>">
|
||||
<input type="text" class="form-control" name="description" placeholder="Description of the asset" maxlength="255" value="<?= $asset_description ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -135,7 +136,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="make" placeholder="Manufacturer" maxlength="200" value="<?php echo $asset_make; ?>">
|
||||
<input type="text" class="form-control" name="make" placeholder="Manufacturer" maxlength="200" value="<?= $asset_make ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -145,7 +146,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="model" placeholder="Model Number" maxlength="200" value="<?php echo $asset_model; ?>">
|
||||
<input type="text" class="form-control" name="model" placeholder="Model Number" maxlength="200" value="<?= $asset_model ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -155,7 +156,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="serial" placeholder="Serial number" maxlength="200" value="<?php echo $asset_serial; ?>">
|
||||
<input type="text" class="form-control" name="serial" placeholder="Serial number" maxlength="200" value="<?= $asset_serial ?>">
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
@@ -167,14 +168,14 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fab fa-fw fa-windows"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="os" placeholder="ex Windows 10 Pro" maxlength="200" value="<?php echo $asset_os; ?>">
|
||||
<input type="text" class="form-control" name="os" id="os" placeholder="ex Windows 10 Pro" maxlength="200" value="<?= $asset_os ?>">
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-network<?php echo $asset_id; ?>">
|
||||
<div class="tab-pane fade" id="pills-network">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Network</label>
|
||||
@@ -227,7 +228,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-random"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="nat_ip" value="<?php echo $asset_nat_ip; ?>" placeholder="10.52.4.55" data-inputmask="'alias': 'ip'" maxlength="200" data-mask>
|
||||
<input type="text" class="form-control" name="nat_ip" value="<?= $asset_nat_ip ?>" placeholder="10.52.4.55" data-inputmask="'alias': 'ip'" maxlength="200" data-mask>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -237,7 +238,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="ipv6" value="<?php echo $asset_ipv6; ?>" placeholder="ex. 2001:0db8:0000:0000:0000:ff00:0042:8329" maxlength="200">
|
||||
<input type="text" class="form-control" name="ipv6" value="<?= $asset_ipv6 ?>" placeholder="ex. 2001:0db8:0000:0000:0000:ff00:0042:8329" maxlength="200">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -247,7 +248,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-ethernet"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="mac" value="<?php echo $asset_mac; ?>" placeholder="MAC Address" data-inputmask="'alias': 'mac'" maxlength="200" data-mask>
|
||||
<input type="text" class="form-control" name="mac" value="<?= $asset_mac ?>" placeholder="MAC Address" data-inputmask="'alias': 'mac'" maxlength="200" data-mask>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -257,7 +258,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="uri" placeholder="URI http:// ftp:// ssh: etc" maxlength="500" value="<?php echo $asset_uri; ?>">
|
||||
<input type="text" class="form-control" name="uri" placeholder="URI http:// ftp:// ssh: etc" maxlength="500" value="<?= $asset_uri ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -282,7 +283,7 @@ ob_start();
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-assignment<?php echo $asset_id; ?>">
|
||||
<div class="tab-pane fade" id="pills-assignment">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Physical Location</label>
|
||||
@@ -290,7 +291,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-map-marker-alt"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="physical_location" placeholder="Physical location eg. Floor 2, Closet B" maxlength="200" value="<?php echo $asset_physical_location; ?>">
|
||||
<input type="text" class="form-control" name="physical_location" placeholder="Physical location eg. Floor 2, Closet B" maxlength="200" value="<?= $asset_physical_location ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -315,7 +316,7 @@ ob_start();
|
||||
$location_name_select_display = $location_name_select;
|
||||
}
|
||||
?>
|
||||
<option <?php if ($asset_location_id == $location_id_select) { echo "selected"; } ?> value="<?php echo $location_id_select; ?>"><?php echo $location_name_select_display; ?></option>
|
||||
<option <?php if ($asset_location_id == $location_id_select) { echo "selected"; } ?> value="<?= $location_id_select ?>"><?= $location_name_select_display ?></option>
|
||||
|
||||
<?php } ?>
|
||||
</select>
|
||||
@@ -343,8 +344,8 @@ ob_start();
|
||||
$contact_name_select_display = $contact_name_select;
|
||||
}
|
||||
?>
|
||||
<option <?php if ($asset_contact_id == $contact_id_select) { echo "selected"; } ?> value="<?php echo $contact_id_select; ?>">
|
||||
<?php echo $contact_name_select_display; ?>
|
||||
<option <?php if ($asset_contact_id == $contact_id_select) { echo "selected"; } ?> value="<?= $contact_id_select ?>">
|
||||
<?= $contact_name_select_display ?>
|
||||
</option>
|
||||
|
||||
<?php } ?>
|
||||
@@ -360,7 +361,7 @@ ob_start();
|
||||
</div>
|
||||
<select class="form-control select2" name="status">
|
||||
<?php foreach($asset_status_array as $asset_status_select) { ?>
|
||||
<option <?php if ($asset_status_select == $asset_status) { echo "selected"; } ?>><?php echo $asset_status_select; ?></option>
|
||||
<option <?php if ($asset_status_select == $asset_status) { echo "selected"; } ?>><?= $asset_status_select ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
@@ -368,7 +369,7 @@ ob_start();
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-purchase<?php echo $asset_id; ?>">
|
||||
<div class="tab-pane fade" id="pills-purchase">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Vendor</label>
|
||||
@@ -391,7 +392,7 @@ ob_start();
|
||||
$vendor_name_select_display = $vendor_name_select;
|
||||
}
|
||||
?>
|
||||
<option <?php if ($asset_vendor_id == $vendor_id_select) { echo "selected"; } ?> value="<?php echo $vendor_id_select; ?>"><?php echo $vendor_name_select_display; ?></option>
|
||||
<option <?php if ($asset_vendor_id == $vendor_id_select) { echo "selected"; } ?> value="<?= $vendor_id_select ?>"><?= $vendor_name_select_display ?></option>
|
||||
|
||||
<?php } ?>
|
||||
</select>
|
||||
@@ -405,7 +406,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" name="purchase_reference" placeholder="eg. Invoice, PO Number" value="<?php echo $asset_purchase_reference; ?>">
|
||||
<input type="text" class="form-control" name="purchase_reference" placeholder="eg. Invoice, PO Number" value="<?= $asset_purchase_reference ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -415,7 +416,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
|
||||
</div>
|
||||
<input type="date" class="form-control" name="purchase_date" max="2999-12-31" value="<?php echo $asset_purchase_date; ?>">
|
||||
<input type="date" class="form-control" name="purchase_date" max="2999-12-31" value="<?= $asset_purchase_date ?>">
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
@@ -426,7 +427,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-calendar-check"></i></span>
|
||||
</div>
|
||||
<input type="date" class="form-control" name="install_date" max="2999-12-31" value="<?php echo $asset_install_date; ?>">
|
||||
<input type="date" class="form-control" name="install_date" max="2999-12-31" value="<?= $asset_install_date ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -437,18 +438,18 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-calendar-times"></i></span>
|
||||
</div>
|
||||
<input type="date" class="form-control" name="warranty_expire" max="2999-12-31" value="<?php echo $asset_warranty_expire; ?>">
|
||||
<input type="date" class="form-control" name="warranty_expire" max="2999-12-31" value="<?= $asset_warranty_expire ?>">
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-notes<?php echo $asset_id; ?>">
|
||||
<div class="tab-pane fade" id="pills-notes">
|
||||
|
||||
<div class="mb-3 text-center">
|
||||
<?php if ($asset_photo) { ?>
|
||||
<img class="img-fluid" alt="asset_photo" src="<?php echo "../uploads/clients/$client_id/$asset_photo"; ?>">
|
||||
<img class="img-fluid" alt="asset_photo" src="<?= "../uploads/clients/$client_id/$asset_photo" ?>">
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
@@ -458,7 +459,7 @@ ob_start();
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<textarea class="form-control" rows="8" placeholder="Enter some notes" name="notes"><?php echo $asset_notes; ?></textarea>
|
||||
<textarea class="form-control" rows="8" placeholder="Enter some notes" name="notes"><?= $asset_notes ?></textarea>
|
||||
</div>
|
||||
|
||||
<p class="text-muted text-right">Asset ID: <?= $asset_id ?></p>
|
||||
@@ -466,7 +467,7 @@ ob_start();
|
||||
</div>
|
||||
|
||||
|
||||
<div class="tab-pane fade" id="pills-history<?php echo $asset_id; ?>">
|
||||
<div class="tab-pane fade" id="pills-history">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Asset History</label>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
|
||||
<?php } ?>
|
||||
<div class="modal-body">
|
||||
<p><strong>Format csv file with headings & data:</strong><br>Name, Description, Type, Make, Model, Serial, OS, Purchase Date, Assigned To, Location, Physical Location</p>
|
||||
<p><strong>Format csv file with headings & data:</strong><br>Name, Description, Type, Make, Model, Serial, OS, Purchase Date, Assigned To, Location, Physical Location, Notes</p>
|
||||
<hr>
|
||||
<div class="form-group my-4">
|
||||
<input type="file" class="form-control-file" name="file" accept=".csv" required>
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
<div class="modal" id="addAssetInterfaceModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$asset_id = intval($_GET['asset_id'] ?? 0);
|
||||
$client_id = intval(getFieldById('assets', $asset_id, 'asset_client_id') ?? 0);
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-ethernet mr-2"></i>New Network Interface</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="asset_id" value="<?php echo $asset_id; ?>">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
|
||||
@@ -173,18 +180,18 @@
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-desktop"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="connected_to">
|
||||
<option value="">- NSelect Asset and Interface -</option>
|
||||
<option value="">- Select Asset and Interface -</option>
|
||||
<?php
|
||||
$sql_interfaces_select = mysqli_query($mysqli, "
|
||||
SELECT i.interface_id, i.interface_name, a.asset_name
|
||||
FROM asset_interfaces i
|
||||
LEFT JOIN assets a ON a.asset_id = i.interface_asset_id
|
||||
WHERE a.asset_archived_at IS NULL
|
||||
AND a.asset_client_id = $client_id
|
||||
AND a.asset_id != $asset_id
|
||||
AND i.interface_id NOT IN (SELECT interface_a_id FROM asset_interface_links)
|
||||
AND i.interface_id NOT IN (SELECT interface_b_id FROM asset_interface_links)
|
||||
ORDER BY a.asset_name ASC, i.interface_name ASC
|
||||
SELECT interface_id, interface_name, asset_name
|
||||
FROM asset_interfaces
|
||||
LEFT JOIN assets ON asset_id = interface_asset_id
|
||||
WHERE asset_archived_at IS NULL
|
||||
AND asset_client_id = $client_id
|
||||
AND asset_id != $asset_id
|
||||
AND interface_id NOT IN (SELECT interface_a_id FROM asset_interface_links)
|
||||
AND interface_id NOT IN (SELECT interface_b_id FROM asset_interface_links)
|
||||
ORDER BY asset_name ASC, interface_name ASC
|
||||
");
|
||||
|
||||
while ($row = mysqli_fetch_array($sql_interfaces_select)) {
|
||||
@@ -218,7 +225,7 @@
|
||||
</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Close</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
<div class="modal" id="addCalendarModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<?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-calendar-plus mr-2"></i>New Calendar</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
@@ -35,7 +39,7 @@
|
||||
<button type="submit" name="add_calendar" class="btn btn-primary"><i class="fa fa-check mr-2"></i>Create</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
<div class="modal" id="addCertificateModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$client_id = intval($_GET['client_id'] ?? 0);
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-lock mr-2"></i>New Certificate</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<div class="modal-body">
|
||||
|
||||
<ul class="nav nav-pills nav-justified mb-3">
|
||||
@@ -28,7 +34,7 @@
|
||||
|
||||
<div class="tab-pane fade show active" id="pills-details">
|
||||
|
||||
<?php if ($client_url) { ?>
|
||||
<?php if ($client_id) { ?>
|
||||
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
|
||||
<?php } else { ?>
|
||||
|
||||
@@ -44,9 +50,9 @@
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE client_archived_at IS NULL $access_permission_query ORDER BY client_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql)) {
|
||||
$client_id = intval($row['client_id']);
|
||||
$client_id_select = intval($row['client_id']);
|
||||
$client_name = nullable_htmlentities($row['client_name']); ?>
|
||||
<option <?php if ($client_id == isset($_GET['client'])) { echo "selected"; } ?> value="<?php echo $client_id; ?>"><?php echo $client_name; ?></option>
|
||||
<option <?php if ($client_id == $client_id_select) { echo "selected"; } ?> value="<?php echo $client_id_select; ?>"><?php echo $client_name; ?></option>
|
||||
|
||||
<?php } ?>
|
||||
</select>
|
||||
@@ -75,7 +81,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($client_url) { ?>
|
||||
<?php if ($client_id) { ?>
|
||||
<div class="form-group">
|
||||
<label>Domain</label>
|
||||
<div class="input-group">
|
||||
@@ -160,7 +166,10 @@
|
||||
<button type="submit" name="add_certificate" class="btn btn-primary text-bold"><i class="fa fa-check"></i> Create</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script src="/agent/js/certificate_fetch_ssl.js"></script>
|
||||
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
@@ -193,5 +193,7 @@ ob_start();
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script src="/agent/js/certificate_fetch_ssl.js"></script>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,14 +1,27 @@
|
||||
<div class="modal" id="addClientModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content border-dark">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-user-plus mr-2"></i>Creating New <?php if($leads_filter == 0){ echo "Client"; } else { echo "Lead"; } ?></h5>
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
// Filters
|
||||
$leads_filter = intval($_GET['lead'] ?? 0);
|
||||
|
||||
// Selects
|
||||
$referral_sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Referral' AND category_archived_at IS NULL ORDER BY category_name ASC");
|
||||
|
||||
$sql_tags_select = mysqli_query($mysqli, "SELECT * FROM tags WHERE tag_type = 1 ORDER BY tag_name ASC");
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-user-plus mr-2"></i>New <?php if($leads_filter == 0){ echo "Client"; } else { echo "Lead"; } ?></h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="modal-header nav nav-pills nav-justified">
|
||||
<ul class="modal-header nav nav-pills nav-justified">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-toggle="pill" href="#pills-details">Details</a>
|
||||
</li>
|
||||
@@ -26,9 +39,9 @@
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-notes">Notes</a>
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
@@ -42,13 +55,16 @@
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" placeholder="Name or Company" maxlength="200" required autofocus>
|
||||
<input type="text" class="form-control" name="name" id="client_name" placeholder="Name or Company" maxlength="200" onfocusout="client_duplicate_check()" required autofocus>
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text">
|
||||
<input type="checkbox" name="lead" value="1" <?php if($leads_filter == 1){ echo "checked"; } ?>>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<span class="text-info" id="client_duplicate_info"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
@@ -81,7 +97,6 @@
|
||||
<option value="">- Select Referral -</option>
|
||||
<?php
|
||||
|
||||
$referral_sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Referral' AND category_archived_at IS NULL ORDER BY category_name ASC");
|
||||
while ($row = mysqli_fetch_array($referral_sql)) {
|
||||
$referral = nullable_htmlentities($row['category_name']); ?>
|
||||
<option><?php echo $referral; ?></option>
|
||||
@@ -116,7 +131,6 @@
|
||||
<select class="form-control select2" name="tags[]" data-placeholder="- Select Tags -"multiple>
|
||||
<?php
|
||||
|
||||
$sql_tags_select = mysqli_query($mysqli, "SELECT * FROM tags WHERE tag_type = 1 ORDER BY tag_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_tags_select)) {
|
||||
$tag_id_select = intval($row['tag_id']);
|
||||
$tag_name_select = nullable_htmlentities($row['tag_name']);
|
||||
@@ -314,21 +328,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Currency <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-money-bill"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="currency_code" required>
|
||||
<option value="">- Select Currency -</option>
|
||||
<?php foreach($currencies_array as $currency_code => $currency_name) { ?>
|
||||
<option <?php if ($session_company_currency == $currency_code) { echo "selected"; } ?> value="<?php echo $currency_code; ?>"><?php echo "$currency_code - $currency_name"; ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Payment Terms</label>
|
||||
<div class="input-group">
|
||||
@@ -366,13 +365,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_client" class="btn btn-primary text-bold" onclick="promptPrimaryContact()"><i class="fa fa-check mr-2"></i>Create</button>
|
||||
<button type="submit" name="add_client" class="btn btn-primary text-bold" onclick="promptPrimaryContact()"><i class="fa fa-check mr-2"></i>Create Client</button>
|
||||
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Close</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
// Checks/prompts that the primary contact field (required) is populated
|
||||
@@ -383,3 +379,23 @@
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
// Checks for duplicate clients
|
||||
function client_duplicate_check() {
|
||||
var name = document.getElementById("client_name").value;
|
||||
//Send a GET request to ajax.php as ajax.php?client_duplicate_check=true&name=NAME
|
||||
jQuery.get(
|
||||
"ajax.php",
|
||||
{client_duplicate_check: 'true', name: name},
|
||||
function(data) {
|
||||
//If we get a response from ajax.php, parse it as JSON
|
||||
const client_duplicate_data = JSON.parse(data);
|
||||
document.getElementById("client_duplicate_info").innerHTML = client_duplicate_data.message;
|
||||
}
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
151
agent/modals/client/client_bulk_add_ticket.php
Normal file
151
agent/modals/client/client_bulk_add_ticket.php
Normal file
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
|
||||
|
||||
$count = count($selected_ids);
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-life-ring mr-2"></i>New Tickets for <strong><?= $count ?></strong> Client(s)</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="client_ids[]" value="<?= $id ?>"><?php } ?>
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Subject <strong class="text-danger">*</strong></label>
|
||||
<input type="text" class="form-control" name="bulk_subject" placeholder="Enter a subject" maxlength="200" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<textarea class="form-control tinymceTicket" id="textInput" name="bulk_details"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col">
|
||||
<div class="form-group">
|
||||
<label>Priority <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-thermometer-half"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="bulk_priority" required>
|
||||
<option>Low</option>
|
||||
<option>Medium</option>
|
||||
<option>High</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<div class="form-group">
|
||||
<label>Category</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-layer-group"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="bulk_category">
|
||||
<option value="0">- Not Categorized -</option>
|
||||
<?php
|
||||
$sql_categories = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Ticket' AND category_archived_at IS NULL");
|
||||
while ($row = mysqli_fetch_array($sql_categories)) {
|
||||
$category_id = intval($row['category_id']);
|
||||
$category_name = nullable_htmlentities($row['category_name']);
|
||||
|
||||
?>
|
||||
<option value="<?php echo $category_id; ?>"><?php echo $category_name; ?></option>
|
||||
<?php } ?>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Assign to</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-user-check"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="bulk_assigned_to">
|
||||
<option value="0">Not Assigned</option>
|
||||
<?php
|
||||
|
||||
$sql = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT user_id, user_name FROM users
|
||||
WHERE user_role_id > 1 AND user_status = 1 AND user_archived_at IS NULL ORDER BY user_name ASC"
|
||||
);
|
||||
while ($row = mysqli_fetch_array($sql)) {
|
||||
$user_id = intval($row['user_id']);
|
||||
$user_name = nullable_htmlentities($row['user_name']); ?>
|
||||
<option value="<?php echo $user_id; ?>"><?php echo $user_name; ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Project</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-project-diagram"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="bulk_project">
|
||||
<option value="0">- None -</option>
|
||||
<?php
|
||||
|
||||
$sql_projects = mysqli_query($mysqli, "SELECT * FROM projects WHERE project_completed_at IS NULL AND project_archived_at IS NULL ORDER BY project_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_projects)) {
|
||||
$project_id_select = intval($row['project_id']);
|
||||
$project_name_select = nullable_htmlentities($row['project_name']); ?>
|
||||
<option value="<?php echo $project_id_select; ?>"><?php echo $project_name_select; ?></option>
|
||||
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($config_module_enable_accounting) { ?>
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" name="bulk_billable" <?php if ($config_ticket_default_billable == 1) { echo "checked"; } ?> value="1" id="billableSwitch">
|
||||
<label class="custom-control-label" for="billableSwitch">Billable</label>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="bulk_add_client_ticket" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
@@ -1,15 +1,28 @@
|
||||
<div class="modal" id="bulkAssignTagsModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-tags mr-2"></i>Bulk Assign Tags</h5>
|
||||
<?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> Clients</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
</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="client_ids[]" value="<?= $id ?>"><?php } ?>
|
||||
<input type="hidden" name="bulk_remove_tags" value="0">
|
||||
|
||||
<div class="modal-body">
|
||||
<input type="hidden" name="bulk_remove_tags" value="0">
|
||||
|
||||
<div class="form-group form-check">
|
||||
<input type="checkbox" class="form-check-input" name="bulk_remove_tags" value="1">
|
||||
@@ -43,6 +56,7 @@
|
||||
<button type="submit" name="bulk_assign_client_tags" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Assign</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,12 +1,25 @@
|
||||
<div class="modal" id="bulkEditHourlyRateModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-clock mr-2"></i>Bulk Edit Hourly Rate</h5>
|
||||
<?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-clock mr-2"></i>Set Hourly Rate for <strong><?= $count ?></strong> Client(s)</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
</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="client_ids[]" value="<?= $id ?>"><?php } ?>
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
@@ -16,16 +29,17 @@
|
||||
<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">
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="bulk_rate" placeholder="0.00" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="bulk_edit_client_hourly_rate" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Assign</button>
|
||||
<button type="submit" name="bulk_edit_client_hourly_rate" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
@@ -1,12 +1,25 @@
|
||||
<div class="modal" id="bulkEditIndustryModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-briefcase mr-2"></i>Bulk Edit Industry</h5>
|
||||
<?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-briefcase mr-2"></i>Set Industry for <strong><?= $count ?></strong> Client(s)</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
</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="client_ids[]" value="<?= $id ?>"><?php } ?>
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
@@ -16,16 +29,17 @@
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-briefcase"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="bulk_industry" placeholder="Enter an Industry" maxlength="200">
|
||||
<input type="text" class="form-control" name="bulk_industry" placeholder="Enter an Industry" maxlength="200" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="bulk_edit_client_industry" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Assign</button>
|
||||
<button type="submit" name="bulk_edit_client_industry" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Set</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user