Feature: On all export modals added Filter Tab and Selectable Columns tab with default selected, also you can now export to a PDF

This commit is contained in:
johnnyq
2026-07-30 00:46:15 -04:00
parent 729d22d19b
commit 3c8f812a16
61 changed files with 3997 additions and 829 deletions

View File

@@ -225,7 +225,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php if ($num_rows[0] > 0) { ?>
<a class="dropdown-item text-dark ajax-modal" href="#"
data-modal-url="modals/asset/asset_export.php?<?= $client_url ?>">
data-modal-url="<?= buildExportModalUrl('modals/asset/asset_export.php', ['client_id', 'type', 'client', 'location', 'tags', 'expire_days', 'archived', 'q']) ?>">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
<?php } ?>

View File

@@ -85,7 +85,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<a class="dropdown-item text-dark ajax-modal" href="#"\
data-modal-url="modals/certificate/certificate_export.php?<?= $client_url ?>">
data-modal-url="<?= buildExportModalUrl('modals/certificate/certificate_export.php', ['client_id', 'client', 'expire_days', 'archived', 'q']) ?>">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
</div>

View File

@@ -98,7 +98,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-dark ajax-modal" href="#"
data-modal-url="modals/client/client_export.php">
data-modal-url="<?= buildExportModalUrl('modals/client/client_export.php', ['leads', 'tags', 'industry', 'referral', 'q', 'archived'], ['dtf' => $dtf, 'dtt' => $dtt]) ?>">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
</div>

View File

@@ -105,7 +105,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<div class="dropdown-divider"></div>
<?php } ?>
<a class="dropdown-item text-dark ajax-modal" href="#"
data-modal-url="modals/contact/contact_export.php?<?= $client_url ?>">
data-modal-url="<?= buildExportModalUrl('modals/contact/contact_export.php', ['client_id', 'client', 'location', 'tags', 'archived', 'q']) ?>">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
</div>

View File

@@ -120,7 +120,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php } ?>
<?php if ($num_rows[0] > 0) { ?>
<a class="dropdown-item text-dark ajax-modal" href="#"
data-modal-url="modals/credential/credential_export.php?<?= $client_url ?>">
data-modal-url="<?= buildExportModalUrl('modals/credential/credential_export.php', ['client_id', 'client', 'tags', 'archived', 'q']) ?>">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
<?php } ?>

View File

@@ -97,7 +97,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<a class="dropdown-item text-dark ajax-modal" href="#"
data-modal-url="modals/domain/domain_export.php?<?= $client_url ?>">
data-modal-url="<?= buildExportModalUrl('modals/domain/domain_export.php', ['client_id', 'client', 'expire_days', 'archived', 'q']) ?>">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
</div>

View File

@@ -69,7 +69,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<a class="dropdown-item text-dark ajax-modal" href="#"
data-modal-url="modals/expense/expense_export.php">
data-modal-url="<?= buildExportModalUrl('modals/expense/expense_export.php', ['account', 'vendor', 'category', 'q'], ['dtf' => $dtf, 'dtt' => $dtt]) ?>">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
</div>

View File

@@ -171,7 +171,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<a class="dropdown-item text-dark ajax-modal" href="#"
data-modal-url="modals/invoice/invoice_export.php?<?= $client_url ?>">
data-modal-url="<?= buildExportModalUrl('modals/invoice/invoice_export.php', ['client_id', 'status', 'category', 'q'], ['dtf' => $dtf, 'dtt' => $dtt]) ?>">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
</div>

View File

@@ -91,7 +91,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php if ($num_rows[0] > 0) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-dark ajax-modal" href="#"
data-modal-url="modals/location/location_export.php?<?= $client_url ?>">
data-modal-url="<?= buildExportModalUrl('modals/location/location_export.php', ['client_id', 'client', 'tags', 'archived', 'q']) ?>">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
<?php } ?>

View File

@@ -2,28 +2,187 @@
require_once '../../../includes/modal_header.php';
enforceUserPermission('module_support');
// Pre-filled from the assets page's current filters. Everything here is editable -
// the export runs whatever this form posts, not whatever the page happened to show.
$client_id = intval($_GET['client_id'] ?? 0);
if ($client_id) {
enforceClientAccess();
}
// Search Filter
$q_filter = $_GET['q'] ?? '';
// Type Filter
$type_filter = $_GET['type'] ?? '';
// Client Filter
$client_filter = intval($_GET['client'] ?? 0);
// Location Filter
$location_filter = intval($_GET['location'] ?? 0);
// Tags Filter
$tag_filter = (isset($_GET['tags']) && is_array($_GET['tags'])) ? array_map('intval', $_GET['tags']) : [];
// Expiring In Filter
$expire_filter = $_GET['expire_days'] ?? '';
// Archived Filter
$archived_filter = (isset($_GET['archived']) && $_GET['archived'] == 1) ? 1 : 0;
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Assets to CSV</h5>
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Assets</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<?php exportTabsNav(); ?>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="client_id" value="<?= $client_id ?>">
<div class="modal-body">
<?php exportTabsFiltersOpen(); ?>
<div class="form-group">
<label>Search</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-search"></i></span>
</div>
<input type="text" class="form-control" name="q" value="<?= stripslashes(escapeHtml($q_filter)) ?>" placeholder="Name, serial, IP, OS">
</div>
</div>
<div class="form-group">
<label>Type</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-desktop"></i></span>
</div>
<select class="form-control select2" name="type">
<option value="">- All Types -</option>
<option <?php if ($type_filter === 'workstation') { echo "selected"; } ?> value="workstation">Workstations</option>
<option <?php if ($type_filter === 'server') { echo "selected"; } ?> value="server">Servers</option>
<option <?php if ($type_filter === 'virtual') { echo "selected"; } ?> value="virtual">Virtual Machines</option>
<option <?php if ($type_filter === 'network') { echo "selected"; } ?> value="network">Network Devices</option>
<option <?php if ($type_filter === 'other') { echo "selected"; } ?> value="other">Other</option>
</select>
</div>
</div>
<?php if (!$client_id) { ?>
<div class="form-group">
<label>Client</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<select class="form-control select2" name="client">
<option value="">- All Clients -</option>
<?php
$sql_clients_filter = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE EXISTS (SELECT 1 FROM assets WHERE asset_client_id = client_id) ORDER BY client_name ASC");
while ($row = mysqli_fetch_assoc($sql_clients_filter)) {
$filter_client_id = intval($row['client_id']);
$filter_client_name = escapeHtml($row['client_name']);
?>
<option <?php if ($client_filter == $filter_client_id) { echo "selected"; } ?> value="<?= $filter_client_id ?>"><?= $filter_client_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<?php } ?>
<?php if ($client_id) { ?>
<div class="form-group">
<label>Location</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-map-marker-alt"></i></span>
</div>
<select class="form-control select2" name="location">
<option value="">- All Locations -</option>
<?php
$sql_locations_filter = mysqli_query($mysqli, "SELECT location_id, location_name FROM locations WHERE location_client_id = $client_id AND location_archived_at IS NULL ORDER BY location_name ASC");
while ($row = mysqli_fetch_assoc($sql_locations_filter)) {
$filter_location_id = intval($row['location_id']);
$filter_location_name = escapeHtml($row['location_name']);
?>
<option <?php if ($location_filter == $filter_location_id) { echo "selected"; } ?> value="<?= $filter_location_id ?>"><?= $filter_location_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<?php } ?>
<div class="form-group">
<label>Tags</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tags"></i></span>
</div>
<select class="form-control select2" name="tags[]" data-placeholder="- All Tags -" multiple>
<?php
$sql_tags_filter = mysqli_query($mysqli, "SELECT tag_id, tag_name FROM tags WHERE tag_type = 5 ORDER BY tag_name ASC");
while ($row = mysqli_fetch_assoc($sql_tags_filter)) {
$filter_tag_id = intval($row['tag_id']);
$filter_tag_name = escapeHtml($row['tag_name']);
?>
<option <?php if (in_array($filter_tag_id, $tag_filter, true)) { echo "selected"; } ?> value="<?= $filter_tag_id ?>"><?= $filter_tag_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<div class="form-group">
<label>Warranty Expiring In</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-hourglass-half"></i></span>
</div>
<select class="form-control select2" name="expire_days">
<option value="">- Any -</option>
<option <?php if ($expire_filter === 'expired') { echo "selected"; } ?> value="expired">Expired</option>
<?php foreach ([7, 30, 45, 60, 90] as $expire_option) { ?>
<option <?php if ($expire_filter !== '' && $expire_filter == $expire_option) { echo "selected"; } ?> value="<?= $expire_option ?>"><?= $expire_option ?> Days</option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group">
<label>Archived</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-archive"></i></span>
</div>
<select class="form-control select2" name="archived">
<option <?php if (!$archived_filter) { echo "selected"; } ?> value="0">Active only</option>
<option <?php if ($archived_filter) { echo "selected"; } ?> value="1">Archived only</option>
</select>
</div>
</div>
<?php exportTabsColumns('assets'); ?>
</div>
<div class="modal-footer">
<button type="submit" name="export_assets_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
<?php renderExportButtons('export_assets'); ?>
</div>
</form>

View File

@@ -2,7 +2,7 @@
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Interfaces to CSV</h5>
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Interfaces</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
@@ -13,10 +13,11 @@
<div class="modal-body">
<?php renderExportColumnPicker('asset_interfaces'); ?>
</div>
<div class="modal-footer">
<button type="submit" name="export_client_asset_interfaces_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
<?php renderExportButtons('export_asset_interfaces'); ?>
</div>
</form>
</div>

View File

@@ -2,27 +2,116 @@
require_once '../../../includes/modal_header.php';
enforceUserPermission('module_support');
// Pre-filled from the certificates page's current filters. Everything here is editable -
// the export runs whatever this form posts, not whatever the page happened to show.
$client_id = intval($_GET['client_id'] ?? 0);
if ($client_id) {
enforceClientAccess();
}
// Search Filter
$q_filter = $_GET['q'] ?? '';
// Client Filter
$client_filter = intval($_GET['client'] ?? 0);
// Expiring In Filter
$expire_filter = $_GET['expire_days'] ?? '';
// Archived Filter
$archived_filter = (isset($_GET['archived']) && $_GET['archived'] == 1) ? 1 : 0;
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Certificates to CSV</h5>
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Certificates</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<?php exportTabsNav(); ?>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="client_id" value="<?= $client_id ?>">
<div class="modal-body">
<?php exportTabsFiltersOpen(); ?>
<div class="form-group">
<label>Search</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-search"></i></span>
</div>
<input type="text" class="form-control" name="q" value="<?= stripslashes(escapeHtml($q_filter)) ?>" placeholder="Name, domain, issuer">
</div>
</div>
<?php if (!$client_id) { ?>
<div class="form-group">
<label>Client</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<select class="form-control select2" name="client">
<option value="">- All Clients -</option>
<?php
$sql_clients_filter = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE EXISTS (SELECT 1 FROM certificates WHERE certificate_client_id = client_id) ORDER BY client_name ASC");
while ($row = mysqli_fetch_assoc($sql_clients_filter)) {
$filter_client_id = intval($row['client_id']);
$filter_client_name = escapeHtml($row['client_name']);
?>
<option <?php if ($client_filter == $filter_client_id) { echo "selected"; } ?> value="<?= $filter_client_id ?>"><?= $filter_client_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<?php } ?>
<div class="form-group">
<label>Expiring In</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-hourglass-half"></i></span>
</div>
<select class="form-control select2" name="expire_days">
<option value="">- Any -</option>
<option <?php if ($expire_filter === 'expired') { echo "selected"; } ?> value="expired">Expired</option>
<?php foreach ([7, 30, 45, 60, 90] as $expire_option) { ?>
<option <?php if ($expire_filter !== '' && $expire_filter == $expire_option) { echo "selected"; } ?> value="<?= $expire_option ?>"><?= $expire_option ?> Days</option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group">
<label>Archived</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-archive"></i></span>
</div>
<select class="form-control select2" name="archived">
<option <?php if (!$archived_filter) { echo "selected"; } ?> value="0">Active only</option>
<option <?php if ($archived_filter) { echo "selected"; } ?> value="1">Archived only</option>
</select>
</div>
</div>
<?php exportTabsColumns('certificates'); ?>
</div>
<div class="modal-footer">
<button type="submit" name="export_certificates_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
<?php renderExportButtons('export_certificates'); ?>
</div>
</form>

View File

@@ -2,23 +2,181 @@
require_once '../../../includes/modal_header.php';
enforceUserPermission('module_client');
// Pre-filled from the clients page's current filters. Everything here is editable -
// the export runs whatever this form posts, not whatever the page happened to show.
$client_id = intval($_GET['client_id'] ?? 0);
if ($client_id) {
enforceClientAccess();
}
// Search Filter
$q_filter = $_GET['q'] ?? '';
// Showing Filter
$leads_filter = $_GET['leads'] ?? '';
// Industry Filter
$industry_filter = $_GET['industry'] ?? '';
// Referral Filter
$referral_filter = $_GET['referral'] ?? '';
// Tags Filter
$tag_filter = (isset($_GET['tags']) && is_array($_GET['tags'])) ? array_map('intval', $_GET['tags']) : [];
// Date Filter - the all-time sentinels from filter_header.php leave the fields blank
$date_from_filter = (!empty($_GET['dtf']) && $_GET['dtf'] !== '1970-01-01') ? escapeHtml($_GET['dtf']) : '';
$date_to_filter = (!empty($_GET['dtt']) && $_GET['dtt'] !== '2099-12-31') ? escapeHtml($_GET['dtt']) : '';
// Archived Filter
$archived_filter = (isset($_GET['archived']) && $_GET['archived'] == 1) ? 1 : 0;
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Clients to CSV</h5>
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Clients</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<?php exportTabsNav(); ?>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="modal-body">
<?php exportTabsFiltersOpen(); ?>
<div class="form-group">
<label>Search</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-search"></i></span>
</div>
<input type="text" class="form-control" name="q" value="<?= stripslashes(escapeHtml($q_filter)) ?>" placeholder="Name, contact, address, tag">
</div>
</div>
<div class="form-group">
<label>Showing</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user-friends"></i></span>
</div>
<select class="form-control select2" name="leads">
<option value="">- Clients -</option>
<option <?php if ($leads_filter === '1') { echo "selected"; } ?> value="1">Leads</option>
</select>
</div>
</div>
<div class="form-group">
<label>Industry</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-industry"></i></span>
</div>
<select class="form-control select2" name="industry">
<option value="">- All Industries -</option>
<?php
$sql_industry_filter = mysqli_query($mysqli, "SELECT DISTINCT client_type FROM clients WHERE client_type != '' ORDER BY client_type ASC");
while ($row = mysqli_fetch_assoc($sql_industry_filter)) {
$filter_industry = escapeHtml($row['client_type']);
?>
<option <?php if ($industry_filter === $row['client_type']) { echo "selected"; } ?> value="<?= $filter_industry ?>"><?= $filter_industry ?></option>
<?php
}
?>
</select>
</div>
</div>
<div class="form-group">
<label>Referral</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-share-alt"></i></span>
</div>
<select class="form-control select2" name="referral">
<option value="">- All Referrals -</option>
<?php
$sql_referral_filter = mysqli_query($mysqli, "SELECT DISTINCT client_referral FROM clients WHERE client_referral != '' ORDER BY client_referral ASC");
while ($row = mysqli_fetch_assoc($sql_referral_filter)) {
$filter_referral = escapeHtml($row['client_referral']);
?>
<option <?php if ($referral_filter === $row['client_referral']) { echo "selected"; } ?> value="<?= $filter_referral ?>"><?= $filter_referral ?></option>
<?php
}
?>
</select>
</div>
</div>
<div class="form-group">
<label>Tags</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tags"></i></span>
</div>
<select class="form-control select2" name="tags[]" data-placeholder="- All Tags -" multiple>
<?php
$sql_tags_filter = mysqli_query($mysqli, "SELECT tag_id, tag_name FROM tags WHERE tag_type = 1 ORDER BY tag_name ASC");
while ($row = mysqli_fetch_assoc($sql_tags_filter)) {
$filter_tag_id = intval($row['tag_id']);
$filter_tag_name = escapeHtml($row['tag_name']);
?>
<option <?php if (in_array($filter_tag_id, $tag_filter, true)) { echo "selected"; } ?> value="<?= $filter_tag_id ?>"><?= $filter_tag_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<div class="form-group">
<label>Created From</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="date" class="form-control" name="dtf" value="<?= $date_from_filter ?>" max="2999-12-31">
</div>
</div>
<div class="form-group">
<label>Created To</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="date" class="form-control" name="dtt" value="<?= $date_to_filter ?>" max="2999-12-31">
</div>
</div>
<div class="form-group">
<label>Archived</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-archive"></i></span>
</div>
<select class="form-control select2" name="archived">
<option <?php if (!$archived_filter) { echo "selected"; } ?> value="0">Active only</option>
<option <?php if ($archived_filter) { echo "selected"; } ?> value="1">Archived only</option>
</select>
</div>
</div>
<?php exportTabsColumns('clients'); ?>
</div>
<div class="modal-footer">
<button type="submit" name="export_clients_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
<?php renderExportButtons('export_clients'); ?>
</div>
</form>

View File

@@ -2,28 +2,148 @@
require_once '../../../includes/modal_header.php';
enforceUserPermission('module_client');
// Pre-filled from the contacts page's current filters. Everything here is editable -
// the export runs whatever this form posts, not whatever the page happened to show.
$client_id = intval($_GET['client_id'] ?? 0);
if ($client_id) {
enforceClientAccess();
}
// Search Filter
$q_filter = $_GET['q'] ?? '';
// Client Filter
$client_filter = intval($_GET['client'] ?? 0);
// Location Filter
$location_filter = intval($_GET['location'] ?? 0);
// Tags Filter
$tag_filter = (isset($_GET['tags']) && is_array($_GET['tags'])) ? array_map('intval', $_GET['tags']) : [];
// Archived Filter
$archived_filter = (isset($_GET['archived']) && $_GET['archived'] == 1) ? 1 : 0;
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Contacts to CSV</h5>
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Contacts</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<?php exportTabsNav(); ?>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="client_id" value="<?= $client_id ?>">
<div class="modal-body">
<?php exportTabsFiltersOpen(); ?>
<div class="form-group">
<label>Search</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-search"></i></span>
</div>
<input type="text" class="form-control" name="q" value="<?= stripslashes(escapeHtml($q_filter)) ?>" placeholder="Name, title, email, phone">
</div>
</div>
<?php if (!$client_id) { ?>
<div class="form-group">
<label>Client</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<select class="form-control select2" name="client">
<option value="">- All Clients -</option>
<?php
$sql_clients_filter = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE EXISTS (SELECT 1 FROM contacts WHERE contact_client_id = client_id) ORDER BY client_name ASC");
while ($row = mysqli_fetch_assoc($sql_clients_filter)) {
$filter_client_id = intval($row['client_id']);
$filter_client_name = escapeHtml($row['client_name']);
?>
<option <?php if ($client_filter == $filter_client_id) { echo "selected"; } ?> value="<?= $filter_client_id ?>"><?= $filter_client_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<?php } ?>
<?php if ($client_id) { ?>
<div class="form-group">
<label>Location</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-map-marker-alt"></i></span>
</div>
<select class="form-control select2" name="location">
<option value="">- All Locations -</option>
<?php
$sql_locations_filter = mysqli_query($mysqli, "SELECT location_id, location_name FROM locations WHERE location_client_id = $client_id AND location_archived_at IS NULL ORDER BY location_name ASC");
while ($row = mysqli_fetch_assoc($sql_locations_filter)) {
$filter_location_id = intval($row['location_id']);
$filter_location_name = escapeHtml($row['location_name']);
?>
<option <?php if ($location_filter == $filter_location_id) { echo "selected"; } ?> value="<?= $filter_location_id ?>"><?= $filter_location_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<?php } ?>
<div class="form-group">
<label>Tags</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tags"></i></span>
</div>
<select class="form-control select2" name="tags[]" data-placeholder="- All Tags -" multiple>
<?php
$sql_tags_filter = mysqli_query($mysqli, "SELECT tag_id, tag_name FROM tags WHERE tag_type = 3 ORDER BY tag_name ASC");
while ($row = mysqli_fetch_assoc($sql_tags_filter)) {
$filter_tag_id = intval($row['tag_id']);
$filter_tag_name = escapeHtml($row['tag_name']);
?>
<option <?php if (in_array($filter_tag_id, $tag_filter, true)) { echo "selected"; } ?> value="<?= $filter_tag_id ?>"><?= $filter_tag_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<div class="form-group">
<label>Archived</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-archive"></i></span>
</div>
<select class="form-control select2" name="archived">
<option <?php if (!$archived_filter) { echo "selected"; } ?> value="0">Active only</option>
<option <?php if ($archived_filter) { echo "selected"; } ?> value="1">Archived only</option>
</select>
</div>
</div>
<?php exportTabsColumns('contacts'); ?>
</div>
<div class="modal-footer">
<button type="submit" name="export_contacts_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
<?php renderExportButtons('export_contacts'); ?>
</div>
</form>

View File

@@ -2,28 +2,121 @@
require_once '../../../includes/modal_header.php';
enforceUserPermission('module_credential');
// Pre-filled from the credentials page's current filters. Everything here is editable -
// the export runs whatever this form posts, not whatever the page happened to show.
$client_id = intval($_GET['client_id'] ?? 0);
if ($client_id) {
enforceClientAccess();
}
// Search Filter
$q_filter = $_GET['q'] ?? '';
// Client Filter
$client_filter = intval($_GET['client'] ?? 0);
// Tags Filter
$tag_filter = (isset($_GET['tags']) && is_array($_GET['tags'])) ? array_map('intval', $_GET['tags']) : [];
// Archived Filter
$archived_filter = (isset($_GET['archived']) && $_GET['archived'] == 1) ? 1 : 0;
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Credentials to CSV</h5>
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Credentials</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<?php exportTabsNav(); ?>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="client_id" value="<?= $client_id ?>">
<div class="modal-body">
<?php exportTabsFiltersOpen(); ?>
<div class="form-group">
<label>Search</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-search"></i></span>
</div>
<input type="text" class="form-control" name="q" value="<?= stripslashes(escapeHtml($q_filter)) ?>" placeholder="Name, description, URI, tag">
</div>
</div>
<?php if (!$client_id) { ?>
<div class="form-group">
<label>Client</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<select class="form-control select2" name="client">
<option value="">- All Clients -</option>
<?php
$sql_clients_filter = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE EXISTS (SELECT 1 FROM credentials WHERE credential_client_id = client_id) ORDER BY client_name ASC");
while ($row = mysqli_fetch_assoc($sql_clients_filter)) {
$filter_client_id = intval($row['client_id']);
$filter_client_name = escapeHtml($row['client_name']);
?>
<option <?php if ($client_filter == $filter_client_id) { echo "selected"; } ?> value="<?= $filter_client_id ?>"><?= $filter_client_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<?php } ?>
<div class="form-group">
<label>Tags</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tags"></i></span>
</div>
<select class="form-control select2" name="tags[]" data-placeholder="- All Tags -" multiple>
<?php
$sql_tags_filter = mysqli_query($mysqli, "SELECT tag_id, tag_name FROM tags WHERE tag_type = 4 ORDER BY tag_name ASC");
while ($row = mysqli_fetch_assoc($sql_tags_filter)) {
$filter_tag_id = intval($row['tag_id']);
$filter_tag_name = escapeHtml($row['tag_name']);
?>
<option <?php if (in_array($filter_tag_id, $tag_filter, true)) { echo "selected"; } ?> value="<?= $filter_tag_id ?>"><?= $filter_tag_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<div class="form-group">
<label>Archived</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-archive"></i></span>
</div>
<select class="form-control select2" name="archived">
<option <?php if (!$archived_filter) { echo "selected"; } ?> value="0">Active only</option>
<option <?php if ($archived_filter) { echo "selected"; } ?> value="1">Archived only</option>
</select>
</div>
</div>
<?php exportTabsColumns('credentials'); ?>
</div>
<div class="modal-footer">
<button type="submit" name="export_credentials_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
<?php renderExportButtons('export_credentials'); ?>
</div>
</form>

View File

@@ -2,27 +2,116 @@
require_once '../../../includes/modal_header.php';
enforceUserPermission('module_support');
// Pre-filled from the domains page's current filters. Everything here is editable -
// the export runs whatever this form posts, not whatever the page happened to show.
$client_id = intval($_GET['client_id'] ?? 0);
if ($client_id) {
enforceClientAccess();
}
// Search Filter
$q_filter = $_GET['q'] ?? '';
// Client Filter
$client_filter = intval($_GET['client'] ?? 0);
// Expiring In Filter
$expire_filter = $_GET['expire_days'] ?? '';
// Archived Filter
$archived_filter = (isset($_GET['archived']) && $_GET['archived'] == 1) ? 1 : 0;
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Domains to CSV</h5>
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Domains</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<?php exportTabsNav(); ?>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="client_id" value="<?= $client_id ?>">
<div class="modal-body">
<?php exportTabsFiltersOpen(); ?>
<div class="form-group">
<label>Search</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-search"></i></span>
</div>
<input type="text" class="form-control" name="q" value="<?= stripslashes(escapeHtml($q_filter)) ?>" placeholder="Domain, registrar, web host">
</div>
</div>
<?php if (!$client_id) { ?>
<div class="form-group">
<label>Client</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<select class="form-control select2" name="client">
<option value="">- All Clients -</option>
<?php
$sql_clients_filter = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE EXISTS (SELECT 1 FROM domains WHERE domain_client_id = client_id) ORDER BY client_name ASC");
while ($row = mysqli_fetch_assoc($sql_clients_filter)) {
$filter_client_id = intval($row['client_id']);
$filter_client_name = escapeHtml($row['client_name']);
?>
<option <?php if ($client_filter == $filter_client_id) { echo "selected"; } ?> value="<?= $filter_client_id ?>"><?= $filter_client_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<?php } ?>
<div class="form-group">
<label>Expiring In</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-hourglass-half"></i></span>
</div>
<select class="form-control select2" name="expire_days">
<option value="">- Any -</option>
<option <?php if ($expire_filter === 'expired') { echo "selected"; } ?> value="expired">Expired</option>
<?php foreach ([7, 30, 45, 60, 90] as $expire_option) { ?>
<option <?php if ($expire_filter !== '' && $expire_filter == $expire_option) { echo "selected"; } ?> value="<?= $expire_option ?>"><?= $expire_option ?> Days</option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group">
<label>Archived</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-archive"></i></span>
</div>
<select class="form-control select2" name="archived">
<option <?php if (!$archived_filter) { echo "selected"; } ?> value="0">Active only</option>
<option <?php if ($archived_filter) { echo "selected"; } ?> value="1">Archived only</option>
</select>
</div>
</div>
<?php exportTabsColumns('domains'); ?>
</div>
<div class="modal-footer">
<button type="submit" name="export_domains_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
<?php renderExportButtons('export_domains'); ?>
</div>
</form>

View File

@@ -2,21 +2,61 @@
require_once '../../../includes/modal_header.php';
enforceUserPermission('module_financial');
// Pre-filled from the expenses page's current filters. Everything here is editable -
// the export runs whatever this form posts, not whatever the page happened to show.
$client_id = intval($_GET['client_id'] ?? 0);
if ($client_id) {
enforceClientAccess();
}
// Search Filter
$q_filter = $_GET['q'] ?? '';
// Account Filter
$account_filter = intval($_GET['account'] ?? 0);
// Vendor Filter
$vendor_filter = intval($_GET['vendor'] ?? 0);
// Category Filter
$category_filter = intval($_GET['category'] ?? 0);
// Date Filter - the all-time sentinels from filter_header.php leave the fields blank
$date_from_filter = (!empty($_GET['dtf']) && $_GET['dtf'] !== '1970-01-01') ? escapeHtml($_GET['dtf']) : '';
$date_to_filter = (!empty($_GET['dtt']) && $_GET['dtt'] !== '2099-12-31') ? escapeHtml($_GET['dtt']) : '';
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-download mr-2"></i>Exporting Expenses to CSV</h5>
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Expenses</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<?php exportTabsNav(); ?>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="modal-body">
<?php exportTabsFiltersOpen(); ?>
<div class="form-group">
<label>Search</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-search"></i></span>
</div>
<input type="text" class="form-control" name="q" value="<?= stripslashes(escapeHtml($q_filter)) ?>" placeholder="Vendor, client, category, description">
</div>
</div>
<div class="form-group">
<label>Account</label>
<div class="input-group">
@@ -25,18 +65,16 @@ ob_start();
</div>
<select class="form-control select2" name="account">
<option value="">- All Accounts -</option>
<?php
$sql_accounts_filter = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
while ($row = mysqli_fetch_assoc($sql_accounts_filter)) {
$account_id = intval($row['account_id']);
$account_name = escapeHtml($row['account_name']);
$sql_account_filter = mysqli_query($mysqli, "SELECT account_id, account_name FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
while ($row = mysqli_fetch_assoc($sql_account_filter)) {
$filter_option_id = intval($row['account_id']);
$filter_option_name = escapeHtml($row['account_name']);
?>
<option <?php if ($account_filter == $account_id) { echo "selected"; } ?> value="<?= $account_id ?>"><?= $account_name ?></option>
<option <?php if ($account_filter == $filter_option_id) { echo "selected"; } ?> value="<?= $filter_option_id ?>"><?= $filter_option_name ?></option>
<?php
}
?>
</select>
</div>
</div>
@@ -49,18 +87,16 @@ ob_start();
</div>
<select class="form-control select2" name="vendor">
<option value="">- All Vendors -</option>
<?php
$sql_vendors_filter = mysqli_query($mysqli, "SELECT * FROM vendors WHERE vendor_client_id = 0 ORDER BY vendor_name ASC");
while ($row = mysqli_fetch_assoc($sql_vendors_filter)) {
$vendor_id = intval($row['vendor_id']);
$vendor_name = escapeHtml($row['vendor_name']);
$sql_vendor_filter = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE EXISTS (SELECT 1 FROM expenses WHERE expense_vendor_id = vendor_id) ORDER BY vendor_name ASC");
while ($row = mysqli_fetch_assoc($sql_vendor_filter)) {
$filter_option_id = intval($row['vendor_id']);
$filter_option_name = escapeHtml($row['vendor_name']);
?>
<option <?php if ($vendor_filter == $vendor_id) { echo "selected"; } ?> value="<?= $vendor_id ?>"><?= $vendor_name ?></option>
<option <?php if ($vendor_filter == $filter_option_id) { echo "selected"; } ?> value="<?= $filter_option_id ?>"><?= $filter_option_name ?></option>
<?php
}
?>
</select>
</div>
</div>
@@ -73,46 +109,45 @@ ob_start();
</div>
<select class="form-control select2" name="category">
<option value="">- All Categories -</option>
<?php
$sql_categories_filter = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Expense' ORDER BY category_name ASC");
while ($row = mysqli_fetch_assoc($sql_categories_filter)) {
$category_id = intval($row['category_id']);
$category_name = escapeHtml($row['category_name']);
$sql_category_filter = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Expense' ORDER BY category_name ASC");
while ($row = mysqli_fetch_assoc($sql_category_filter)) {
$filter_option_id = intval($row['category_id']);
$filter_option_name = escapeHtml($row['category_name']);
?>
<option <?php if ($category_filter == $category_id) { echo "selected"; } ?> value="<?= $category_id ?>"><?= $category_name ?></option>
<option <?php if ($category_filter == $filter_option_id) { echo "selected"; } ?> value="<?= $filter_option_id ?>"><?= $filter_option_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<div class="form-group">
<label>Date From</label>
<label>Dated From</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="date" class="form-control" name="date_from" max="2999-12-31">
<input type="date" class="form-control" name="dtf" value="<?= $date_from_filter ?>" max="2999-12-31">
</div>
</div>
<div class="form-group">
<label>Date To</label>
<label>Dated To</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="date" class="form-control" name="date_to" max="2999-12-31">
<input type="date" class="form-control" name="dtt" value="<?= $date_to_filter ?>" max="2999-12-31">
</div>
</div>
<?php exportTabsColumns('expenses'); ?>
</div>
<div class="modal-footer">
<button type="submit" name="export_expenses_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
<?php renderExportButtons('export_expenses'); ?>
</div>
</form>

View File

@@ -53,17 +53,21 @@ ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-download mr-2"></i>Exporting Income to CSV</h5>
<h5 class="modal-title"><i class="fa fa-fw fa-download mr-2"></i>Export Income</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<?php exportTabsNav(); ?>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="client_id" value="<?= $client_id ?>">
<div class="modal-body">
<?php exportTabsFiltersOpen(); ?>
<div class="form-group">
<label>Search</label>
<div class="input-group">
@@ -163,10 +167,12 @@ ob_start();
</div>
</div>
<?php exportTabsColumns('income'); ?>
</div>
<div class="modal-footer">
<button type="submit" name="export_income_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
<?php renderExportButtons('export_income'); ?>
</div>
</form>

View File

@@ -2,47 +2,121 @@
require_once '../../../includes/modal_header.php';
enforceUserPermission('module_sales');
// Pre-filled from the invoices page's current filters. Everything here is editable -
// the export runs whatever this form posts, not whatever the page happened to show.
$client_id = intval($_GET['client_id'] ?? 0);
if ($client_id) {
enforceClientAccess();
}
// Search Filter
$q_filter = $_GET['q'] ?? '';
// Status Filter
$status_filter = $_GET['status'] ?? '';
// Category Filter
$category_filter = intval($_GET['category'] ?? 0);
// Date Filter - the all-time sentinels from filter_header.php leave the fields blank
$date_from_filter = (!empty($_GET['dtf']) && $_GET['dtf'] !== '1970-01-01') ? escapeHtml($_GET['dtf']) : '';
$date_to_filter = (!empty($_GET['dtt']) && $_GET['dtt'] !== '2099-12-31') ? escapeHtml($_GET['dtt']) : '';
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-download mr-2"></i>Export Invoices to CSV</h5>
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Invoices</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<?php exportTabsNav(); ?>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="client_id" value="<?= $client_id ?>">
<div class="modal-body">
<?php exportTabsFiltersOpen(); ?>
<div class="form-group">
<label>Date From</label>
<label>Search</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
<span class="input-group-text"><i class="fa fa-fw fa-search"></i></span>
</div>
<input type="date" class="form-control" name="date_from" max="2999-12-31">
<input type="text" class="form-control" name="q" value="<?= stripslashes(escapeHtml($q_filter)) ?>" placeholder="Number, scope, client, amount">
</div>
</div>
<div class="form-group">
<label>Date To</label>
<label>Status</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-file-invoice-dollar"></i></span>
</div>
<select class="form-control select2" name="status">
<option value="">- All Statuses -</option>
<option <?php if ($status_filter === 'Draft') { echo "selected"; } ?> value="Draft">Draft</option>
<option <?php if ($status_filter === 'Unpaid') { echo "selected"; } ?> value="Unpaid">Unpaid</option>
<option <?php if ($status_filter === 'Overdue') { echo "selected"; } ?> value="Overdue">Overdue</option>
</select>
</div>
</div>
<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-list"></i></span>
</div>
<select class="form-control select2" name="category">
<option value="">- All Categories -</option>
<?php
$sql_category_filter = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Income' ORDER BY category_name ASC");
while ($row = mysqli_fetch_assoc($sql_category_filter)) {
$filter_option_id = intval($row['category_id']);
$filter_option_name = escapeHtml($row['category_name']);
?>
<option <?php if ($category_filter == $filter_option_id) { echo "selected"; } ?> value="<?= $filter_option_id ?>"><?= $filter_option_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<div class="form-group">
<label>Issued From</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="date" class="form-control" name="date_to" max="2999-12-31">
<input type="date" class="form-control" name="dtf" value="<?= $date_from_filter ?>" max="2999-12-31">
</div>
</div>
<div class="form-group">
<label>Issued To</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="date" class="form-control" name="dtt" value="<?= $date_to_filter ?>" max="2999-12-31">
</div>
</div>
<?php exportTabsColumns('invoices'); ?>
</div>
<div class="modal-footer">
<button type="submit" name="export_invoices_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
<?php renderExportButtons('export_invoices'); ?>
</div>
</form>

View File

@@ -2,27 +2,121 @@
require_once '../../../includes/modal_header.php';
enforceUserPermission('module_client');
// Pre-filled from the locations page's current filters. Everything here is editable -
// the export runs whatever this form posts, not whatever the page happened to show.
$client_id = intval($_GET['client_id'] ?? 0);
if ($client_id) {
enforceClientAccess();
}
// Search Filter
$q_filter = $_GET['q'] ?? '';
// Client Filter
$client_filter = intval($_GET['client'] ?? 0);
// Tags Filter
$tag_filter = (isset($_GET['tags']) && is_array($_GET['tags'])) ? array_map('intval', $_GET['tags']) : [];
// Archived Filter
$archived_filter = (isset($_GET['archived']) && $_GET['archived'] == 1) ? 1 : 0;
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Locations to CSV</h5>
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Locations</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<?php exportTabsNav(); ?>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="client_id" value="<?= $client_id ?>">
<div class="modal-body">
<?php exportTabsFiltersOpen(); ?>
<div class="form-group">
<label>Search</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-search"></i></span>
</div>
<input type="text" class="form-control" name="q" value="<?= stripslashes(escapeHtml($q_filter)) ?>" placeholder="Name, address, city, phone">
</div>
</div>
<?php if (!$client_id) { ?>
<div class="form-group">
<label>Client</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<select class="form-control select2" name="client">
<option value="">- All Clients -</option>
<?php
$sql_clients_filter = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE EXISTS (SELECT 1 FROM locations WHERE location_client_id = client_id) ORDER BY client_name ASC");
while ($row = mysqli_fetch_assoc($sql_clients_filter)) {
$filter_client_id = intval($row['client_id']);
$filter_client_name = escapeHtml($row['client_name']);
?>
<option <?php if ($client_filter == $filter_client_id) { echo "selected"; } ?> value="<?= $filter_client_id ?>"><?= $filter_client_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<?php } ?>
<div class="form-group">
<label>Tags</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tags"></i></span>
</div>
<select class="form-control select2" name="tags[]" data-placeholder="- All Tags -" multiple>
<?php
$sql_tags_filter = mysqli_query($mysqli, "SELECT tag_id, tag_name FROM tags WHERE tag_type = 2 ORDER BY tag_name ASC");
while ($row = mysqli_fetch_assoc($sql_tags_filter)) {
$filter_tag_id = intval($row['tag_id']);
$filter_tag_name = escapeHtml($row['tag_name']);
?>
<option <?php if (in_array($filter_tag_id, $tag_filter, true)) { echo "selected"; } ?> value="<?= $filter_tag_id ?>"><?= $filter_tag_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<div class="form-group">
<label>Archived</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-archive"></i></span>
</div>
<select class="form-control select2" name="archived">
<option <?php if (!$archived_filter) { echo "selected"; } ?> value="0">Active only</option>
<option <?php if ($archived_filter) { echo "selected"; } ?> value="1">Archived only</option>
</select>
</div>
</div>
<?php exportTabsColumns('locations'); ?>
</div>
<div class="modal-footer">
<button type="submit" name="export_locations_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
<?php renderExportButtons('export_locations'); ?>
</div>
</form>

View File

@@ -2,27 +2,124 @@
require_once '../../../includes/modal_header.php';
enforceUserPermission('module_support');
// Pre-filled from the networks page's current filters. Everything here is editable -
// the export runs whatever this form posts, not whatever the page happened to show.
$client_id = intval($_GET['client_id'] ?? 0);
if ($client_id) {
enforceClientAccess();
}
// Search Filter
$q_filter = $_GET['q'] ?? '';
// Client Filter
$client_filter = intval($_GET['client'] ?? 0);
// Location Filter
$location_filter = intval($_GET['location'] ?? 0);
// Archived Filter
$archived_filter = (isset($_GET['archived']) && $_GET['archived'] == 1) ? 1 : 0;
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Networks to CSV</h5>
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Networks</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<?php exportTabsNav(); ?>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="client_id" value="<?= $client_id ?>">
<div class="modal-body">
<?php exportTabsFiltersOpen(); ?>
<div class="form-group">
<label>Search</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-search"></i></span>
</div>
<input type="text" class="form-control" name="q" value="<?= stripslashes(escapeHtml($q_filter)) ?>" placeholder="Name, CIDR, gateway, DNS">
</div>
</div>
<?php if (!$client_id) { ?>
<div class="form-group">
<label>Client</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<select class="form-control select2" name="client">
<option value="">- All Clients -</option>
<?php
$sql_clients_filter = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE EXISTS (SELECT 1 FROM networks WHERE network_client_id = client_id) ORDER BY client_name ASC");
while ($row = mysqli_fetch_assoc($sql_clients_filter)) {
$filter_client_id = intval($row['client_id']);
$filter_client_name = escapeHtml($row['client_name']);
?>
<option <?php if ($client_filter == $filter_client_id) { echo "selected"; } ?> value="<?= $filter_client_id ?>"><?= $filter_client_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<?php } ?>
<?php if ($client_id) { ?>
<div class="form-group">
<label>Location</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-map-marker-alt"></i></span>
</div>
<select class="form-control select2" name="location">
<option value="">- All Locations -</option>
<?php
$sql_locations_filter = mysqli_query($mysqli, "SELECT location_id, location_name FROM locations WHERE location_client_id = $client_id AND location_archived_at IS NULL ORDER BY location_name ASC");
while ($row = mysqli_fetch_assoc($sql_locations_filter)) {
$filter_location_id = intval($row['location_id']);
$filter_location_name = escapeHtml($row['location_name']);
?>
<option <?php if ($location_filter == $filter_location_id) { echo "selected"; } ?> value="<?= $filter_location_id ?>"><?= $filter_location_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<?php } ?>
<div class="form-group">
<label>Archived</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-archive"></i></span>
</div>
<select class="form-control select2" name="archived">
<option <?php if (!$archived_filter) { echo "selected"; } ?> value="0">Active only</option>
<option <?php if ($archived_filter) { echo "selected"; } ?> value="1">Archived only</option>
</select>
</div>
</div>
<?php exportTabsColumns('networks'); ?>
</div>
<div class="modal-footer">
<button type="submit" name="export_networks_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
<?php renderExportButtons('export_networks'); ?>
</div>
</form>

View File

@@ -2,24 +2,111 @@
require_once '../../../includes/modal_header.php';
enforceUserPermission('module_sales');
// Pre-filled from the products page's current filters. Everything here is editable -
// the export runs whatever this form posts, not whatever the page happened to show.
$client_id = intval($_GET['client_id'] ?? 0);
if ($client_id) {
enforceClientAccess();
}
// Search Filter
$q_filter = $_GET['q'] ?? '';
// Type Filter
$type_filter = $_GET['type'] ?? '';
// Category Filter
$category_filter = intval($_GET['category'] ?? 0);
// Archived Filter
$archived_filter = (isset($_GET['archived']) && $_GET['archived'] == 1) ? 1 : 0;
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-download mr-2"></i>Export Products to CSV</h5>
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Products</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<?php exportTabsNav(); ?>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="modal-body">
<?php exportTabsFiltersOpen(); ?>
<div class="form-group">
<label>Search</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-search"></i></span>
</div>
<input type="text" class="form-control" name="q" value="<?= stripslashes(escapeHtml($q_filter)) ?>" placeholder="Name, code, description">
</div>
</div>
<div class="form-group">
<label>Type</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-box"></i></span>
</div>
<select class="form-control select2" name="type">
<option value="">- All Types -</option>
<option <?php if ($type_filter === 'product') { echo "selected"; } ?> value="product">Products</option>
<option <?php if ($type_filter === 'service') { echo "selected"; } ?> value="service">Services</option>
</select>
</div>
</div>
<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-list"></i></span>
</div>
<select class="form-control select2" name="category">
<option value="">- All Categories -</option>
<?php
$sql_category_filter = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Income' ORDER BY category_name ASC");
while ($row = mysqli_fetch_assoc($sql_category_filter)) {
$filter_option_id = intval($row['category_id']);
$filter_option_name = escapeHtml($row['category_name']);
?>
<option <?php if ($category_filter == $filter_option_id) { echo "selected"; } ?> value="<?= $filter_option_id ?>"><?= $filter_option_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<div class="form-group">
<label>Archived</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-archive"></i></span>
</div>
<select class="form-control select2" name="archived">
<option <?php if (!$archived_filter) { echo "selected"; } ?> value="0">Active only</option>
<option <?php if ($archived_filter) { echo "selected"; } ?> value="1">Archived only</option>
</select>
</div>
</div>
<?php exportTabsColumns('products'); ?>
</div>
<div class="modal-footer">
<button type="submit" name="export_products_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
<?php renderExportButtons('export_products'); ?>
</div>
</form>

View File

@@ -2,28 +2,78 @@
require_once '../../../includes/modal_header.php';
enforceUserPermission('module_sales');
// Pre-filled from the quotes page's current filters. Everything here is editable -
// the export runs whatever this form posts, not whatever the page happened to show.
$client_id = intval($_GET['client_id'] ?? 0);
if ($client_id) {
enforceClientAccess();
}
// Search Filter
$q_filter = $_GET['q'] ?? '';
// Date Filter - the all-time sentinels from filter_header.php leave the fields blank
$date_from_filter = (!empty($_GET['dtf']) && $_GET['dtf'] !== '1970-01-01') ? escapeHtml($_GET['dtf']) : '';
$date_to_filter = (!empty($_GET['dtt']) && $_GET['dtt'] !== '2099-12-31') ? escapeHtml($_GET['dtt']) : '';
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Quotes to CSV</h5>
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Quotes</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<?php exportTabsNav(); ?>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="client_id" value="<?= $client_id ?>">
<div class="modal-body">
<?php exportTabsFiltersOpen(); ?>
<div class="form-group">
<label>Search</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-search"></i></span>
</div>
<input type="text" class="form-control" name="q" value="<?= stripslashes(escapeHtml($q_filter)) ?>" placeholder="Number, scope, client, amount">
</div>
</div>
<div class="form-group">
<label>Dated From</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="date" class="form-control" name="dtf" value="<?= $date_from_filter ?>" max="2999-12-31">
</div>
</div>
<div class="form-group">
<label>Dated To</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="date" class="form-control" name="dtt" value="<?= $date_to_filter ?>" max="2999-12-31">
</div>
</div>
<?php exportTabsColumns('quotes'); ?>
</div>
<div class="modal-footer">
<button type="submit" name="export_quotes_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
<?php renderExportButtons('export_quotes'); ?>
</div>
</form>

View File

@@ -1,23 +1,98 @@
<div class="modal" id="exportRecurringModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Recurring Invoices to CSV</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="client_id" value="<?= $client_id ?>">
<div class="modal-body">
<?php
</div>
<div class="modal-footer">
<button type="submit" name="export_client_recurring_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
</div>
</form>
</div>
</div>
require_once '../../../includes/modal_header.php';
enforceUserPermission('module_sales');
// Pre-filled from the recurring invoices page's current filters. Everything here is editable -
// the export runs whatever this form posts, not whatever the page happened to show.
$client_id = intval($_GET['client_id'] ?? 0);
if ($client_id) {
enforceClientAccess();
}
// Search Filter
$q_filter = $_GET['q'] ?? '';
// Status Filter
$status_filter = $_GET['status'] ?? '';
// Date Filter - the all-time sentinels from filter_header.php leave the fields blank
$date_from_filter = (!empty($_GET['dtf']) && $_GET['dtf'] !== '1970-01-01') ? escapeHtml($_GET['dtf']) : '';
$date_to_filter = (!empty($_GET['dtt']) && $_GET['dtt'] !== '2099-12-31') ? escapeHtml($_GET['dtt']) : '';
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Recurring Invoices</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<?php exportTabsNav(); ?>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="client_id" value="<?= $client_id ?>">
<div class="modal-body">
<?php exportTabsFiltersOpen(); ?>
<div class="form-group">
<label>Search</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-search"></i></span>
</div>
<input type="text" class="form-control" name="q" value="<?= stripslashes(escapeHtml($q_filter)) ?>" placeholder="Number, scope, frequency, client">
</div>
</div>
<div class="form-group">
<label>Status</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-toggle-on"></i></span>
</div>
<select class="form-control select2" name="status">
<option value="">- Any Status -</option>
<option <?php if ($status_filter === 'active') { echo "selected"; } ?> value="active">Active</option>
<option <?php if ($status_filter === 'inactive') { echo "selected"; } ?> value="inactive">Inactive</option>
</select>
</div>
</div>
<div class="form-group">
<label>Created From</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="date" class="form-control" name="dtf" value="<?= $date_from_filter ?>" max="2999-12-31">
</div>
</div>
<div class="form-group">
<label>Created To</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="date" class="form-control" name="dtt" value="<?= $date_to_filter ?>" max="2999-12-31">
</div>
</div>
<?php exportTabsColumns('recurring_invoices'); ?>
</div>
<div class="modal-footer">
<?php renderExportButtons('export_recurring_invoices'); ?>
</div>
</form>
<?php
require_once '../../../includes/modal_footer.php';

View File

@@ -2,28 +2,116 @@
require_once '../../../includes/modal_header.php';
enforceUserPermission('module_support');
// Pre-filled from the software page's current filters. Everything here is editable -
// the export runs whatever this form posts, not whatever the page happened to show.
$client_id = intval($_GET['client_id'] ?? 0);
if ($client_id) {
enforceClientAccess();
}
// Search Filter
$q_filter = $_GET['q'] ?? '';
// Client Filter
$client_filter = intval($_GET['client'] ?? 0);
// Expiring In Filter
$expire_filter = $_GET['expire_days'] ?? '';
// Archived Filter
$archived_filter = (isset($_GET['archived']) && $_GET['archived'] == 1) ? 1 : 0;
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Licenses to CSV</h5>
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Software</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<?php exportTabsNav(); ?>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="client_id" value="<?= $client_id ?>">
<div class="modal-body">
<?php exportTabsFiltersOpen(); ?>
<div class="form-group">
<label>Search</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-search"></i></span>
</div>
<input type="text" class="form-control" name="q" value="<?= stripslashes(escapeHtml($q_filter)) ?>" placeholder="Name, type, key">
</div>
</div>
<?php if (!$client_id) { ?>
<div class="form-group">
<label>Client</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<select class="form-control select2" name="client">
<option value="">- All Clients -</option>
<?php
$sql_clients_filter = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE EXISTS (SELECT 1 FROM software WHERE software_client_id = client_id) ORDER BY client_name ASC");
while ($row = mysqli_fetch_assoc($sql_clients_filter)) {
$filter_client_id = intval($row['client_id']);
$filter_client_name = escapeHtml($row['client_name']);
?>
<option <?php if ($client_filter == $filter_client_id) { echo "selected"; } ?> value="<?= $filter_client_id ?>"><?= $filter_client_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<?php } ?>
<div class="form-group">
<label>Expiring In</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-hourglass-half"></i></span>
</div>
<select class="form-control select2" name="expire_days">
<option value="">- Any -</option>
<option <?php if ($expire_filter === 'expired') { echo "selected"; } ?> value="expired">Expired</option>
<?php foreach ([7, 30, 45, 60, 90] as $expire_option) { ?>
<option <?php if ($expire_filter !== '' && $expire_filter == $expire_option) { echo "selected"; } ?> value="<?= $expire_option ?>"><?= $expire_option ?> Days</option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group">
<label>Archived</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-archive"></i></span>
</div>
<select class="form-control select2" name="archived">
<option <?php if (!$archived_filter) { echo "selected"; } ?> value="0">Active only</option>
<option <?php if ($archived_filter) { echo "selected"; } ?> value="1">Archived only</option>
</select>
</div>
</div>
<?php exportTabsColumns('software'); ?>
</div>
<div class="modal-footer">
<button type="submit" name="export_software_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
<?php renderExportButtons('export_software'); ?>
</div>
</form>

View File

@@ -2,27 +2,214 @@
require_once '../../../includes/modal_header.php';
enforceUserPermission('module_support');
// Pre-filled from the tickets page's current filters. Everything here is editable -
// the export runs whatever this form posts, not whatever the page happened to show.
$client_id = intval($_GET['client_id'] ?? 0);
if ($client_id) {
enforceClientAccess();
}
// Search Filter
$q_filter = $_GET['q'] ?? '';
// Status Filter - the page uses an ID set, or the Open / Closed shorthand
$status_filter = (isset($_GET['status']) && is_array($_GET['status'])) ? array_map('intval', $_GET['status']) : [];
$status_shorthand = (isset($_GET['status']) && !is_array($_GET['status'])) ? $_GET['status'] : '';
// Client Filter
$client_filter = intval($_GET['client'] ?? 0);
// Category Filter
$category_filter = intval($_GET['category'] ?? 0);
// Assigned To Filter
$assigned_filter = intval($_GET['assigned'] ?? 0);
// SLA Filter
$sla_filter = $_GET['sla'] ?? '';
// Date Filter - the all-time sentinels from filter_header.php leave the fields blank
$date_from_filter = (!empty($_GET['dtf']) && $_GET['dtf'] !== '1970-01-01') ? escapeHtml($_GET['dtf']) : '';
$date_to_filter = (!empty($_GET['dtt']) && $_GET['dtt'] !== '2099-12-31') ? escapeHtml($_GET['dtt']) : '';
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Tickets to CSV</h5>
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Tickets</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<?php exportTabsNav(); ?>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="client_id" value="<?= $client_id ?>">
<div class="modal-body">
<?php exportTabsFiltersOpen(); ?>
<div class="form-group">
<label>Search</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-search"></i></span>
</div>
<input type="text" class="form-control" name="q" value="<?= stripslashes(escapeHtml($q_filter)) ?>" placeholder="Number, subject, client, contact">
</div>
</div>
<div class="form-group">
<label>Status</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tasks"></i></span>
</div>
<select class="form-control select2" name="status[]" data-placeholder="- Open tickets -" multiple>
<?php
$sql_statuses_filter = mysqli_query($mysqli, "SELECT ticket_status_id, ticket_status_name FROM ticket_statuses ORDER BY ticket_status_name ASC");
while ($row = mysqli_fetch_assoc($sql_statuses_filter)) {
$filter_status_id = intval($row['ticket_status_id']);
$filter_status_name = escapeHtml($row['ticket_status_name']);
?>
<option <?php if (in_array($filter_status_id, $status_filter, true)) { echo "selected"; } ?> value="<?= $filter_status_id ?>"><?= $filter_status_name ?></option>
<?php
}
?>
</select>
</div>
<small class="form-text text-muted">Leave empty for open tickets only.</small>
</div>
<div class="form-group">
<label>Resolution</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-check"></i></span>
</div>
<select class="form-control select2" name="resolution">
<option <?php if ($status_shorthand !== 'Closed') { echo "selected"; } ?> value="">Open</option>
<option <?php if ($status_shorthand === 'Closed') { echo "selected"; } ?> value="Closed">Closed</option>
</select>
</div>
</div>
<?php if (!$client_id) { ?>
<div class="form-group">
<label>Client</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div>
<select class="form-control select2" name="client">
<option value="">- All Clients -</option>
<?php
$sql_clients_filter = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE EXISTS (SELECT 1 FROM tickets WHERE ticket_client_id = client_id) ORDER BY client_name ASC");
while ($row = mysqli_fetch_assoc($sql_clients_filter)) {
$filter_client_id = intval($row['client_id']);
$filter_client_name = escapeHtml($row['client_name']);
?>
<option <?php if ($client_filter == $filter_client_id) { echo "selected"; } ?> value="<?= $filter_client_id ?>"><?= $filter_client_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<?php } ?>
<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-list"></i></span>
</div>
<select class="form-control select2" name="category">
<option value="">- All Categories -</option>
<?php
$sql_category_filter = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Ticket' ORDER BY category_name ASC");
while ($row = mysqli_fetch_assoc($sql_category_filter)) {
$filter_option_id = intval($row['category_id']);
$filter_option_name = escapeHtml($row['category_name']);
?>
<option <?php if ($category_filter == $filter_option_id) { echo "selected"; } ?> value="<?= $filter_option_id ?>"><?= $filter_option_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<div class="form-group">
<label>Assigned To</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user-tie"></i></span>
</div>
<select class="form-control select2" name="assigned">
<option value="">- Anyone -</option>
<?php
$sql_assigned_filter = mysqli_query($mysqli, "SELECT user_id, user_name FROM users WHERE user_type = 1 AND user_archived_at IS NULL ORDER BY user_name ASC");
while ($row = mysqli_fetch_assoc($sql_assigned_filter)) {
$filter_option_id = intval($row['user_id']);
$filter_option_name = escapeHtml($row['user_name']);
?>
<option <?php if ($assigned_filter == $filter_option_id) { echo "selected"; } ?> value="<?= $filter_option_id ?>"><?= $filter_option_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<div class="form-group">
<label>SLA</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-stopwatch"></i></span>
</div>
<select class="form-control select2" name="sla">
<option value="">- Any SLA state -</option>
<option <?php if ($sla_filter === 'breached') { echo "selected"; } ?> value="breached">Breached</option>
<option <?php if ($sla_filter === 'at_risk') { echo "selected"; } ?> value="at_risk">At risk</option>
<option <?php if ($sla_filter === 'paused') { echo "selected"; } ?> value="paused">Paused</option>
<option <?php if ($sla_filter === 'met') { echo "selected"; } ?> value="met">Met</option>
<option <?php if ($sla_filter === 'none') { echo "selected"; } ?> value="none">No SLA</option>
</select>
</div>
</div>
<div class="form-group">
<label>Opened From</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="date" class="form-control" name="dtf" value="<?= $date_from_filter ?>" max="2999-12-31">
</div>
</div>
<div class="form-group">
<label>Opened To</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="date" class="form-control" name="dtt" value="<?= $date_to_filter ?>" max="2999-12-31">
</div>
</div>
<?php exportTabsColumns('tickets'); ?>
</div>
<div class="modal-footer">
<button type="submit" name="export_tickets_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
<?php renderExportButtons('export_tickets'); ?>
</div>
</form>

View File

@@ -76,16 +76,20 @@ ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-download mr-2"></i>Exporting Transactions to CSV</h5>
<h5 class="modal-title"><i class="fa fa-fw fa-download mr-2"></i>Export Transactions</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<?php exportTabsNav(); ?>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="modal-body">
<?php exportTabsFiltersOpen(); ?>
<div class="form-group">
<label>Account</label>
<div class="input-group">
@@ -239,10 +243,11 @@ ob_start();
</div>
</div>
<?php exportTabsColumns('transactions'); ?>
</div>
<div class="modal-footer">
<button type="submit" name="export_transactions_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
<?php renderExportButtons('export_transactions'); ?>
</div>
</form>

View File

@@ -2,47 +2,78 @@
require_once '../../../includes/modal_header.php';
enforceUserPermission('module_financial');
// Pre-filled from the trips page's current filters. Everything here is editable -
// the export runs whatever this form posts, not whatever the page happened to show.
$client_id = intval($_GET['client_id'] ?? 0);
if ($client_id) {
enforceClientAccess();
}
// Search Filter
$q_filter = $_GET['q'] ?? '';
// Date Filter - the all-time sentinels from filter_header.php leave the fields blank
$date_from_filter = (!empty($_GET['dtf']) && $_GET['dtf'] !== '1970-01-01') ? escapeHtml($_GET['dtf']) : '';
$date_to_filter = (!empty($_GET['dtt']) && $_GET['dtt'] !== '2099-12-31') ? escapeHtml($_GET['dtt']) : '';
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Trips to CSV</h5>
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Trips</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<?php exportTabsNav(); ?>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="client_id" value="<?= $client_id ?>">
<div class="modal-body">
<?php exportTabsFiltersOpen(); ?>
<div class="form-group">
<label>Date From</label>
<label>Search</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
<span class="input-group-text"><i class="fa fa-fw fa-search"></i></span>
</div>
<input type="date" class="form-control" name="date_from" max="2999-12-31">
<input type="text" class="form-control" name="q" value="<?= stripslashes(escapeHtml($q_filter)) ?>" placeholder="Purpose, source, destination">
</div>
</div>
<div class="form-group">
<label>Date To</label>
<label>Dated From</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="date" class="form-control" name="date_to" max="2999-12-31">
<input type="date" class="form-control" name="dtf" value="<?= $date_from_filter ?>" max="2999-12-31">
</div>
</div>
<div class="form-group">
<label>Dated To</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<input type="date" class="form-control" name="dtt" value="<?= $date_to_filter ?>" max="2999-12-31">
</div>
</div>
<?php exportTabsColumns('trips'); ?>
</div>
<div class="modal-footer">
<button type="submit" name="export_trips_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
<?php renderExportButtons('export_trips'); ?>
</div>
</form>

View File

@@ -2,28 +2,70 @@
require_once '../../../includes/modal_header.php';
enforceUserPermission('module_client');
// Pre-filled from the vendors page's current filters. Everything here is editable -
// the export runs whatever this form posts, not whatever the page happened to show.
$client_id = intval($_GET['client_id'] ?? 0);
if ($client_id) {
enforceClientAccess();
}
// Search Filter
$q_filter = $_GET['q'] ?? '';
// Archived Filter
$archived_filter = (isset($_GET['archived']) && $_GET['archived'] == 1) ? 1 : 0;
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Vendors to CSV</h5>
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Vendors</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<?php exportTabsNav(); ?>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="client_id" value="<?= $client_id ?>">
<div class="modal-body">
<?php exportTabsFiltersOpen(); ?>
<div class="form-group">
<label>Search</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-search"></i></span>
</div>
<input type="text" class="form-control" name="q" value="<?= stripslashes(escapeHtml($q_filter)) ?>" placeholder="Name, contact, account number">
</div>
</div>
<div class="form-group">
<label>Archived</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-archive"></i></span>
</div>
<select class="form-control select2" name="archived">
<option <?php if (!$archived_filter) { echo "selected"; } ?> value="0">Active only</option>
<option <?php if ($archived_filter) { echo "selected"; } ?> value="1">Archived only</option>
</select>
</div>
</div>
<?php exportTabsColumns('vendors'); ?>
</div>
<div class="modal-footer">
<button type="submit" name="export_vendors_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
<?php renderExportButtons('export_vendors'); ?>
</div>
</form>

View File

@@ -83,7 +83,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<div class="dropdown-menu">
<?php if ($num_rows[0] > 0) { ?>
<a class="dropdown-item text-dark ajax-modal" href="#"
data-modal-url="modals/network/network_export.php?<?= $client_url ?>">
data-modal-url="<?= buildExportModalUrl('modals/network/network_export.php', ['client_id', 'client', 'location', 'archived', 'q']) ?>">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
<?php } ?>

View File

@@ -1303,62 +1303,155 @@ if (isset($_GET['download_assets_csv_template'])) {
}
if (isset($_POST['export_assets_csv'])) {
if (isset($_POST['export_assets'])) {
validateCSRFToken();
enforceUserPermission('module_support');
if ($_POST['client_id']) {
$format = resolveExportFormat($_POST['export_assets']);
// Filters inherited from the assets page - mirrors agent/assets.php
$filter_summary = [];
if (!empty($_POST['client_id'])) {
$client_id = intval($_POST['client_id']);
$client_query = "AND asset_client_id = $client_id";
$client_row = mysqli_fetch_assoc(mysqli_query($mysqli,"SELECT client_name FROM clients WHERE client_id = $client_id"));
$client_row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT client_name FROM clients WHERE client_id = $client_id"));
$client_name = $client_row['client_name'];
$file_name_prepend = "$client_name-";
$filter_summary['Client'] = $client_name;
enforceClientAccess();
} else {
$client_query = '';
$client_id = 0; // for Logging
$file_name_prepend = "$session_company_name-";
// Client Filter
if (!empty($_POST['client'])) {
$filter_client_id = intval($_POST['client']);
$client_query = "AND (asset_client_id = $filter_client_id)";
$client_row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT client_name FROM clients WHERE client_id = $filter_client_id"));
$filter_summary['Client'] = $client_row['client_name'] ?? '';
}
}
// Get records from database
$sql = mysqli_query($mysqli,"SELECT * FROM assets LEFT JOIN contacts ON asset_contact_id = contact_id LEFT JOIN locations ON asset_location_id = location_id LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1 LEFT JOIN clients ON asset_client_id = client_id WHERE asset_archived_at IS NULL $client_query $access_permission_query ORDER BY asset_name ASC");
// Archived Filter
if (isset($_POST['archived']) && $_POST['archived'] == 1) {
$archive_query = $client_id ? "asset_archived_at IS NOT NULL" : "(client_archived_at IS NOT NULL OR asset_archived_at IS NOT NULL)";
$filter_summary['Archived'] = 'Archived only';
} else {
$archive_query = $client_id ? "asset_archived_at IS NULL" : "(client_archived_at IS NULL AND asset_archived_at IS NULL)";
}
// Type Filter
$type = $_POST['type'] ?? '';
if ($type == 'workstation') {
$type_query = "asset_type = 'desktop' OR asset_type = 'laptop'";
} elseif ($type == 'server') {
$type_query = "asset_type = 'server'";
} elseif ($type == 'virtual') {
$type_query = "asset_type = 'Virtual Machine'";
} elseif ($type == 'network') {
$type_query = "asset_type = 'Firewall/Router' OR asset_type = 'Switch' OR asset_type = 'Access Point'";
} elseif ($type == 'other') {
$type_query = "asset_type NOT LIKE 'laptop' AND asset_type NOT LIKE 'desktop' AND asset_type NOT LIKE 'server' AND asset_type NOT LIKE 'virtual machine' AND asset_type NOT LIKE 'firewall/router' AND asset_type NOT LIKE 'switch' AND asset_type NOT LIKE 'access point'";
} else {
// Default - any
$type = '';
$type_query = "asset_type LIKE '%'";
}
if ($type) {
$filter_summary['Type'] = ucwords($type);
}
// Location Filter
if (!empty($_POST['location'])) {
$filter_location_id = intval($_POST['location']);
$location_query = "AND (asset_location_id = $filter_location_id)";
$location_row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT location_name FROM locations WHERE location_id = $filter_location_id"));
$filter_summary['Location'] = $location_row['location_name'] ?? '';
} else {
// Default - any
$location_query = '';
}
// Tags Filter
if (isset($_POST['tags']) && is_array($_POST['tags']) && !empty($_POST['tags'])) {
$tag_filter = implode(",", array_map('intval', $_POST['tags']));
$tag_query = "AND tag_id IN ($tag_filter)";
$tag_names = [];
$sql_tags = mysqli_query($mysqli, "SELECT tag_name FROM tags WHERE tag_id IN ($tag_filter) ORDER BY tag_name ASC");
while ($tag_row = mysqli_fetch_assoc($sql_tags)) {
$tag_names[] = $tag_row['tag_name'];
}
$filter_summary['Tags'] = implode(', ', $tag_names);
} else {
// Default - any
$tag_query = '';
}
// Expiring In Filter
if (!empty($_POST['expire_days'])) {
if ($_POST['expire_days'] == "expired") {
$expire_query = "AND (asset_warranty_expire IS NOT NULL AND asset_warranty_expire != '0000-00-00' AND asset_warranty_expire < CURDATE())";
$filter_summary['Warranty'] = 'Expired';
} else {
$expire_days = intval($_POST['expire_days']);
$expire_query = "AND (asset_warranty_expire IS NOT NULL AND asset_warranty_expire != '0000-00-00' AND asset_warranty_expire BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL $expire_days DAY))";
$filter_summary['Warranty'] = "Expiring within $expire_days days";
}
} else {
// Default - any
$expire_query = '';
}
// Search Filter
$q = escapeSql($_POST['q'] ?? '');
if (!empty($q)) {
$filter_summary['Search'] = $_POST['q'];
}
// Get records from database - same shape as the assets page list query
$sql = mysqli_query(
$mysqli,
"SELECT * FROM assets
LEFT JOIN clients ON asset_client_id = client_id
LEFT JOIN contacts ON asset_contact_id = contact_id
LEFT JOIN locations ON asset_location_id = location_id
LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1
LEFT JOIN asset_tags ON asset_tag_asset_id = asset_id
LEFT JOIN tags ON tag_id = asset_tag_tag_id
WHERE $archive_query
$tag_query
AND (asset_name LIKE '%$q%' OR asset_description LIKE '%$q%' OR asset_type LIKE '%$q%' OR interface_ip LIKE '%$q%' OR interface_ipv6 LIKE '%$q%' OR interface_mac LIKE '%$q%' OR asset_make LIKE '%$q%' OR asset_model LIKE '%$q%' OR asset_serial LIKE '%$q%' OR asset_os LIKE '%$q%' OR contact_name LIKE '%$q%' OR location_name LIKE '%$q%' OR client_name LIKE '%$q%' OR tag_name LIKE '%$q%')
AND ($type_query)
$access_permission_query
$location_query
$expire_query
$client_query
GROUP BY asset_id
ORDER BY asset_name ASC"
);
$num_rows = mysqli_num_rows($sql);
if ($num_rows > 0) {
$delimiter = ",";
$enclosure = '"';
$escape = '\\'; // backslash
$filename = sanitizeFilename($file_name_prepend . "Assets-" . date('Y-m-d_H-i-s') . ".csv");
//create a file pointer
$f = fopen('php://memory', 'w');
guardExportPdfRowCount($format, $num_rows);
//set column headers
$fields = array('Name', 'Description', 'Type', 'Make', 'Model', 'Serial Number', 'Operating System', 'Purchase Date', 'Warranty Expire', 'Install Date', 'Assigned To', 'Location', 'Physical Location', 'Notes');
fputcsv($f, $fields, $delimiter, $enclosure, $escape);
$export = beginExport('assets', $format, $file_name_prepend . 'Assets', 'Assets', summarizeExportFilters($filter_summary));
//output each row of the data, format line as csv and write to file pointer
while ($row = mysqli_fetch_assoc($sql)) {
$lineData = array($row['asset_name'], $row['asset_description'], $row['asset_type'], $row['asset_make'], $row['asset_model'], $row['asset_serial'], $row['asset_os'], $row['asset_purchase_date'], $row['asset_warranty_expire'], $row['asset_install_date'], $row['contact_name'], $row['location_name'], $row['asset_physical_location'], $row['asset_notes']);
fputcsv($f, array_map('escapeCsvFormula', $lineData), $delimiter, $enclosure, $escape);
addExportRow($export, $row);
}
//move back to beginning of file
fseek($f, 0);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
finishExport($export);
}
logAudit("Asset", "Export", "$session_name exported $num_rows asset(s) to a CSV file", $client_id);
logAudit("Asset", "Export", "$session_name exported $num_rows asset(s) to a " . strtoupper($format) . " file", $client_id);
exit;
@@ -1950,57 +2043,50 @@ if (isset($_GET['download_client_asset_interfaces_csv_template'])) {
}
if (isset($_POST['export_client_asset_interfaces_csv'])) {
if (isset($_POST['export_asset_interfaces'])) {
validateCSRFToken();
enforceUserPermission('module_support');
$format = resolveExportFormat($_POST['export_asset_interfaces']);
$asset_id = intval($_POST['asset_id']);
$client_id = intval(getFieldById('assets', $asset_id, 'asset_client_id'));
enforceClientAccess();
//get records from database
$sql = mysqli_query($mysqli,"SELECT * FROM asset_interfaces LEFT JOIN assets ON asset_id = interface_asset_id LEFT JOIN networks ON interface_network_id = network_id LEFT JOIN clients ON asset_client_id = client_id WHERE asset_id = $asset_id AND interface_archived_at IS NULL ORDER BY interface_name ASC");
$row = mysqli_fetch_assoc($sql);
$asset_name = getFieldById('assets', $asset_id, 'asset_name');
// Get records from database - scoped to the one asset, so no page filters apply
$sql = mysqli_query(
$mysqli,
"SELECT * FROM asset_interfaces
LEFT JOIN assets ON asset_id = interface_asset_id
LEFT JOIN networks ON interface_network_id = network_id
LEFT JOIN clients ON asset_client_id = client_id
WHERE asset_id = $asset_id
AND interface_archived_at IS NULL
ORDER BY interface_name ASC"
);
$num_rows = mysqli_num_rows($sql);
if ($num_rows > 0) {
mysqli_data_seek($sql, 0); // <— rewind to the start
$delimiter = ",";
$enclosure = '"';
$escape = '\\'; // backslash
$filename = toAlphanumeric($asset_name) . "-Interfaces-" . date('Y-m-d') . ".csv";
guardExportPdfRowCount($format, $num_rows);
//create a file pointer
$f = fopen('php://memory', 'w');
$export = beginExport('asset_interfaces', $format, toAlphanumeric($asset_name) . '-Interfaces', "$asset_name - Interfaces", '');
//set column headers
$fields = array('Name', 'Description', 'Type', 'MAC', 'IP', 'NAT IP', 'IPv6', 'Network');
fputcsv($f, $fields, $delimiter, $enclosure, $escape);
//output each row of the data, format line as csv and write to file pointer
while($row = mysqli_fetch_assoc($sql)) {
$lineData = array($row['interface_name'], $row['interface_description'], $row['interface_type'], $row['interface_mac'], $row['interface_ip'], $row['interface_nat_ip'], $row['interface_ipv6'], $row['network_name']);
fputcsv($f, array_map('escapeCsvFormula', $lineData), $delimiter, $enclosure, $escape);
while ($row = mysqli_fetch_assoc($sql)) {
addExportRow($export, $row);
}
//move back to beginning of file
fseek($f, 0);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
finishExport($export);
}
logAudit("Asset Interface", "Export", "$session_name exported $num_rows interfaces(s) to a CSV file", $client_id);
logAudit("Asset Interface", "Export", "$session_name exported $num_rows interface(s) to a " . strtoupper($format) . " file", $client_id);
exit;

View File

@@ -338,59 +338,98 @@ if (isset($_POST['bulk_delete_certificates'])) {
}
if (isset($_POST['export_certificates_csv'])) {
if (isset($_POST['export_certificates'])) {
validateCSRFToken();
// Exports are reads - see CONTRIBUTING.md
enforceUserPermission('module_support');
if ($_POST['client_id']) {
$format = resolveExportFormat($_POST['export_certificates']);
// Filters inherited from the certificates page - mirrors agent/certificates.php
$filter_summary = [];
// Archived Filter
$archived = (isset($_POST['archived']) && $_POST['archived'] == 1);
if ($archived) {
$filter_summary['Archived'] = 'Archived only';
}
if (!empty($_POST['client_id'])) {
$client_id = intval($_POST['client_id']);
$client_query = "AND certificate_client_id = $client_id";
$client_name = getFieldById('clients', $client_id, 'client_name');
$file_name_prepend = "$client_name-";
$filter_summary['Client'] = $client_name;
enforceClientAccess();
$archive_query = $archived ? "certificate_archived_at IS NOT NULL" : "certificate_archived_at IS NULL";
} else {
$client_query = '';
$client_id = 0;
$client_id = 0; // for Logging
$file_name_prepend = "$session_company_name-";
// Client Filter
if (!empty($_POST['client'])) {
$filter_client_id = intval($_POST['client']);
$client_query = "AND (certificate_client_id = $filter_client_id)";
$filter_summary['Client'] = getFieldById('clients', $filter_client_id, 'client_name');
}
$archive_query = $archived ? "(client_archived_at IS NOT NULL OR certificate_archived_at IS NOT NULL)" : "(client_archived_at IS NULL AND certificate_archived_at IS NULL)";
}
$sql = mysqli_query($mysqli,"SELECT * FROM certificates LEFT JOIN clients ON client_id = certificate_client_id WHERE certificate_archived_at IS NULL $client_query $access_permission_query ORDER BY certificate_name ASC");
// Expiring In Filter
if (!empty($_POST['expire_days'])) {
if ($_POST['expire_days'] == "expired") {
$expire_query = "AND (certificate_expire IS NOT NULL AND certificate_expire != '0000-00-00' AND certificate_expire < CURDATE())";
$filter_summary['Expiry'] = 'Expired';
} else {
$expire_days = intval($_POST['expire_days']);
$expire_query = "AND (certificate_expire IS NOT NULL AND certificate_expire != '0000-00-00' AND certificate_expire BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL $expire_days DAY))";
$filter_summary['Expiry'] = "Expiring within $expire_days days";
}
} else {
// Default - any
$expire_query = '';
}
// Search Filter
$q = escapeSql($_POST['q'] ?? '');
if (!empty($q)) {
$filter_summary['Search'] = $_POST['q'];
}
$sql = mysqli_query(
$mysqli,
"SELECT * FROM certificates
LEFT JOIN clients ON client_id = certificate_client_id
WHERE $archive_query
AND (certificate_name LIKE '%$q%' OR certificate_domain LIKE '%$q%' OR certificate_description LIKE '%$q%' OR certificate_issued_by LIKE '%$q%' OR client_name LIKE '%$q%')
$access_permission_query
$client_query
$expire_query
ORDER BY certificate_name ASC"
);
$num_rows = mysqli_num_rows($sql);
if ($num_rows > 0) {
$delimiter = ",";
$enclosure = '"';
$escape = '\\'; // backslash
$filename = sanitizeFilename($file_name_prepend . "Certificates-" . date('Y-m-d_H-i-s') . ".csv");
//create a file pointer
$f = fopen('php://memory', 'w');
guardExportPdfRowCount($format, $num_rows);
//set column headers
$fields = array('Name', 'Description', 'Domain', 'Issuer', 'Expiration Date');
fputcsv($f, $fields, $delimiter, $enclosure, $escape);
$export = beginExport('certificates', $format, $file_name_prepend . 'Certificates', 'Certificates', summarizeExportFilters($filter_summary));
//output each row of the data, format line as csv and write to file pointer
while($row = $sql->fetch_assoc()) {
$lineData = array($row['certificate_name'], $row['certificate_description'], $row['certificate_domain'], $row['certificate_issued_by'], $row['certificate_expire']);
fputcsv($f, array_map('escapeCsvFormula', $lineData), $delimiter, $enclosure, $escape);
while ($row = mysqli_fetch_assoc($sql)) {
addExportRow($export, $row);
}
//move back to beginning of file
fseek($f, 0);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
finishExport($export);
}
logAudit("Certificate", "Export", "$session_name exported $num_rows certificate(s) to a CSV file", $client_id);
logAudit("Certificate", "Export", "$session_name exported $num_rows certificate(s) to a " . strtoupper($format) . " file", $client_id);
exit;

View File

@@ -528,51 +528,125 @@ if (isset($_GET['delete_client'])) {
}
if (isset($_POST['export_clients_csv'])) {
if (isset($_POST['export_clients'])) {
validateCSRFToken();
enforceUserPermission('module_client', 1);
enforceUserPermission('module_client');
//get records from database
$sql = mysqli_query($mysqli, "SELECT * FROM clients
$format = resolveExportFormat($_POST['export_clients']);
// Filters inherited from the clients page - mirrors agent/clients.php
$filter_summary = [];
// Leads Filter
if (isset($_POST['leads']) && $_POST['leads'] == 1) {
$leads_query = "AND client_lead = 1";
$filter_summary['Showing'] = 'Leads';
$export_label = 'Leads';
} else {
$leads_query = "AND client_lead = 0";
$export_label = 'Clients';
}
// Tags Filter
if (isset($_POST['tags']) && is_array($_POST['tags']) && !empty($_POST['tags'])) {
$tag_filter = implode(",", array_map('intval', $_POST['tags']));
$tag_query = "AND tags.tag_id IN ($tag_filter)";
$tag_names = [];
$sql_tags = mysqli_query($mysqli, "SELECT tag_name FROM tags WHERE tag_id IN ($tag_filter) ORDER BY tag_name ASC");
while ($tag_row = mysqli_fetch_assoc($sql_tags)) {
$tag_names[] = $tag_row['tag_name'];
}
$filter_summary['Tags'] = implode(', ', $tag_names);
} else {
// Default - any
$tag_query = '';
}
// Industry Filter
if (!empty($_POST['industry'])) {
$industry_query = "AND (clients.client_type = '" . escapeSql($_POST['industry']) . "')";
$filter_summary['Industry'] = $_POST['industry'];
} else {
// Default - any
$industry_query = '';
}
// Referral Filter
if (!empty($_POST['referral'])) {
$referral_query = "AND (clients.client_referral = '" . escapeSql($_POST['referral']) . "')";
$filter_summary['Referral'] = $_POST['referral'];
} else {
// Default - any
$referral_query = '';
}
// Archived Filter
if (isset($_POST['archived']) && $_POST['archived'] == 1) {
$archive_query = "client_archived_at IS NOT NULL";
$filter_summary['Archived'] = 'Archived only';
} else {
$archive_query = "client_archived_at IS NULL";
}
// Date Filter - all-time sentinels from filter_header.php are left in place,
// they match everything anyway
$dtf = escapeSql(!empty($_POST['dtf']) ? $_POST['dtf'] : '1970-01-01');
$dtt = escapeSql(!empty($_POST['dtt']) ? $_POST['dtt'] : '2099-12-31');
$date_range = formatExportDateRange($dtf, $dtt);
if ($date_range) {
$filter_summary['Created'] = $date_range;
}
// Search Filter
$q = escapeSql($_POST['q'] ?? '');
$phone_query = preg_replace('/\D/', '', $q);
if (!empty($q)) {
$filter_summary['Search'] = $_POST['q'];
}
// Get records from database - same shape as the clients page list query
$sql = mysqli_query(
$mysqli,
"SELECT clients.*, contacts.*, locations.*
FROM clients
LEFT JOIN contacts ON clients.client_id = contacts.contact_client_id AND contact_primary = 1
LEFT JOIN locations ON clients.client_id = locations.location_client_id AND location_primary = 1
ORDER BY client_name ASC
");
LEFT JOIN client_tags ON client_tags.client_id = clients.client_id
LEFT JOIN tags ON tags.tag_id = client_tags.tag_id
WHERE (client_name LIKE '%$q%' OR client_abbreviation LIKE '%$q%' OR client_type LIKE '%$q%' OR client_referral LIKE '%$q%'
OR contact_email LIKE '%$q%' OR contact_name LIKE '%$q%' OR contact_phone LIKE '%$phone_query%'
OR contact_mobile LIKE '%$phone_query%' OR location_address LIKE '%$q%'
OR location_city LIKE '%$q%' OR location_state LIKE '%$q%' OR location_zip LIKE '%$q%' OR location_country LIKE '%$q%'
OR tag_name LIKE '%$q%' OR client_tax_id_number LIKE '%$q%')
AND $archive_query
AND DATE(client_created_at) BETWEEN '$dtf' AND '$dtt'
$leads_query
$access_permission_query
$tag_query
$industry_query
$referral_query
GROUP BY client_id
ORDER BY client_name ASC"
);
$num_rows = mysqli_num_rows($sql);
if ($num_rows > 0) {
$delimiter = ",";
$enclosure = '"';
$escape = '\\'; // backslash
$filename = sanitizeFilename($session_company_name . "-Clients-" . date('Y-m-d_H-i-s') . ".csv");
//create a file pointer
$f = fopen('php://memory', 'w');
guardExportPdfRowCount($format, $num_rows);
//set column headers
$fields = array('Client Name', 'Industry', 'Referral', 'Website', 'Primary Location Name', 'Location Phone', 'Location Address', 'City', 'State', 'Postal Code', 'Country', 'Primary Contact Name', 'Title', 'Contact Phone', 'Extension', 'Contact Mobile', 'Contact Email', 'Hourly Rate', 'Currency', 'Payment Terms', 'Tax ID', 'Abbreviation');
fputcsv($f, $fields, $delimiter, $enclosure, $escape);
$export = beginExport('clients', $format, "$session_company_name-$export_label", $export_label, summarizeExportFilters($filter_summary));
//output each row of the data, format line as csv and write to file pointer
while($row = $sql->fetch_assoc()) {
$lineData = array($row['client_name'], $row['client_type'], $row['client_referral'], $row['client_website'], $row['location_name'], formatPhoneNumber($row['location_phone']), $row['location_address'], $row['location_city'], $row['location_state'], $row['location_zip'], $row['location_country'], $row['contact_name'], $row['contact_title'], formatPhoneNumber($row['contact_phone']), $row['contact_extension'], formatPhoneNumber($row['contact_mobile']), $row['contact_email'], $row['client_rate'], $row['client_currency_code'], $row['client_net_terms'], $row['client_tax_id_number'], $row['client_abbreviation']);
fputcsv($f, array_map('escapeCsvFormula', $lineData), $delimiter, $enclosure, $escape);
while ($row = mysqli_fetch_assoc($sql)) {
addExportRow($export, $row);
}
//move back to beginning of file
fseek($f, 0);
finishExport($export);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
logAudit("Client", "Export", "$session_name exported $num_rows client(s) to a CSV file");
logAudit("Client", "Export", "$session_name exported $num_rows client(s) to a " . strtoupper($format) . " file");
}

View File

@@ -1262,59 +1262,116 @@ if (isset($_GET['unlink_contact_from_file'])) {
}
if (isset($_POST['export_contacts_csv'])) {
if (isset($_POST['export_contacts'])) {
validateCSRFToken();
// Exports are reads - see CONTRIBUTING.md
enforceUserPermission('module_client');
if ($_POST['client_id']) {
$format = resolveExportFormat($_POST['export_contacts']);
// Filters inherited from the contacts page - mirrors agent/contacts.php
$filter_summary = [];
// Archived Filter
$archived = (isset($_POST['archived']) && $_POST['archived'] == 1);
if ($archived) {
$filter_summary['Archived'] = 'Archived only';
}
if (!empty($_POST['client_id'])) {
$client_id = intval($_POST['client_id']);
$client_query = "AND contact_client_id = $client_id";
$client_name = getFieldById('clients', $client_id, 'client_name');
$file_name_prepend = "$client_name-";
$filter_summary['Client'] = $client_name;
enforceClientAccess();
$archive_query = $archived ? "contact_archived_at IS NOT NULL" : "contact_archived_at IS NULL";
} else {
$client_query = '';
$client_id = 0; //Logging;
$client_id = 0; // for Logging
$file_name_prepend = "$session_company_name-";
// Client Filter
if (!empty($_POST['client'])) {
$filter_client_id = intval($_POST['client']);
$client_query = "AND (contact_client_id = $filter_client_id)";
$filter_summary['Client'] = getFieldById('clients', $filter_client_id, 'client_name');
}
$archive_query = $archived ? "(client_archived_at IS NOT NULL OR contact_archived_at IS NOT NULL)" : "(client_archived_at IS NULL AND contact_archived_at IS NULL)";
}
//Contacts
$sql = mysqli_query($mysqli,"SELECT * FROM contacts LEFT JOIN locations ON location_id = contact_location_id LEFT JOIN clients ON client_id = contact_client_id WHERE contact_archived_at IS NULL AND client_archived_at IS NULL $client_query $access_permission_query ORDER BY contact_name ASC");
// Tags Filter
if (isset($_POST['tags']) && is_array($_POST['tags']) && !empty($_POST['tags'])) {
$tag_filter = implode(",", array_map('intval', $_POST['tags']));
$tag_query = "AND tags.tag_id IN ($tag_filter)";
$tag_names = [];
$sql_tags = mysqli_query($mysqli, "SELECT tag_name FROM tags WHERE tag_id IN ($tag_filter) ORDER BY tag_name ASC");
while ($tag_row = mysqli_fetch_assoc($sql_tags)) {
$tag_names[] = $tag_row['tag_name'];
}
$filter_summary['Tags'] = implode(', ', $tag_names);
} else {
// Default - any
$tag_query = '';
}
// Location Filter
if (!empty($_POST['location'])) {
$filter_location_id = intval($_POST['location']);
$location_query = "AND (contact_location_id = $filter_location_id)";
$filter_summary['Location'] = getFieldById('locations', $filter_location_id, 'location_name');
} else {
// Default - any
$location_query = '';
}
// Search Filter
$q = escapeSql($_POST['q'] ?? '');
if (!empty($q)) {
$filter_summary['Search'] = $_POST['q'];
}
$sql = mysqli_query(
$mysqli,
"SELECT contacts.*, clients.*, locations.*, users.*
FROM contacts
LEFT JOIN clients ON client_id = contact_client_id
LEFT JOIN locations ON location_id = contact_location_id
LEFT JOIN users ON user_id = contact_user_id
LEFT JOIN contact_tags ON contact_tags.contact_id = contacts.contact_id
LEFT JOIN tags ON tags.tag_id = contact_tags.tag_id
WHERE $archive_query
$tag_query
AND (contact_name LIKE '%$q%' OR contact_title LIKE '%$q%' OR location_name LIKE '%$q%' OR contact_email LIKE '%$q%' OR contact_department LIKE '%$q%' OR contact_phone LIKE '%$q%' OR contact_mobile LIKE '%$q%' OR client_name LIKE '%$q%' OR tag_name LIKE '%$q%')
$access_permission_query
$client_query
$location_query
GROUP BY contact_id
ORDER BY contact_name ASC"
);
$num_rows = mysqli_num_rows($sql);
if ($num_rows > 0) {
$delimiter = ",";
$enclosure = '"';
$escape = '\\'; // backslash
$filename = sanitizeFilename($file_name_prepend . "Contacts-" . date('Y-m-d_H-i-s') . ".csv");
//create a file pointer
$f = fopen('php://memory', 'w');
guardExportPdfRowCount($format, $num_rows);
//set column headers
$fields = array('Name', 'Title', 'Department', 'Email', 'Phone', 'Ext', 'Mobile', 'Location');
fputcsv($f, $fields, $delimiter, $enclosure, $escape);
$export = beginExport('contacts', $format, $file_name_prepend . 'Contacts', 'Contacts', summarizeExportFilters($filter_summary));
//output each row of the data, format line as csv and write to file pointer
while($row = $sql->fetch_assoc()) {
$lineData = array($row['contact_name'], $row['contact_title'], $row['contact_department'], $row['contact_email'], formatPhoneNumber($row['contact_phone']), $row['contact_extension'], formatPhoneNumber($row['contact_mobile']), $row['location_name']);
fputcsv($f, array_map('escapeCsvFormula', $lineData), $delimiter, $enclosure, $escape);
while ($row = mysqli_fetch_assoc($sql)) {
addExportRow($export, $row);
}
//move back to beginning of file
fseek($f, 0);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
finishExport($export);
}
logAudit("Contact", "Export", "$session_name exported $num_rows contact(s) to a CSV file", $client_id);
logAudit("Contact", "Export", "$session_name exported $num_rows contact(s) to a " . strtoupper($format) . " file", $client_id);
exit;

View File

@@ -410,61 +410,107 @@ if (isset($_POST['bulk_delete_credentials'])) {
}
if (isset($_POST['export_credentials_csv'])) {
if (isset($_POST['export_credentials'])) {
validateCSRFToken();
// Exports are reads - see CONTRIBUTING.md
enforceUserPermission('module_credential');
if ($_POST['client_id']) {
$format = resolveExportFormat($_POST['export_credentials']);
// Filters inherited from the credentials page - mirrors agent/credentials.php
$filter_summary = [];
// Archived Filter
$archived = (isset($_POST['archived']) && $_POST['archived'] == 1);
if ($archived) {
$filter_summary['Archived'] = 'Archived only';
}
if (!empty($_POST['client_id'])) {
$client_id = intval($_POST['client_id']);
$client_query = "AND credential_client_id = $client_id";
$client_name = getFieldById('clients', $client_id, 'client_name');
$file_name_prepend = "$client_name-";
$filter_summary['Client'] = $client_name;
enforceClientAccess();
$archive_query = $archived ? "credential_archived_at IS NOT NULL" : "credential_archived_at IS NULL";
} else {
$client_query = '';
$client_id = 0;
$client_id = 0; // for Logging
$file_name_prepend = "$session_company_name-";
// Client Filter
if (!empty($_POST['client'])) {
$filter_client_id = intval($_POST['client']);
$client_query = "AND (credential_client_id = $filter_client_id)";
$filter_summary['Client'] = getFieldById('clients', $filter_client_id, 'client_name');
}
$archive_query = $archived ? "(client_archived_at IS NOT NULL OR credential_archived_at IS NOT NULL)" : "(client_archived_at IS NULL AND credential_archived_at IS NULL)";
}
//get records from database
$sql = mysqli_query($mysqli,"SELECT * FROM credentials LEFT JOIN clients ON client_id = credential_client_id WHERE credential_archived_at IS NULL $client_query $access_permission_query ORDER BY credential_name ASC");
// Tags Filter
if (isset($_POST['tags']) && is_array($_POST['tags']) && !empty($_POST['tags'])) {
$tag_filter = implode(",", array_map('intval', $_POST['tags']));
$tag_query = "AND tags.tag_id IN ($tag_filter)";
$tag_names = [];
$sql_tags = mysqli_query($mysqli, "SELECT tag_name FROM tags WHERE tag_id IN ($tag_filter) ORDER BY tag_name ASC");
while ($tag_row = mysqli_fetch_assoc($sql_tags)) {
$tag_names[] = $tag_row['tag_name'];
}
$filter_summary['Tags'] = implode(', ', $tag_names);
} else {
// Default - any
$tag_query = '';
}
// Search Filter
$q = escapeSql($_POST['q'] ?? '');
if (!empty($q)) {
$filter_summary['Search'] = $_POST['q'];
}
$sql = mysqli_query(
$mysqli,
"SELECT c.*, clients.*, contacts.*, assets.*
FROM credentials c
LEFT JOIN credential_tags ON credential_tags.credential_id = c.credential_id
LEFT JOIN tags ON tags.tag_id = credential_tags.tag_id
LEFT JOIN clients ON client_id = credential_client_id
LEFT JOIN contacts ON contact_id = credential_contact_id
LEFT JOIN assets ON asset_id = credential_asset_id
WHERE $archive_query
$tag_query
AND (c.credential_name LIKE '%$q%' OR c.credential_description LIKE '%$q%' OR c.credential_uri LIKE '%$q%' OR tag_name LIKE '%$q%' OR client_name LIKE '%$q%')
$access_permission_query
$client_query
GROUP BY c.credential_id
ORDER BY c.credential_name ASC"
);
$num_rows = mysqli_num_rows($sql);
if ($num_rows > 0) {
$delimiter = ",";
$enclosure = '"';
$escape = '\\'; // backslash
$filename = sanitizeFilename($file_name_prepend . "Credentials-" . date('Y-m-d_H-i-s') . ".csv");
//create a file pointer
$f = fopen('php://memory', 'w');
guardExportPdfRowCount($format, $num_rows);
//set column headers
$fields = array('Name', 'Description', 'Username', 'Password', 'TOTP', 'URI');
fputcsv($f, $fields, $delimiter, $enclosure, $escape);
$export = beginExport('credentials', $format, $file_name_prepend . 'Credentials', 'Credentials', summarizeExportFilters($filter_summary));
//output each row of the data, format line as csv and write to file pointer
while($row = mysqli_fetch_assoc($sql)){
$credential_username = decryptCredentialEntry($row['credential_username']);
$credential_password = decryptCredentialEntry($row['credential_password']);
$lineData = array($row['credential_name'], $row['credential_description'], $credential_username, $credential_password, $row['credential_otp_secret'], $row['credential_uri']);
fputcsv($f, array_map('escapeCsvFormula', $lineData), $delimiter, $enclosure, $escape);
while ($row = mysqli_fetch_assoc($sql)) {
$row['credential_username'] = decryptCredentialEntry($row['credential_username']);
$row['credential_password'] = decryptCredentialEntry($row['credential_password']);
addExportRow($export, $row);
}
//move back to beginning of file
fseek($f, 0);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
finishExport($export);
}
logAudit("Credential", "Export", "$session_name exported $num_rows credential(s) to a CSV file", $client_id);
logAudit("Credential", "Export", "$session_name exported $num_rows credential(s) to a " . strtoupper($format) . " file", $client_id);
exit;

View File

@@ -455,59 +455,103 @@ if (isset($_POST['bulk_refresh_domains'])) {
}
if (isset($_POST['export_domains_csv'])) {
if (isset($_POST['export_domains'])) {
validateCSRFToken();
// Exports are reads - see CONTRIBUTING.md
enforceUserPermission('module_support');
if ($_POST['client_id']) {
$format = resolveExportFormat($_POST['export_domains']);
// Filters inherited from the domains page - mirrors agent/domains.php
$filter_summary = [];
// Archived Filter
$archived = (isset($_POST['archived']) && $_POST['archived'] == 1);
if ($archived) {
$filter_summary['Archived'] = 'Archived only';
}
if (!empty($_POST['client_id'])) {
$client_id = intval($_POST['client_id']);
$client_query = "AND domain_client_id = $client_id";
$client_name = getFieldById('clients', $client_id, 'client_name');
$file_name_prepend = "$client_name-";
$filter_summary['Client'] = $client_name;
enforceClientAccess();
$archive_query = $archived ? "domain_archived_at IS NOT NULL" : "domain_archived_at IS NULL";
} else {
$client_query = '';
$client_id = 0;
$client_id = 0; // for Logging
$file_name_prepend = "$session_company_name-";
// Client Filter
if (!empty($_POST['client'])) {
$filter_client_id = intval($_POST['client']);
$client_query = "AND (domain_client_id = $filter_client_id)";
$filter_summary['Client'] = getFieldById('clients', $filter_client_id, 'client_name');
}
$archive_query = $archived ? "(client_archived_at IS NOT NULL OR domain_archived_at IS NOT NULL)" : "(client_archived_at IS NULL AND domain_archived_at IS NULL)";
}
$sql = mysqli_query($mysqli,"SELECT * FROM domains LEFT JOIN clients ON client_id = domain_client_id WHERE domain_archived_at IS NULL $client_query $access_permission_query ORDER BY domain_name ASC");
// Expiring In Filter
if (!empty($_POST['expire_days'])) {
if ($_POST['expire_days'] == "expired") {
$expire_query = "AND (domain_expire IS NOT NULL AND domain_expire != '0000-00-00' AND domain_expire < CURDATE())";
$filter_summary['Expiry'] = 'Expired';
} else {
$expire_days = intval($_POST['expire_days']);
$expire_query = "AND (domain_expire IS NOT NULL AND domain_expire != '0000-00-00' AND domain_expire BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL $expire_days DAY))";
$filter_summary['Expiry'] = "Expiring within $expire_days days";
}
} else {
// Default - any
$expire_query = '';
}
// Search Filter
$q = escapeSql($_POST['q'] ?? '');
if (!empty($q)) {
$filter_summary['Search'] = $_POST['q'];
}
$sql = mysqli_query(
$mysqli,
"SELECT domains.*, clients.*,
registrar.vendor_name AS domain_registrar_name,
webhost.vendor_name AS domain_webhost_name
FROM domains
LEFT JOIN clients ON client_id = domain_client_id
LEFT JOIN vendors AS registrar ON domains.domain_registrar = registrar.vendor_id
LEFT JOIN vendors AS webhost ON domains.domain_webhost = webhost.vendor_id
WHERE (domains.domain_name LIKE '%$q%' OR domains.domain_description LIKE '%$q%' OR registrar.vendor_name LIKE '%$q%' OR webhost.vendor_name LIKE '%$q%' OR client_name LIKE '%$q%')
AND $archive_query
$access_permission_query
$client_query
$expire_query
ORDER BY domains.domain_name ASC"
);
$num_rows = mysqli_num_rows($sql);
if ($num_rows > 0) {
$delimiter = ",";
$enclosure = '"';
$escape = '\\'; // backslash
$filename = sanitizeFilename($file_name_prepend . "Domains-" . date('Y-m-d_H-i-s') . ".csv");
//create a file pointer
$f = fopen('php://memory', 'w');
guardExportPdfRowCount($format, $num_rows);
//set column headers
$fields = array('Domain', 'Description', 'Registrar', 'Web Host', 'Expiration Date');
fputcsv($f, $fields, $delimiter, $enclosure, $escape);
$export = beginExport('domains', $format, $file_name_prepend . 'Domains', 'Domains', summarizeExportFilters($filter_summary));
//output each row of the data, format line as csv and write to file pointer
while($row = $sql->fetch_assoc()) {
$lineData = array($row['domain_name'], $row['domain_description'], $row['domain_registrar'], $row['domain_webhost'], $row['domain_expire']);
fputcsv($f, array_map('escapeCsvFormula', $lineData), $delimiter, $enclosure, $escape);
while ($row = mysqli_fetch_assoc($sql)) {
addExportRow($export, $row);
}
//move back to beginning of file
fseek($f, 0);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
finishExport($export);
}
logAudit("Domain", "Export", "$session_name exported $num_rows domain(s)", $client_id);
logAudit("Domain", "Export", "$session_name exported $num_rows domain(s) to a " . strtoupper($format) . " file", $client_id);
exit;

View File

@@ -298,96 +298,98 @@ if (isset($_POST['bulk_delete_expenses'])) {
}
if (isset($_POST['export_expenses_csv'])) {
if (isset($_POST['export_expenses'])) {
validateCSRFToken();
// Exports are reads - see CONTRIBUTING.md
enforceUserPermission('module_financial');
$date_from = escapeSql($_POST['date_from']);
$date_to = escapeSql($_POST['date_to']);
$account = intval($_POST['account']);
$vendor = intval($_POST['vendor']);
$category = intval($_POST['category']);
$format = resolveExportFormat($_POST['export_expenses']);
if (!empty($date_from) && !empty($date_to)) {
$date_query = "AND DATE(expense_date) BETWEEN '$date_from' AND '$date_to'";
$file_name_date = "$date_from-to-$date_to";
}else{
$date_query = "";
$file_name_date = date('Y-m-d');
}
// Filters inherited from the expenses page - mirrors agent/expenses.php
$filter_summary = [];
// Vendor Filter
if ($account) {
$account_query = "AND expense_account_id = $account";
$client_id = 0; // for Logging
$file_name_prepend = "$session_company_name-";
// Account Filter
if (!empty($_POST['account'])) {
$filter_account_id = intval($_POST['account']);
$account_query = "AND (expense_account_id = $filter_account_id)";
$filter_summary['Account'] = getFieldById('accounts', $filter_account_id, 'account_name');
} else {
// Default - any
$account_query = '';
}
// Vendor Filter
if ($vendor) {
$vendor_query = "AND expense_vendor_id = $vendor";
if (!empty($_POST['vendor'])) {
$filter_vendor_id = intval($_POST['vendor']);
$vendor_query = "AND (vendor_id = $filter_vendor_id)";
$filter_summary['Vendor'] = getFieldById('vendors', $filter_vendor_id, 'vendor_name');
} else {
// Default - any
$vendor_query = '';
}
// Category Filter
if ($category) {
$category_query = "AND expense_category_id = $category";
if (!empty($_POST['category'])) {
$filter_category_id = intval($_POST['category']);
$category_query = "AND (category_id = $filter_category_id)";
$filter_summary['Category'] = getFieldById('categories', $filter_category_id, 'category_name');
} else {
// Default - any
$category_query = '';
}
//get records from database
$sql = mysqli_query($mysqli,"SELECT * FROM expenses
LEFT JOIN categories ON expense_category_id = category_id
LEFT JOIN vendors ON expense_vendor_id = vendor_id
LEFT JOIN accounts ON expense_account_id = account_id
LEFT JOIN clients ON expense_client_id = client_id
WHERE expense_vendor_id > 0
$date_query
$account_query
$vendor_query
$category_query
$access_permission_query
ORDER BY expense_date DESC
");
$num_rows = mysqli_num_rows($sql);
if ($num_rows > 0) {
$delimiter = ",";
$enclosure = '"';
$escape = '\\'; // backslash
$filename = sanitizeFilename("$session_company_name-Expenses-" . date('Y-m-d_H-i-s') . ".csv");
//create a file pointer
$f = fopen('php://memory', 'w');
//set column headers
$fields = array('Date', 'Amount', 'Vendor', 'Description', 'Category', 'Account');
fputcsv($f, $fields, $delimiter, $enclosure, $escape);
//output each row of the data, format line as csv and write to file pointer
while($row = mysqli_fetch_assoc($sql)) {
$lineData = array($row['expense_date'], $row['expense_amount'], $row['vendor_name'], $row['expense_description'], $row['category_name'], $row['account_name']);
fputcsv($f, array_map('escapeCsvFormula', $lineData), $delimiter, $enclosure, $escape);
}
//move back to beginning of file
fseek($f, 0);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
// Date Filter
$dtf = escapeSql(!empty($_POST['dtf']) ? $_POST['dtf'] : '1970-01-01');
$dtt = escapeSql(!empty($_POST['dtt']) ? $_POST['dtt'] : '2099-12-31');
$date_range = formatExportDateRange($dtf, $dtt);
if ($date_range) {
$filter_summary['Dated'] = $date_range;
}
logAudit("Expense", "Export", "$session_name exported $num_rows expense(s) to CSV file");
// Search Filter
$q = escapeSql($_POST['q'] ?? '');
if (!empty($q)) {
$filter_summary['Search'] = $_POST['q'];
}
$sql = mysqli_query(
$mysqli,
"SELECT * FROM expenses
LEFT JOIN categories ON expense_category_id = category_id
LEFT JOIN vendors ON expense_vendor_id = vendor_id
LEFT JOIN accounts ON expense_account_id = account_id
LEFT JOIN clients ON expense_client_id = client_id
WHERE expense_vendor_id > 0
AND DATE(expense_date) BETWEEN '$dtf' AND '$dtt'
$vendor_query
$category_query
AND (vendor_name LIKE '%$q%' OR client_name LIKE '%$q%' OR category_name LIKE '%$q%' OR account_name LIKE '%$q%' OR expense_description LIKE '%$q%' OR expense_amount LIKE '%$q%')
$account_query
$access_permission_query
ORDER BY expense_date ASC"
);
$num_rows = mysqli_num_rows($sql);
if ($num_rows > 0) {
guardExportPdfRowCount($format, $num_rows);
$export = beginExport('expenses', $format, $file_name_prepend . 'Expenses', 'Expenses', summarizeExportFilters($filter_summary));
while ($row = mysqli_fetch_assoc($sql)) {
addExportRow($export, $row);
}
finishExport($export);
}
logAudit("Expense", "Export", "$session_name exported $num_rows expense(s) to a " . strtoupper($format) . " file", $client_id);
exit;

View File

@@ -9,12 +9,14 @@ if (!defined('FROM_POST_HANDLER')) {
exit;
}
if (isset($_POST['export_income_csv'])) {
if (isset($_POST['export_income'])) {
validateCSRFToken();
enforceUserPermission('module_financial');
$format = resolveExportFormat($_POST['export_income']);
$date_from = escapeSql($_POST['date_from']);
$date_to = escapeSql($_POST['date_to']);
$account = intval($_POST['account']);
@@ -139,36 +141,19 @@ if (isset($_POST['export_income_csv'])) {
$num_rows = mysqli_num_rows($sql);
if ($num_rows > 0) {
$delimiter = ",";
$enclosure = '"';
$escape = '\\'; // backslash
$filename = sanitizeFilename($file_name_prepend . "Income-" . date('Y-m-d_H-i-s') . ".csv");
//create a file pointer
$f = fopen('php://memory', 'w');
guardExportPdfRowCount($format, $num_rows);
//set column headers
$fields = array('Date', 'Type', 'Source', 'Description', 'Client', 'Amount', 'Currency', 'Payment Method', 'Reference', 'Account');
fputcsv($f, $fields, $delimiter, $enclosure, $escape);
$export = beginExport('income', $format, $file_name_prepend . 'Income', 'Income', summarizeExportFilters($filter_summary ?? []));
//output each row of the data, format line as csv and write to file pointer
while ($row = mysqli_fetch_assoc($sql)) {
$lineData = array($row['income_date'], $row['income_type'], $row['income_source'], $row['income_description'], $row['income_client'], $row['income_amount'], $row['income_currency_code'], $row['income_method'], $row['income_reference'], $row['income_account']);
fputcsv($f, array_map('escapeCsvFormula', $lineData), $delimiter, $enclosure, $escape);
addExportRow($export, $row);
}
//move back to beginning of file
fseek($f, 0);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
finishExport($export);
}
logAudit("Income", "Export", "$session_name exported $num_rows income record(s) to CSV file");
logAudit("Income", "Export", "$session_name exported $num_rows income record(s) to a " . strtoupper($format) . " file");
exit;

View File

@@ -650,69 +650,117 @@ if (isset($_GET['email_invoice'])) {
}
if (isset($_POST['export_invoices_csv'])) {
if (isset($_POST['export_invoices'])) {
validateCSRFToken();
enforceUserPermission('module_sales');
if ($_POST['client_id']) {
$format = resolveExportFormat($_POST['export_invoices']);
// Filters inherited from the invoices page - mirrors agent/invoices.php
$filter_summary = [];
if (!empty($_POST['client_id'])) {
$client_id = intval($_POST['client_id']);
$client_query = "1=1 AND invoice_client_id = $client_id";
$client_query = "AND invoice_client_id = $client_id";
$client_name = getFieldById('clients', $client_id, 'client_name');
$file_name_prepend = "$client_name-";
$filter_summary['Client'] = $client_name;
enforceClientAccess();
} else {
$client_query = '1=1 ';
$client_name = '';
$client_query = '';
$client_id = 0; // for Logging
$file_name_prepend = "$session_company_name-";
}
$date_from = escapeSql($_POST['date_from']);
$date_to = escapeSql($_POST['date_to']);
if (!empty($date_from) && !empty($date_to)) {
$date_query = "DATE(invoice_date) BETWEEN '$date_from' AND '$date_to'";
$file_name_date = "$date_from-to-$date_to";
}else{
$date_query = "";
$file_name_date = date('Y-m-d_H-i-s');
// Status Filter
$overdue_query = '';
if (!empty($_POST['status']) && $_POST['status'] == 'Draft') {
$status_query = "invoice_status = 'Draft'";
$filter_summary['Status'] = 'Draft';
} elseif (!empty($_POST['status']) && $_POST['status'] == 'Unpaid') {
$status_query = "invoice_status = 'Sent' OR invoice_status = 'Viewed' OR invoice_status = 'Partial'";
$filter_summary['Status'] = 'Unpaid';
} elseif (!empty($_POST['status']) && $_POST['status'] == 'Overdue') {
$status_query = "invoice_status = 'Sent' OR invoice_status = 'Viewed' OR invoice_status = 'Partial'";
$overdue_query = "AND (invoice_due < CURDATE())";
$filter_summary['Status'] = 'Overdue';
} else {
// Default - any
$status_query = "invoice_status LIKE '%'";
}
$sql = mysqli_query($mysqli,"SELECT * FROM invoices LEFT JOIN clients ON invoice_client_id = client_id WHERE $date_query AND $client_query $access_permission_query ORDER BY invoice_number ASC");
// Category Filter
if (!empty($_POST['category'])) {
$filter_category_id = intval($_POST['category']);
$category_query = "AND (category_id = $filter_category_id)";
$filter_summary['Category'] = getFieldById('categories', $filter_category_id, 'category_name');
} else {
// Default - any
$category_query = '';
}
// Date Filter - drives the file name too, when a real range is in play
$dtf = escapeSql(!empty($_POST['dtf']) ? $_POST['dtf'] : '1970-01-01');
$dtt = escapeSql(!empty($_POST['dtt']) ? $_POST['dtt'] : '2099-12-31');
$date_range = formatExportDateRange($dtf, $dtt);
if ($date_range) {
$filter_summary['Issued'] = $date_range;
$file_name_append = "-$dtf-to-$dtt";
} else {
$file_name_append = '';
}
// Search Filter
$q = escapeSql($_POST['q'] ?? '');
if (!empty($q)) {
$filter_summary['Search'] = $_POST['q'];
}
// Get records from database - same shape as the invoices page list query
$sql = 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 ($status_query)
$overdue_query
$category_query
AND DATE(invoice_date) BETWEEN '$dtf' AND '$dtt'
AND (CONCAT(invoice_prefix,invoice_number) LIKE '%$q%' OR invoice_scope LIKE '%$q%' OR client_name LIKE '%$q%' OR invoice_status LIKE '%$q%' OR invoice_amount LIKE '%$q%' OR category_name LIKE '%$q%')
$access_permission_query
$client_query
ORDER BY invoice_number ASC"
);
$num_rows = mysqli_num_rows($sql);
if ($num_rows > 0) {
$delimiter = ",";
$enclosure = '"';
$escape = '\\'; // backslash
$filename = sanitizeFilename($file_name_prepend . "Invoices-$file_name_date.csv");
//create a file pointer
$f = fopen('php://memory', 'w');
guardExportPdfRowCount($format, $num_rows);
//set column headers
$fields = array('Invoice Number', 'Scope', 'Amount', 'Issued Date', 'Due Date', 'Status');
fputcsv($f, $fields, $delimiter, $enclosure, $escape);
$export = beginExport('invoices', $format, $file_name_prepend . 'Invoices' . $file_name_append, 'Invoices', summarizeExportFilters($filter_summary));
//output each row of the data, format line as csv and write to file pointer
while($row = $sql->fetch_assoc()) {
$lineData = array($row['invoice_prefix'] . $row['invoice_number'], $row['invoice_scope'], $row['invoice_amount'], $row['invoice_date'], $row['invoice_due'], $row['invoice_status'], $row['client_name']);
fputcsv($f, array_map('escapeCsvFormula', $lineData), $delimiter, $enclosure, $escape);
while ($row = mysqli_fetch_assoc($sql)) {
$row['invoice_number_display'] = $row['invoice_prefix'] . $row['invoice_number'];
// Paid / balance are opt-in columns - only pay for the lookup if asked
if (isset($export['columns']['amount_paid']) || isset($export['columns']['invoice_balance'])) {
$invoice_id = intval($row['invoice_id']);
$payment_row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT SUM(payment_amount) AS amount_paid FROM payments WHERE payment_invoice_id = $invoice_id AND payment_archived_at IS NULL"));
$row['amount_paid'] = floatval($payment_row['amount_paid']);
$row['invoice_balance'] = floatval($row['invoice_amount']) - $row['amount_paid'];
}
addExportRow($export, $row);
}
//move back to beginning of file
fseek($f, 0);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
finishExport($export);
}
logAudit("Invoice", "Export", "$session_name exported $num_rows invoices to CSV file");
logAudit("Invoice", "Export", "$session_name exported $num_rows invoice(s) to a " . strtoupper($format) . " file", $client_id);
exit;

View File

@@ -388,59 +388,103 @@ if (isset($_POST['bulk_delete_locations'])) {
}
if(isset($_POST['export_locations_csv'])){
if (isset($_POST['export_locations'])) {
validateCSRFToken();
// Exports are reads - see CONTRIBUTING.md
enforceUserPermission('module_client');
if ($_POST['client_id']) {
$format = resolveExportFormat($_POST['export_locations']);
// Filters inherited from the locations page - mirrors agent/locations.php
$filter_summary = [];
// Archived Filter
$archived = (isset($_POST['archived']) && $_POST['archived'] == 1);
if ($archived) {
$filter_summary['Archived'] = 'Archived only';
}
if (!empty($_POST['client_id'])) {
$client_id = intval($_POST['client_id']);
$client_query = "AND location_client_id = $client_id";
$client_name = getFieldById('clients', $client_id, 'client_name');
$file_name_prepend = "$client_name-";
$filter_summary['Client'] = $client_name;
enforceClientAccess();
$archive_query = $archived ? "location_archived_at IS NOT NULL" : "location_archived_at IS NULL";
} else {
$client_query = '';
$client_id = 0;
$client_id = 0; // for Logging
$file_name_prepend = "$session_company_name-";
// Client Filter
if (!empty($_POST['client'])) {
$filter_client_id = intval($_POST['client']);
$client_query = "AND (location_client_id = $filter_client_id)";
$filter_summary['Client'] = getFieldById('clients', $filter_client_id, 'client_name');
}
$archive_query = $archived ? "(client_archived_at IS NOT NULL OR location_archived_at IS NOT NULL)" : "(client_archived_at IS NULL AND location_archived_at IS NULL)";
}
//Locations
$sql = mysqli_query($mysqli,"SELECT * FROM locations LEFT JOIN clients ON client_id = location_client_id WHERE location_archived_at IS NULL AND client_archived_at IS NULL $client_query $access_permission_query ORDER BY location_name ASC");
// Tags Filter
if (isset($_POST['tags']) && is_array($_POST['tags']) && !empty($_POST['tags'])) {
$tag_filter = implode(",", array_map('intval', $_POST['tags']));
$tag_query = "AND tags.tag_id IN ($tag_filter)";
$tag_names = [];
$sql_tags = mysqli_query($mysqli, "SELECT tag_name FROM tags WHERE tag_id IN ($tag_filter) ORDER BY tag_name ASC");
while ($tag_row = mysqli_fetch_assoc($sql_tags)) {
$tag_names[] = $tag_row['tag_name'];
}
$filter_summary['Tags'] = implode(', ', $tag_names);
} else {
// Default - any
$tag_query = '';
}
// Search Filter
$q = escapeSql($_POST['q'] ?? '');
if (!empty($q)) {
$filter_summary['Search'] = $_POST['q'];
}
$sql = mysqli_query(
$mysqli,
"SELECT locations.*, clients.*
FROM locations
LEFT JOIN clients ON client_id = location_client_id
LEFT JOIN location_tags ON location_tags.location_id = locations.location_id
LEFT JOIN tags ON tags.tag_id = location_tags.tag_id
WHERE $archive_query
$tag_query
AND (location_name LIKE '%$q%' OR location_description LIKE '%$q%' OR location_address LIKE '%$q%' OR location_city LIKE '%$q%' OR location_state LIKE '%$q%' OR location_zip LIKE '%$q%' OR location_country LIKE '%$q%' OR location_phone LIKE '%$q%' OR client_name LIKE '%$q%' OR tag_name LIKE '%$q%')
$access_permission_query
$client_query
GROUP BY location_id
ORDER BY location_name ASC"
);
$num_rows = mysqli_num_rows($sql);
if($num_rows > 0) {
$delimiter = ",";
$enclosure = '"';
$escape = '\\'; // backslash
$filename = sanitizeFilename($file_name_prepend . "Locations-" . date('Y-m-d_H-i-s') . ".csv");
if ($num_rows > 0) {
//create a file pointer
$f = fopen('php://memory', 'w');
guardExportPdfRowCount($format, $num_rows);
//set column headers
$fields = array('Name', 'Description', 'Address', 'City', 'State', 'Postal Code', 'Phone', 'Hours');
fputcsv($f, $fields, $delimiter, $enclosure, $escape);
$export = beginExport('locations', $format, $file_name_prepend . 'Locations', 'Locations', summarizeExportFilters($filter_summary));
//output each row of the data, format line as csv and write to file pointer
while($row = $sql->fetch_assoc()){
$lineData = array($row['location_name'], $row['location_description'], $row['location_address'], $row['location_city'], $row['location_state'], $row['location_zip'], $row['location_phone'], $row['location_hours']);
fputcsv($f, array_map('escapeCsvFormula', $lineData), $delimiter, $enclosure, $escape);
while ($row = mysqli_fetch_assoc($sql)) {
addExportRow($export, $row);
}
//move back to beginning of file
fseek($f, 0);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
finishExport($export);
}
logAudit("Location", "Export", "$session_name exported $num_rows location(s) to a CSV file", $client_id);
logAudit("Location", "Export", "$session_name exported $num_rows location(s) to a " . strtoupper($format) . " file", $client_id);
exit;

View File

@@ -172,59 +172,94 @@ if (isset($_POST['bulk_delete_networks'])) {
}
if (isset($_POST['export_networks_csv'])) {
if (isset($_POST['export_networks'])) {
validateCSRFToken();
// Exports are reads - see CONTRIBUTING.md
enforceUserPermission('module_support');
if ($_POST['client_id']) {
$format = resolveExportFormat($_POST['export_networks']);
// Filters inherited from the networks page - mirrors agent/networks.php
$filter_summary = [];
// Archived Filter
$archived = (isset($_POST['archived']) && $_POST['archived'] == 1);
if ($archived) {
$filter_summary['Archived'] = 'Archived only';
}
if (!empty($_POST['client_id'])) {
$client_id = intval($_POST['client_id']);
$client_query = "AND network_client_id = $client_id";
$client_name = getFieldById('clients', $client_id, 'client_name');
$file_name_prepend = "$client_name-";
$filter_summary['Client'] = $client_name;
enforceClientAccess();
$archive_query = $archived ? "network_archived_at IS NOT NULL" : "network_archived_at IS NULL";
} else {
$client_query = '';
$client_id = 0;
$client_id = 0; // for Logging
$file_name_prepend = "$session_company_name-";
// Client Filter
if (!empty($_POST['client'])) {
$filter_client_id = intval($_POST['client']);
$client_query = "AND (network_client_id = $filter_client_id)";
$filter_summary['Client'] = getFieldById('clients', $filter_client_id, 'client_name');
}
$archive_query = $archived ? "(client_archived_at IS NOT NULL OR network_archived_at IS NOT NULL)" : "(client_archived_at IS NULL AND network_archived_at IS NULL)";
}
$sql = mysqli_query($mysqli,"SELECT * FROM networks LEFT JOIN clients ON client_id = network_client_id WHERE network_archived_at IS NULL $client_query $access_permission_query ORDER BY network_name ASC");
// Location Filter
if (!empty($_POST['location'])) {
$filter_location_id = intval($_POST['location']);
$location_query = "AND (network_location_id = $filter_location_id)";
$filter_summary['Location'] = getFieldById('locations', $filter_location_id, 'location_name');
} else {
// Default - any
$location_query = '';
}
// Search Filter
$q = escapeSql($_POST['q'] ?? '');
if (!empty($q)) {
$filter_summary['Search'] = $_POST['q'];
}
$sql = mysqli_query(
$mysqli,
"SELECT * FROM networks
LEFT JOIN clients ON client_id = network_client_id
LEFT JOIN locations ON location_id = network_location_id
WHERE $archive_query
AND (network_name LIKE '%$q%' OR network_description LIKE '%$q%' OR network_vlan LIKE '%$q%' OR network LIKE '%$q%' OR network_gateway LIKE '%$q%' OR network_primary_dns LIKE '%$q%' OR network_secondary_dns LIKE '%$q%' OR client_name LIKE '%$q%')
$access_permission_query
$location_query
$client_query
ORDER BY network_name ASC"
);
$num_rows = mysqli_num_rows($sql);
if ($num_rows > 0) {
$delimiter = ",";
$enclosure = '"';
$escape = '\\'; // backslash
$filename = sanitizeFilename($file_name_prepend . "Networks-" . date('Y-m-d_H-i-s') . ".csv");
//create a file pointer
$f = fopen('php://memory', 'w');
guardExportPdfRowCount($format, $num_rows);
//set column headers
$fields = array('Name', 'Description', 'VLAN', 'Network (CIDR)', 'Gateway', 'IP Range', 'Primary DNS', 'Secondary DNS');
fputcsv($f, $fields, $delimiter, $enclosure, $escape);
$export = beginExport('networks', $format, $file_name_prepend . 'Networks', 'Networks', summarizeExportFilters($filter_summary));
//output each row of the data, format line as csv and write to file pointer
while ($row = $sql->fetch_assoc()) {
$lineData = array($row['network_name'], $row['network_description'], $row['network_vlan'], $row['network'], $row['network_gateway'], $row['network_dhcp_range'], $row['network_primary_dns'], $row['network_secondary_dns']);
fputcsv($f, array_map('escapeCsvFormula', $lineData), $delimiter, $enclosure, $escape);
while ($row = mysqli_fetch_assoc($sql)) {
addExportRow($export, $row);
}
//move back to beginning of file
fseek($f, 0);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
finishExport($export);
}
logAudit("Network", "Export", "$session_name deleted $num_rows network(s) to a CSV file", $client_id);
logAudit("Network", "Export", "$session_name exported $num_rows network(s) to a " . strtoupper($format) . " file", $client_id);
exit;
@@ -232,7 +267,7 @@ if (isset($_POST['export_networks_csv'])) {
// ============================================================
// Add these two blocks to agent/post/network.php
// Place them alongside the existing export_networks_csv block.
// Place them alongside the existing export_networks block.
// ============================================================
// ----------------------------------------------------------

View File

@@ -244,55 +244,90 @@ if (isset($_POST['bulk_delete_products'])) {
}
if (isset($_POST['export_products_csv'])) {
if (isset($_POST['export_products'])) {
validateCSRFToken();
// Exports are reads - see CONTRIBUTING.md
enforceUserPermission('module_sales');
//get records from database
$sql = mysqli_query($mysqli,"SELECT * FROM products
LEFT JOIN categories ON product_category_id = category_id
LEFT JOIN taxes ON product_tax_id = tax_id
WHERE product_archived_at IS NULL
ORDER BY product_name DESC
");
$format = resolveExportFormat($_POST['export_products']);
// Filters inherited from the products page - mirrors agent/products.php
$filter_summary = [];
// Archived Filter
$archived = (isset($_POST['archived']) && $_POST['archived'] == 1);
if ($archived) {
$filter_summary['Archived'] = 'Archived only';
}
$client_id = 0; // for Logging
$file_name_prepend = "$session_company_name-";
// Type Filter
if (isset($_POST['type']) && $_POST['type'] === 'product') {
$type_query = "AND product_type = 'product'";
$filter_summary['Type'] = 'Product';
} elseif (isset($_POST['type']) && $_POST['type'] === 'service') {
$type_query = "AND product_type = 'service'";
$filter_summary['Type'] = 'Service';
} else {
// Default - any
$type_query = '';
}
$archive_query = $archived ? "product_archived_at IS NOT NULL" : "product_archived_at IS NULL";
// Category Filter
if (!empty($_POST['category'])) {
$filter_category_id = intval($_POST['category']);
$category_query = "AND (category_id = $filter_category_id)";
$filter_summary['Category'] = getFieldById('categories', $filter_category_id, 'category_name');
} else {
// Default - any
$category_query = '';
}
// Search Filter
$q = escapeSql($_POST['q'] ?? '');
if (!empty($q)) {
$filter_summary['Search'] = $_POST['q'];
}
$sql = mysqli_query(
$mysqli,
"SELECT products.*, categories.*, taxes.*
FROM products
LEFT JOIN categories ON product_category_id = category_id
LEFT JOIN taxes ON product_tax_id = tax_id
WHERE (product_name LIKE '%$q%' OR product_description LIKE '%$q%' OR product_code LIKE '%$q%' OR product_location LIKE '%$q%' OR category_name LIKE '%$q%' OR product_price LIKE '%$q%' OR tax_name LIKE '%$q%')
$type_query
AND $archive_query
$category_query
GROUP BY product_id
ORDER BY product_name ASC"
);
$num_rows = mysqli_num_rows($sql);
if ($num_rows > 0) {
$delimiter = ",";
$enclosure = '"';
$escape = '\\'; // backslash
$filename = sanitizeFilename("$session_company_name-Products-" . date('Y-m-d_H-i-s') . ".csv");
//create a file pointer
$f = fopen('php://memory', 'w');
guardExportPdfRowCount($format, $num_rows);
//set column headers
$fields = array('Product', 'Description', 'Price', 'Currency', 'Category', 'Tax');
fputcsv($f, $fields, $delimiter, $enclosure, $escape);
$export = beginExport('products', $format, $file_name_prepend . 'Products', 'Products', summarizeExportFilters($filter_summary));
//output each row of the data, format line as csv and write to file pointer
while($row = mysqli_fetch_assoc($sql)) {
$lineData = array($row['product_name'], $row['product_description'], $row['product_price'], $row['product_currency_code'], $row['category_name'], $row['tax_name']);
fputcsv($f, array_map('escapeCsvFormula', $lineData), $delimiter, $enclosure, $escape);
while ($row = mysqli_fetch_assoc($sql)) {
addExportRow($export, $row);
}
//move back to beginning of file
fseek($f, 0);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
finishExport($export);
}
logAudit("Product", "Export", "$session_name exported $num_rows product(s) to a CSV file");
logAudit("Product", "Export", "$session_name exported $num_rows product(s) to a " . strtoupper($format) . " file", $client_id);
exit;
}
if (isset($_POST['add_product_stock'])) {

View File

@@ -685,62 +685,75 @@ if (isset($_GET['mark_quote_invoiced'])) {
}
if(isset($_POST['export_quotes_csv'])){
if (isset($_POST['export_quotes'])) {
validateCSRFToken();
// Exports are reads - see CONTRIBUTING.md
enforceUserPermission('module_sales');
if ($_POST['client_id']) {
$format = resolveExportFormat($_POST['export_quotes']);
// Filters inherited from the quotes page - mirrors agent/quotes.php
$filter_summary = [];
if (!empty($_POST['client_id'])) {
$client_id = intval($_POST['client_id']);
$client_query = "WHERE quote_client_id = $client_id";
// Get Client Name for logging
$client_query = "AND quote_client_id = $client_id";
$client_name = getFieldById('clients', $client_id, 'client_name');
$file_name_prepend = "$client_name-";
$filter_summary['Client'] = $client_name;
enforceClientAccess();
} else {
$client_query = 'WHERE 1=1';
$client_name = '';
$file_name_prepend = "$session_company_name";
$client_query = '';
$client_id = 0; // for Logging
$file_name_prepend = "$session_company_name-";
}
$sql = mysqli_query($mysqli,"SELECT * FROM quotes LEFT JOIN clients ON client_id = quote_client_id $client_query $access_permission_query ORDER BY quote_number ASC");
// Date Filter
$dtf = escapeSql(!empty($_POST['dtf']) ? $_POST['dtf'] : '1970-01-01');
$dtt = escapeSql(!empty($_POST['dtt']) ? $_POST['dtt'] : '2099-12-31');
$date_range = formatExportDateRange($dtf, $dtt);
if ($date_range) {
$filter_summary['Dated'] = $date_range;
}
// Search Filter
$q = escapeSql($_POST['q'] ?? '');
if (!empty($q)) {
$filter_summary['Search'] = $_POST['q'];
}
$sql = 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 (CONCAT(quote_prefix,quote_number) LIKE '%$q%' OR quote_scope LIKE '%$q%' OR category_name LIKE '%$q%' OR quote_status LIKE '%$q%' OR quote_amount LIKE '%$q%' OR client_name LIKE '%$q%')
AND DATE(quote_date) BETWEEN '$dtf' AND '$dtt'
$access_permission_query
$client_query
ORDER BY quote_number ASC"
);
$num_rows = mysqli_num_rows($sql);
if($num_rows > 0){
$delimiter = ",";
$enclosure = '"';
$escape = '\\'; // backslash
$filename = sanitizeFilename($file_name_prepend . "Quotes-" . date('Y-m-d_H-i-s') . ".csv");
if ($num_rows > 0) {
//create a file pointer
$f = fopen('php://memory', 'w');
guardExportPdfRowCount($format, $num_rows);
//set column headers
$fields = array('Quote Number', 'Scope', 'Amount', 'Date', 'Status');
fputcsv($f, $fields, $delimiter, $enclosure, $escape);
$export = beginExport('quotes', $format, $file_name_prepend . 'Quotes', 'Quotes', summarizeExportFilters($filter_summary));
//output each row of the data, format line as csv and write to file pointer
while($row = $sql->fetch_assoc()){
$lineData = array($row['quote_prefix'] . $row['quote_number'], $row['quote_scope'], $row['quote_amount'], $row['quote_date'], $row['quote_status']);
fputcsv($f, array_map('escapeCsvFormula', $lineData), $delimiter, $enclosure, $escape);
while ($row = mysqli_fetch_assoc($sql)) {
$row['quote_number_display'] = $row['quote_prefix'] . $row['quote_number'];
addExportRow($export, $row);
}
//move back to beginning of file
fseek($f, 0);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
finishExport($export);
}
logAudit("Quote", "Export", "$session_name exported $num_rows quote(s) to a CSV file");
flashAlert("Exported <strong>$num_rows</strong> quote(s)");
logAudit("Quote", "Export", "$session_name exported $num_rows quote(s) to a " . strtoupper($format) . " file", $client_id);
exit;

View File

@@ -605,55 +605,89 @@ if (isset($_POST['set_recurring_payment'])) {
}
if (isset($_POST['export_client_recurring_invoice_csv'])) {
if (isset($_POST['export_recurring_invoices'])) {
validateCSRFToken();
// Exports are reads - see CONTRIBUTING.md
enforceUserPermission('module_sales');
$client_id = intval($_POST['client_id']);
$format = resolveExportFormat($_POST['export_recurring_invoices']);
enforceClientAccess();
// Filters inherited from the recurring invoices page - mirrors agent/recurring_invoices.php
$filter_summary = [];
//get records from database
$sql = mysqli_query($mysqli,"SELECT client_name FROM clients WHERE client_id = $client_id");
$row = mysqli_fetch_assoc($sql);
if (!empty($_POST['client_id'])) {
$client_id = intval($_POST['client_id']);
$client_query = "AND recurring_invoice_client_id = $client_id";
$client_name = getFieldById('clients', $client_id, 'client_name');
$file_name_prepend = "$client_name-";
$filter_summary['Client'] = $client_name;
$client_name = $row['client_name'];
enforceClientAccess();
} else {
$client_query = '';
$client_id = 0; // for Logging
$file_name_prepend = "$session_company_name-";
}
$sql = mysqli_query($mysqli,"SELECT * FROM recurring_invoices WHERE recurring_invoice_client_id = $client_id ORDER BY recurring_invoice_number ASC");
// Status Filter
if (isset($_POST['status']) && $_POST['status'] === 'inactive') {
$status_query = "AND recurring_invoice_status = 0";
$filter_summary['Status'] = 'Inactive';
} elseif (isset($_POST['status']) && $_POST['status'] === 'active') {
$status_query = "AND recurring_invoice_status = 1";
$filter_summary['Status'] = 'Active';
} else {
// Default - any
$status_query = '';
}
// Date Filter
$dtf = escapeSql(!empty($_POST['dtf']) ? $_POST['dtf'] : '1970-01-01');
$dtt = escapeSql(!empty($_POST['dtt']) ? $_POST['dtt'] : '2099-12-31');
$date_range = formatExportDateRange($dtf, $dtt);
if ($date_range) {
$filter_summary['Created'] = $date_range;
}
// Search Filter
$q = escapeSql($_POST['q'] ?? '');
if (!empty($q)) {
$filter_summary['Search'] = $_POST['q'];
}
$sql = mysqli_query(
$mysqli,
"SELECT * FROM recurring_invoices
LEFT JOIN clients ON recurring_invoice_client_id = client_id
LEFT JOIN categories ON recurring_invoice_category_id = category_id
WHERE (CONCAT(recurring_invoice_prefix,recurring_invoice_number) LIKE '%$q%' OR recurring_invoice_frequency LIKE '%$q%' OR recurring_invoice_scope LIKE '%$q%' OR client_name LIKE '%$q%' OR category_name LIKE '%$q%')
AND DATE(recurring_invoice_created_at) BETWEEN '$dtf' AND '$dtt'
$status_query
$client_query
$access_permission_query
ORDER BY recurring_invoice_number ASC"
);
$num_rows = mysqli_num_rows($sql);
if ($num_rows > 0) {
$delimiter = ",";
$filename = $client_name . "-Recurring Invoices-" . date('Y-m-d') . ".csv";
//create a file pointer
$f = fopen('php://memory', 'w');
guardExportPdfRowCount($format, $num_rows);
//set column headers
$fields = array('Recurring Number', 'Scope', 'Amount', 'Frequency', 'Date Created');
fputcsv($f, $fields, $delimiter);
$export = beginExport('recurring_invoices', $format, $file_name_prepend . 'RecurringInvoices', 'Recurring Invoices', summarizeExportFilters($filter_summary));
//output each row of the data, format line as csv and write to file pointer
while($row = $sql->fetch_assoc()) {
$lineData = array($row['recurring_invoice_prefix'] . $row['recurring_invoice_number'], $row['recurring_invoice_scope'], $row['recurring_invoice_amount'], ucwords($row['recurring_invoice_frequency'] . "ly"), $row['recurring_invoice_created_at']);
fputcsv($f, array_map('escapeCsvFormula', $lineData), $delimiter);
while ($row = mysqli_fetch_assoc($sql)) {
$row['recurring_invoice_number_display'] = $row['recurring_invoice_prefix'] . $row['recurring_invoice_number'];
$row['recurring_invoice_frequency_display'] = ucwords($row['recurring_invoice_frequency'] . 'ly');
addExportRow($export, $row);
}
//move back to beginning of file
fseek($f, 0);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
finishExport($export);
}
logAudit("Recurring Invoice", "Export", "$session_name exported $num_rows recurring invoices to CSV file");
logAudit("Recurring Invoice", "Export", "$session_name exported $num_rows recurring invoice(s) to a " . strtoupper($format) . " file", $client_id);
exit;

View File

@@ -225,86 +225,118 @@ if (isset($_GET['delete_software'])) {
}
if (isset($_POST['export_software_csv'])) {
if (isset($_POST['export_software'])) {
validateCSRFToken();
// Exports are reads - see CONTRIBUTING.md
enforceUserPermission('module_support');
if ($_POST['client_id']) {
$client_id = intval($_POST['client_id']);
$client_query = "WHERE software_client_id = $client_id";
$client_name = getFieldById('clients', $client_id, 'client_name');
$file_name_prepend = "$client_name-";
} else {
$client_query = '';
$client_id = 0; //Logging
$file_name_prepend = "$session_company_name-";
$format = resolveExportFormat($_POST['export_software']);
// Filters inherited from the software page - mirrors agent/software.php
$filter_summary = [];
// Archived Filter
$archived = (isset($_POST['archived']) && $_POST['archived'] == 1);
if ($archived) {
$filter_summary['Archived'] = 'Archived only';
}
$sql = mysqli_query($mysqli,"SELECT * FROM software LEFT JOIN client ON client_id = software_client_id WHERE software_archived_at IS NULL $client_query $access_permission_query ORDER BY software_name ASC");
if (!empty($_POST['client_id'])) {
$client_id = intval($_POST['client_id']);
$client_query = "AND software_client_id = $client_id";
$client_name = getFieldById('clients', $client_id, 'client_name');
$file_name_prepend = "$client_name-";
$filter_summary['Client'] = $client_name;
enforceClientAccess();
$archive_query = $archived ? "software_archived_at IS NOT NULL" : "software_archived_at IS NULL";
} else {
$client_query = '';
$client_id = 0; // for Logging
$file_name_prepend = "$session_company_name-";
// Client Filter
if (!empty($_POST['client'])) {
$filter_client_id = intval($_POST['client']);
$client_query = "AND (software_client_id = $filter_client_id)";
$filter_summary['Client'] = getFieldById('clients', $filter_client_id, 'client_name');
}
$archive_query = $archived ? "(client_archived_at IS NOT NULL OR software_archived_at IS NOT NULL)" : "(client_archived_at IS NULL AND software_archived_at IS NULL)";
}
// Expiring In Filter
if (!empty($_POST['expire_days'])) {
if ($_POST['expire_days'] == "expired") {
$expire_query = "AND (software_expire IS NOT NULL AND software_expire != '0000-00-00' AND software_expire < CURDATE())";
$filter_summary['Expiry'] = 'Expired';
} else {
$expire_days = intval($_POST['expire_days']);
$expire_query = "AND (software_expire IS NOT NULL AND software_expire != '0000-00-00' AND software_expire BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL $expire_days DAY))";
$filter_summary['Expiry'] = "Expiring within $expire_days days";
}
} else {
// Default - any
$expire_query = '';
}
// Search Filter
$q = escapeSql($_POST['q'] ?? '');
if (!empty($q)) {
$filter_summary['Search'] = $_POST['q'];
}
$sql = mysqli_query(
$mysqli,
"SELECT * FROM software
LEFT JOIN clients ON client_id = software_client_id
LEFT JOIN vendors ON vendor_id = software_vendor_id
WHERE (software_name LIKE '%$q%' OR software_type LIKE '%$q%' OR software_key LIKE '%$q%' OR client_name LIKE '%$q%')
AND $archive_query
$access_permission_query
$client_query
$expire_query
ORDER BY software_name ASC"
);
$num_rows = mysqli_num_rows($sql);
if ($num_rows > 0) {
$delimiter = ",";
$enclosure = '"';
$escape = '\\'; // backslash
$filename = sanitizeFilename($file_name_prepend . "Software-" . date('Y-m-d_H-i-s') . ".csv");
//create a file pointer
$f = fopen('php://memory', 'w');
guardExportPdfRowCount($format, $num_rows);
//set column headers
$fields = array('Name', 'Version', 'Description', 'Type', 'License Type', 'Seats', 'Key', 'Assets', 'Contacts', 'Purchased', 'Expires', 'Notes');
fputcsv($f, $fields, $delimiter, $enclosure, $escape);
$export = beginExport('software', $format, $file_name_prepend . 'Software', 'Software', summarizeExportFilters($filter_summary));
//output each row of the data, format line as csv and write to file pointer
while($row = $sql->fetch_assoc()) {
// Generate asset & user license list for this software
// Asset licenses
$assigned_to_assets = '';
$asset_licenses_sql = mysqli_query($mysqli,"SELECT software_assets.asset_id, assets.asset_name
FROM software_assets
LEFT JOIN assets
ON software_assets.asset_id = assets.asset_id
WHERE software_id = $row[software_id]"
);
while($asset_row = mysqli_fetch_assoc($asset_licenses_sql)) {
$assigned_to_assets .= $asset_row['asset_name'] . ", ";
while ($row = mysqli_fetch_assoc($sql)) {
// Asset and contact licence lists, only when those columns are wanted
if (isset($export['columns']['assigned_to_assets'])) {
$software_id = intval($row['software_id']);
$assigned_to_assets = [];
$asset_licenses_sql = mysqli_query($mysqli, "SELECT asset_name FROM software_assets LEFT JOIN assets ON software_assets.asset_id = assets.asset_id WHERE software_id = $software_id");
while ($asset_row = mysqli_fetch_assoc($asset_licenses_sql)) {
$assigned_to_assets[] = $asset_row['asset_name'];
}
$row['assigned_to_assets'] = implode(', ', $assigned_to_assets);
}
// Contact Licenses
$assigned_to_contacts = '';
$contact_licenses_sql = mysqli_query($mysqli,"SELECT software_contacts.contact_id, contacts.contact_name
FROM software_contacts
LEFT JOIN contacts
ON software_contacts.contact_id = contacts.contact_id
WHERE software_id = $row[software_id]"
);
while($contact_row = mysqli_fetch_assoc($contact_licenses_sql)) {
$assigned_to_contacts .= $contact_row['contact_name'] . ", ";
if (isset($export['columns']['assigned_to_contacts'])) {
$software_id = intval($row['software_id']);
$assigned_to_contacts = [];
$contact_licenses_sql = mysqli_query($mysqli, "SELECT contact_name FROM software_contacts LEFT JOIN contacts ON software_contacts.contact_id = contacts.contact_id WHERE software_id = $software_id");
while ($contact_row = mysqli_fetch_assoc($contact_licenses_sql)) {
$assigned_to_contacts[] = $contact_row['contact_name'];
}
$row['assigned_to_contacts'] = implode(', ', $assigned_to_contacts);
}
$lineData = array($row['software_name'], $row['software_version'], $row['software_description'], $row['software_type'], $row['software_license_type'], $row['software_seats'], $row['software_key'], $assigned_to_assets, $assigned_to_contacts, $row['software_purchase'], $row['software_expire'], $row['software_notes']);
fputcsv($f, array_map('escapeCsvFormula', $lineData), $delimiter, $enclosure, $escape);
addExportRow($export, $row);
}
//move back to beginning of file
fseek($f, 0);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
finishExport($export);
}
logAudit("Software", "Export", "$session_name exported $num_rows software(s) $software_name to a CSV file", $client_id);
logAudit("Software", "Export", "$session_name exported $num_rows software(s) to a " . strtoupper($format) . " file", $client_id);
exit;

View File

@@ -2695,59 +2695,193 @@ if (isset($_POST['add_quote_from_ticket'])) {
}
if (isset($_POST['export_tickets_csv'])) {
if (isset($_POST['export_tickets'])) {
validateCSRFToken();
enforceUserPermission('module_support', 2);
// Exports are reads - see CONTRIBUTING.md
enforceUserPermission('module_support');
if ($_POST['client_id']) {
$format = resolveExportFormat($_POST['export_tickets']);
// Filters inherited from the tickets page - mirrors agent/tickets.php
$filter_summary = [];
if (!empty($_POST['client_id'])) {
$client_id = intval($_POST['client_id']);
$client_query = "WHERE ticket_client_id = $client_id";
$client_query = "AND ticket_client_id = $client_id";
$client_name = getFieldById('clients', $client_id, 'client_name');
$file_name_prepend = "$client_name-";
$filter_summary['Client'] = $client_name;
enforceClientAccess();
} else {
$client_query = '';
$client_name = '';
$client_id = 0; // for Logging
$file_name_prepend = "$session_company_name-";
// Client Filter - the global ticket list can be narrowed to one client
if (!empty($_POST['client'])) {
$filter_client_id = intval($_POST['client']);
$client_query = "AND ticket_client_id = $filter_client_id";
$filter_summary['Client'] = getFieldById('clients', $filter_client_id, 'client_name');
}
}
// Status Filter - a set of status IDs, or the Open / Closed shorthand
if (isset($_POST['status']) && is_array($_POST['status']) && !empty($_POST['status'])) {
$status_ids = implode(",", array_map('intval', $_POST['status']));
$ticket_status_snippet = "ticket_status IN ($status_ids)";
$status_names = [];
$sql_statuses = mysqli_query($mysqli, "SELECT ticket_status_name FROM ticket_statuses WHERE ticket_status_id IN ($status_ids) ORDER BY ticket_status_name ASC");
while ($status_row = mysqli_fetch_assoc($sql_statuses)) {
$status_names[] = $status_row['ticket_status_name'];
}
$filter_summary['Status'] = implode(', ', $status_names);
} elseif (!empty($_POST['resolution']) && $_POST['resolution'] == 'Closed') {
$ticket_status_snippet = "ticket_resolved_at IS NOT NULL";
$filter_summary['Status'] = 'Closed';
} else {
// Default - open tickets
$ticket_status_snippet = "ticket_resolved_at IS NULL";
$filter_summary['Status'] = 'Open';
}
// Billable / unbilled Filter - overrides the status snippet, same as the page
if (isset($_POST['billable']) && $_POST['billable'] == 1 && isset($_POST['unbilled'])) {
$ticket_billable_snippet = "AND ticket_billable = 1 AND ticket_invoice_id = 0";
$ticket_status_snippet = '1 = 1';
$filter_summary['Billable'] = 'Billable, not yet invoiced';
} else {
$ticket_billable_snippet = '';
}
// Category Filter
if (!empty($_POST['category'])) {
$filter_category_id = intval($_POST['category']);
$category_query = "AND (ticket_category = $filter_category_id)";
$filter_summary['Category'] = getFieldById('categories', $filter_category_id, 'category_name');
} else {
// Default - any
$category_query = '';
}
// Assignment Filter
if (!empty($_POST['assigned'])) {
if ($_POST['assigned'] == 'unassigned') {
$ticket_assigned_query = 'AND ticket_assigned_to = 0';
$filter_summary['Assigned'] = 'Unassigned';
} else {
$filter_user_id = intval($_POST['assigned']);
$ticket_assigned_query = "AND ticket_assigned_to = $filter_user_id";
$filter_summary['Assigned'] = getFieldById('users', $filter_user_id, 'user_name');
}
} else {
// Default - any
$ticket_assigned_query = '';
}
// SLA State Filter
$ticket_sla_query = '';
if (!empty($_POST['sla'])) {
$sla_filter = $_POST['sla'];
if ($sla_filter == 'breached') {
$ticket_sla_query = 'AND ticket_sla_id > 0 AND (ticket_response_sla_alert_stage = 2 OR ticket_resolution_sla_alert_stage = 2 OR ticket_response_sla_met = 0 OR ticket_resolution_sla_met = 0)';
$filter_summary['SLA'] = 'SLA breached';
} elseif ($sla_filter == 'at_risk') {
$ticket_sla_query = 'AND ticket_sla_id > 0 AND COALESCE(ticket_status_pauses_sla, 0) = 0 AND (ticket_response_sla_alert_stage = 1 OR ticket_resolution_sla_alert_stage = 1)';
$filter_summary['SLA'] = 'SLA at risk';
} elseif ($sla_filter == 'paused') {
$ticket_sla_query = 'AND ticket_sla_id > 0 AND ticket_status_pauses_sla = 1';
$filter_summary['SLA'] = 'SLA paused';
} elseif ($sla_filter == 'met') {
$ticket_sla_query = 'AND ticket_sla_id > 0 AND ticket_response_sla_met = 1 AND (ticket_resolution_sla_met = 1 OR ticket_resolution_due_at IS NULL)';
$filter_summary['SLA'] = 'SLA met';
} elseif ($sla_filter == 'none') {
$ticket_sla_query = 'AND ticket_sla_id = 0';
$filter_summary['SLA'] = 'No SLA';
}
}
// Project Filter
if (!empty($_POST['project']) && $_POST['project'] > '0') {
$filter_project_id = intval($_POST['project']);
$ticket_project_snippet = "AND ticket_project_id = $filter_project_id";
$filter_summary['Project'] = getFieldById('projects', $filter_project_id, 'project_name');
} else {
// Default - any, including tickets without a project
$ticket_project_snippet = '';
}
// Client access override - the only way tickets without a client reach agents
// with restricted client access
$access_permission_query_overide = '';
if ($client_access_string) {
$access_permission_query_overide = "AND ticket_client_id IN (0,$client_access_string)";
}
// Date Filter
$dtf = escapeSql(!empty($_POST['dtf']) ? $_POST['dtf'] : '1970-01-01');
$dtt = escapeSql(!empty($_POST['dtt']) ? $_POST['dtt'] : '2099-12-31');
$date_range = formatExportDateRange($dtf, $dtt);
if ($date_range) {
$filter_summary['Opened'] = $date_range;
}
// Search Filter
$q = escapeSql($_POST['q'] ?? '');
if (!empty($q)) {
$filter_summary['Search'] = $_POST['q'];
}
// Get records from database - same shape as the tickets page list query
$sql = mysqli_query(
$mysqli,
"SELECT * FROM tickets
LEFT JOIN clients ON ticket_client_id = client_id
LEFT JOIN contacts ON ticket_contact_id = contact_id
LEFT JOIN users ON ticket_assigned_to = user_id
LEFT JOIN assets ON ticket_asset_id = asset_id
LEFT JOIN locations ON ticket_location_id = location_id
LEFT JOIN vendors ON ticket_vendor_id = vendor_id
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
$client_query ORDER BY ticket_number ASC"
LEFT JOIN categories ON ticket_category = category_id
WHERE $ticket_status_snippet
$ticket_assigned_query
$category_query
AND DATE(ticket_created_at) BETWEEN '$dtf' AND '$dtt'
AND (CONCAT(ticket_prefix,ticket_number) LIKE '%$q%' OR client_name LIKE '%$q%' OR ticket_subject LIKE '%$q%' OR ticket_status_name LIKE '%$q%' OR ticket_priority LIKE '%$q%' OR user_name LIKE '%$q%' OR contact_name LIKE '%$q%' OR asset_name LIKE '%$q%' OR vendor_name LIKE '%$q%')
$ticket_sla_query
$ticket_billable_snippet
$ticket_project_snippet
$access_permission_query_overide
$client_query
ORDER BY ticket_number ASC"
);
if ($sql->num_rows > 0) {
$delimiter = ",";
$enclosure = '"';
$escape = '\\'; // backslash
$filename = sanitizeFilename($file_name_prepend . "Tickets-" . date('Y-m-d_H-i-s') . ".csv");
$num_rows = mysqli_num_rows($sql);
//create a file pointer
$f = fopen('php://memory', 'w');
if ($num_rows > 0) {
//set column headers
$fields = array('Ticket Number', 'Priority', 'Status', 'Subject', 'Date Opened', 'Date Resolved', 'Date Closed');
fputcsv($f, $fields, $delimiter, $enclosure, $escape);
guardExportPdfRowCount($format, $num_rows);
//output each row of the data, format line as csv and write to file pointer
while ($row = $sql->fetch_assoc()) {
$lineData = array($config_ticket_prefix . $row['ticket_number'], $row['ticket_priority'], $row['ticket_status_name'], $row['ticket_subject'], $row['ticket_created_at'], $row['ticket_resolved_at'], $row['ticket_closed_at']);
fputcsv($f, array_map('escapeCsvFormula', $lineData), $delimiter, $enclosure, $escape);
$export = beginExport('tickets', $format, $file_name_prepend . 'Tickets', 'Tickets', summarizeExportFilters($filter_summary));
while ($row = mysqli_fetch_assoc($sql)) {
// Per-ticket prefix where the row carries one, config default otherwise
$row['ticket_number_display'] = ($row['ticket_prefix'] ?: $config_ticket_prefix) . $row['ticket_number'];
$row['ticket_category_name'] = $row['category_name'];
$row['ticket_assigned_to'] = $row['user_name'];
$row['ticket_billable'] = $row['ticket_billable'] ? 'Yes' : 'No';
addExportRow($export, $row);
}
//move back to beginning of file
fseek($f, 0);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
finishExport($export);
}
logAudit("Ticket", "Export", "$session_name exported $num_rows ticket(s) to a " . strtoupper($format) . " file", $client_id);
exit;
}

View File

@@ -9,12 +9,17 @@ if (!defined('FROM_POST_HANDLER')) {
exit;
}
if (isset($_POST['export_transactions_csv'])) {
if (isset($_POST['export_transactions'])) {
validateCSRFToken();
enforceUserPermission('module_financial');
$format = resolveExportFormat($_POST['export_transactions']);
// Human-readable filter list for the PDF header
$filter_summary = [];
$date_from = escapeSql($_POST['date_from']);
$date_to = escapeSql($_POST['date_to']);
$account = intval($_POST['account']);
@@ -24,6 +29,7 @@ if (isset($_POST['export_transactions_csv'])) {
$transaction_types_array = ['Revenue', 'Payment', 'Expense', 'Transfer In', 'Transfer Out'];
if (!empty($_POST['type']) && in_array($_POST['type'], $transaction_types_array)) {
$type_query = "AND (transaction_type = '" . escapeSql($_POST['type']) . "')";
$filter_summary['Type'] = $_POST['type'];
} else {
// Default - any
$type_query = '';
@@ -32,6 +38,8 @@ if (isset($_POST['export_transactions_csv'])) {
// Category Filter
if ($category) {
$category_query = "AND (transaction_category_id = $category)";
$category_row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT category_name FROM categories WHERE category_id = $category"));
$filter_summary['Category'] = $category_row['category_name'] ?? '';
} else {
// Default - any
$category_query = '';
@@ -41,6 +49,8 @@ if (isset($_POST['export_transactions_csv'])) {
$client = intval($_POST['client']);
if ($client) {
$client_query = "AND (transaction_client_id = $client)";
$client_row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT client_name FROM clients WHERE client_id = $client"));
$filter_summary['Client'] = $client_row['client_name'] ?? '';
} else {
// Default - any
$client_query = '';
@@ -49,6 +59,7 @@ if (isset($_POST['export_transactions_csv'])) {
// Payment Method Filter
if (!empty($_POST['payment_method'])) {
$payment_method_query = "AND (transaction_payment_method = '" . escapeSql($_POST['payment_method']) . "')";
$filter_summary['Payment Method'] = $_POST['payment_method'];
} else {
// Default - any
$payment_method_query = '';
@@ -57,12 +68,14 @@ if (isset($_POST['export_transactions_csv'])) {
// Amount Range Filter - matched on absolute value so direction doesn't matter
if (isset($_POST['amount_min']) && $_POST['amount_min'] != '') {
$amount_min_query = 'AND (ABS(transaction_amount) >= ' . floatval($_POST['amount_min']) . ')';
$filter_summary['Amount from'] = floatval($_POST['amount_min']);
} else {
// Default - any
$amount_min_query = '';
}
if (isset($_POST['amount_max']) && $_POST['amount_max'] != '') {
$amount_max_query = 'AND (ABS(transaction_amount) <= ' . floatval($_POST['amount_max']) . ')';
$filter_summary['Amount to'] = floatval($_POST['amount_max']);
} else {
// Default - any
$amount_max_query = '';
@@ -71,6 +84,7 @@ if (isset($_POST['export_transactions_csv'])) {
// Search Filter - mirrors the transactions page search box
$q = escapeSql($_POST['q']);
if (!empty($q)) {
$filter_summary['Search'] = $_POST['q'];
$search_query = "AND (transaction_description LIKE '%$q%' OR transaction_category LIKE '%$q%' OR transaction_reference LIKE '%$q%' OR transaction_other_account LIKE '%$q%' OR transaction_amount LIKE '%$q%')";
} else {
// Default - any
@@ -80,6 +94,7 @@ if (isset($_POST['export_transactions_csv'])) {
// Date Filter
if (!empty($date_from) && !empty($date_to)) {
$date_query = "AND DATE(transaction_date) BETWEEN '$date_from' AND '$date_to'";
$filter_summary['Date'] = "$date_from to $date_to";
} else {
$date_query = '';
}
@@ -178,36 +193,19 @@ if (isset($_POST['export_transactions_csv'])) {
$num_rows = mysqli_num_rows($sql);
if ($num_rows > 0) {
$delimiter = ",";
$enclosure = '"';
$escape = '\\'; // backslash
$filename = sanitizeFilename("$session_company_name-$account_name-Transactions-" . date('Y-m-d_H-i-s') . ".csv");
//create a file pointer
$f = fopen('php://memory', 'w');
guardExportPdfRowCount($format, $num_rows);
//set column headers
$fields = array('Date', 'Type', 'Description', 'Transfer Account', 'Reference', 'Category', 'Payment Method', 'Amount', 'Balance');
fputcsv($f, $fields, $delimiter, $enclosure, $escape);
$export = beginExport('transactions', $format, "$session_company_name-$account_name-Transactions", "$account_name - Transactions", summarizeExportFilters($filter_summary));
//output each row of the data, format line as csv and write to file pointer
while ($row = mysqli_fetch_assoc($sql)) {
$lineData = array($row['transaction_date'], $row['transaction_type'], $row['transaction_description'], $row['transaction_other_account'], $row['transaction_reference'], $row['transaction_category'], $row['transaction_payment_method'], $row['transaction_amount'], $row['transaction_balance']);
fputcsv($f, array_map('escapeCsvFormula', $lineData), $delimiter, $enclosure, $escape);
addExportRow($export, $row);
}
//move back to beginning of file
fseek($f, 0);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
finishExport($export);
}
logAudit("Transaction", "Export", "$session_name exported $num_rows transaction(s) to CSV file");
logAudit("Transaction", "Export", "$session_name exported $num_rows transaction(s) to a " . strtoupper($format) . " file");
}

View File

@@ -84,76 +84,76 @@ if (isset($_GET['delete_trip'])) {
}
if (isset($_POST['export_trips_csv'])) {
if (isset($_POST['export_trips'])) {
validateCSRFToken();
// Exports are reads - see CONTRIBUTING.md
enforceUserPermission('module_financial');
if ($_POST['client_id']) {
$format = resolveExportFormat($_POST['export_trips']);
// Filters inherited from the trips page - mirrors agent/trips.php
$filter_summary = [];
if (!empty($_POST['client_id'])) {
$client_id = intval($_POST['client_id']);
$client_query = "AND trip_client_id = $client_id";
$client_name = getFieldById('clients', $client_id, 'client_name');
$file_name_prepend = "$client_name-";
$filter_summary['Client'] = $client_name;
enforceClientAccess();
} else {
$client_query = '';
$client_name = '';
$client_id = 0; // for Logging
$file_name_prepend = "$session_company_name-";
}
$date_from = escapeSql($_POST['date_from']);
$date_to = escapeSql($_POST['date_to']);
if (!empty($date_from) && !empty($date_to)){
$date_query = "DATE(trip_date) BETWEEN '$date_from' AND '$date_to'";
$file_name_date = "$date_from-to-$date_to";
} else {
$date_query = "trip_date IS NOT NULL";
$file_name_date = date('Y-m-d');
// Date Filter
$dtf = escapeSql(!empty($_POST['dtf']) ? $_POST['dtf'] : '1970-01-01');
$dtt = escapeSql(!empty($_POST['dtt']) ? $_POST['dtt'] : '2099-12-31');
$date_range = formatExportDateRange($dtf, $dtt);
if ($date_range) {
$filter_summary['Dated'] = $date_range;
}
//get records from database
$sql = mysqli_query($mysqli,"SELECT * FROM trips
// Search Filter
$q = escapeSql($_POST['q'] ?? '');
if (!empty($q)) {
$filter_summary['Search'] = $_POST['q'];
}
$sql = mysqli_query(
$mysqli,
"SELECT * FROM trips
LEFT JOIN clients ON trip_client_id = client_id
WHERE $date_query
LEFT JOIN users ON trip_user_id = user_id
WHERE (trip_purpose LIKE '%$q%' OR trip_source LIKE '%$q%' OR trip_destination LIKE '%$q%' OR trip_miles LIKE '%$q%' OR client_name LIKE '%$q%' OR user_name LIKE '%$q%')
AND DATE(trip_date) BETWEEN '$dtf' AND '$dtt'
AND trip_archived_at IS NULL
$client_query
$access_permission_query
ORDER BY trip_date DESC"
ORDER BY trip_date ASC"
);
$count = mysqli_num_rows($sql);
$num_rows = mysqli_num_rows($sql);
if ($count > 0) {
$delimiter = ",";
$enclosure = '"';
$escape = '\\'; // backslash
$filename = sanitizeFilename($file_name_prepend . "Trips-" . date('Y-m-d_H-i-s') . ".csv");
if ($num_rows > 0) {
//create a file pointer
$f = fopen('php://memory', 'w');
guardExportPdfRowCount($format, $num_rows);
//set column headers
$fields = array('Date', 'Purpose', 'Source', 'Destination', 'Miles');
fputcsv($f, $fields, $delimiter, $enclosure, $escape);
$export = beginExport('trips', $format, $file_name_prepend . 'Trips', 'Trips', summarizeExportFilters($filter_summary));
//output each row of the data, format line as csv and write to file pointer
while($row = mysqli_fetch_assoc($sql)){
$lineData = array($row['trip_date'], $row['trip_purpose'], $row['trip_source'], $row['trip_destination'], $row['trip_miles']);
fputcsv($f, array_map('escapeCsvFormula', $lineData), $delimiter, $enclosure, $escape);
while ($row = mysqli_fetch_assoc($sql)) {
addExportRow($export, $row);
}
//move back to beginning of file
fseek($f, 0);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
logAudit("Trip", "Export", "$session_name exported $count trip(s) to a CSV file");
finishExport($export);
}
logAudit("Trip", "Export", "$session_name exported $num_rows trip(s) to a " . strtoupper($format) . " file", $client_id);
exit;
}

View File

@@ -350,59 +350,74 @@ if (isset($_POST['bulk_delete_vendors'])) {
}
if (isset($_POST['export_vendors_csv'])) {
if (isset($_POST['export_vendors'])) {
validateCSRFToken();
if ($_POST['client_id']) {
// Exports are reads - see CONTRIBUTING.md
enforceUserPermission('module_client');
$format = resolveExportFormat($_POST['export_vendors']);
// Filters inherited from the vendors page - mirrors agent/vendors.php
$filter_summary = [];
// Archived Filter
$archived = (isset($_POST['archived']) && $_POST['archived'] == 1);
if ($archived) {
$filter_summary['Archived'] = 'Archived only';
}
if (!empty($_POST['client_id'])) {
$client_id = intval($_POST['client_id']);
$client_query = "WHERE vendor_client_id = $client_id";
$client_query = "AND vendor_client_id = $client_id";
$client_name = getFieldById('clients', $client_id, 'client_name');
$file_name_prepend = "$client_name-";
enforceUserPermission('module_client');
$filter_summary['Client'] = $client_name;
enforceClientAccess();
} else {
$client_query = "WHERE vendor_client_id = 0";
$client_name = '';
// Global vendors only, same as the vendors page
$client_query = "AND vendor_client_id = 0";
$client_id = 0; // for Logging
$file_name_prepend = "$session_company_name-";
enforceUserPermission('module_financial');
}
$sql = mysqli_query($mysqli,"SELECT * FROM vendors LEFT JOIN clients ON client_id = vendor_client_id $client_query ORDER BY vendor_name ASC");
$archive_query = $archived ? "vendor_archived_at IS NOT NULL" : "vendor_archived_at IS NULL";
$count = mysqli_num_rows($sql);
// Search Filter
$q = escapeSql($_POST['q'] ?? '');
if (!empty($q)) {
$filter_summary['Search'] = $_POST['q'];
}
if ($count > 0) {
$delimiter = ",";
$enclosure = '"';
$escape = '\\'; // backslash
$filename = sanitizeFilename($file_name_prepend . "Vendors-" . date('Y-m-d_H-i-s') . ".csv");
$sql = mysqli_query(
$mysqli,
"SELECT * FROM vendors
LEFT JOIN clients ON client_id = vendor_client_id
WHERE $archive_query
AND (vendor_name LIKE '%$q%' OR vendor_description LIKE '%$q%' OR vendor_account_number LIKE '%$q%' OR vendor_website LIKE '%$q%' OR vendor_contact_name LIKE '%$q%' OR vendor_email LIKE '%$q%' OR vendor_phone LIKE '%$q%')
$client_query
$access_permission_query
ORDER BY vendor_name ASC"
);
//create a file pointer
$f = fopen('php://memory', 'w');
$num_rows = mysqli_num_rows($sql);
//set column headers
$fields = array('Name', 'Description', 'Contact Name', 'Phone', 'Website', 'Account Number', 'Notes');
fputcsv($f, $fields, $delimiter, $enclosure, $escape);
if ($num_rows > 0) {
//output each row of the data, format line as csv and write to file pointer
while($row = $sql->fetch_assoc()) {
$lineData = array($row['vendor_name'], $row['vendor_description'], $row['vendor_contact_name'], $row['vendor_phone'], $row['vendor_website'], $row['vendor_account_number'], $row['vendor_notes']);
fputcsv($f, array_map('escapeCsvFormula', $lineData), $delimiter, $enclosure, $escape);
guardExportPdfRowCount($format, $num_rows);
$export = beginExport('vendors', $format, $file_name_prepend . 'Vendors', 'Vendors', summarizeExportFilters($filter_summary));
while ($row = mysqli_fetch_assoc($sql)) {
addExportRow($export, $row);
}
//move back to beginning of file
fseek($f, 0);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
finishExport($export);
}
logAudit("Vendor", "Export", "$session_name exported $count vendor(s) to a CSV file");
logAudit("Vendor", "Export", "$session_name exported $num_rows vendor(s) to a " . strtoupper($format) . " file", $client_id);
exit;

View File

@@ -70,7 +70,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<a class="dropdown-item text-dark ajax-modal"
data-modal-url="modals/product/product_export.php">
data-modal-url="<?= buildExportModalUrl('modals/product/product_export.php', ['type', 'category', 'archived', 'q']) ?>">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
</div>

View File

@@ -45,7 +45,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<a class="dropdown-item text-dark ajax-modal" href="#"
data-modal-url="modals/quote/quote_export.php?<?= $client_url ?>">
data-modal-url="<?= buildExportModalUrl('modals/quote/quote_export.php', ['client_id', 'q'], ['dtf' => $dtf, 'dtt' => $dtt]) ?>">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
</div>

View File

@@ -50,7 +50,18 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<h3 class="card-title mt-2"><i class="fa fa-redo-alt mr-2"></i>Recurring Invoices</h3>
<?php if (lookupUserPermission("module_sales") >= 2) { ?>
<div class="card-tools">
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/recurring_invoice/recurring_invoice_add.php?<?= $client_url ?>"><i class="fas fa-plus"></i><span class="d-none d-lg-inline ml-2">New Recurring Invoice</span></button>
<div class="btn-group">
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/recurring_invoice/recurring_invoice_add.php?<?= $client_url ?>"><i class="fas fa-plus"></i><span class="d-none d-lg-inline ml-2">New Recurring Invoice</span></button>
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<?php if ($num_rows[0] > 0) { ?>
<a class="dropdown-item text-dark ajax-modal" href="#"
data-modal-url="<?= buildExportModalUrl('modals/recurring_invoice/recurring_invoice_export.php', ['client_id', 'status', 'q'], ['dtf' => $dtf, 'dtt' => $dtt]) ?>">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
<?php } ?>
</div>
</div>
</div>
<?php } ?>
</div>

View File

@@ -94,7 +94,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php if ($num_rows[0] > 0) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-dark ajax-modal" href="#"
data-modal-url="modals/software/software_export.php?<?= $client_url ?>">
data-modal-url="<?= buildExportModalUrl('modals/software/software_export.php', ['client_id', 'client', 'expire_days', 'archived', 'q']) ?>">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
<?php } ?>

View File

@@ -203,7 +203,7 @@ $sql_categories_filter = mysqli_query(
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<a class="dropdown-item text-dark ajax-modal" href="#"
data-modal-url="modals/ticket/ticket_export.php?<?= $client_url ?>">
data-modal-url="<?= buildExportModalUrl('modals/ticket/ticket_export.php', ['client_id', 'status', 'billable', 'unbilled', 'category', 'assigned', 'sla', 'project', 'q'], ['dtf' => $dtf, 'dtt' => $dtt]) ?>">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
</div>

View File

@@ -42,7 +42,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<a class="dropdown-item text-dark ajax-modal" href="#"
data-modal-url="modals/trip/trip_export.php?<?= $client_url ?>">
data-modal-url="<?= buildExportModalUrl('modals/trip/trip_export.php', ['client_id', 'q'], ['dtf' => $dtf, 'dtt' => $dtt]) ?>">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
</div>

View File

@@ -50,7 +50,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php if ($num_rows[0] > 0) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-dark ajax-modal" href="#"
data-modal-url="modals/vendor/vendor_export.php?<?= $client_url ?>">
data-modal-url="<?= buildExportModalUrl('modals/vendor/vendor_export.php', ['client_id', 'archived', 'q']) ?>">
<i class="fa fa-fw fa-download mr-2"></i>Export
</a>
<?php } ?>