mirror of
https://github.com/itflow-org/itflow
synced 2026-08-16 12:35:11 +00:00
Add Category column and filter into income along with the exports
This commit is contained in:
@@ -41,6 +41,17 @@ if (isset($_GET['account']) && !empty($_GET['account'])) {
|
||||
$account_filter = '';
|
||||
}
|
||||
|
||||
// Category Filter - a revenue carries its own category, a payment inherits the one on the
|
||||
// invoice it was paid against. Both come from the same 'Income' category pool.
|
||||
if (isset($_GET['category']) && !empty($_GET['category'])) {
|
||||
$category_query = 'AND (income_category_id = ' . intval($_GET['category']) . ')';
|
||||
$category_filter = intval($_GET['category']);
|
||||
} else {
|
||||
// Default - any
|
||||
$category_query = '';
|
||||
$category_filter = '';
|
||||
}
|
||||
|
||||
// Payment Method Filter
|
||||
if (isset($_GET['method']) && !empty($_GET['method'])) {
|
||||
$method_query = "AND (income_method = '" . escapeSql($_GET['method']) . "')";
|
||||
@@ -62,6 +73,8 @@ $income_query =
|
||||
payment_created_at AS income_created_at,
|
||||
payment_invoice_id AS income_invoice_id,
|
||||
CONCAT(invoice_prefix, invoice_number) AS income_source,
|
||||
category_name AS income_category,
|
||||
IFNULL(invoice_category_id, 0) AS income_category_id,
|
||||
invoice_client_id AS income_client_id,
|
||||
client_name AS income_client,
|
||||
payment_amount AS income_amount,
|
||||
@@ -75,6 +88,7 @@ $income_query =
|
||||
LEFT JOIN invoices ON payment_invoice_id = invoice_id
|
||||
LEFT JOIN clients ON invoice_client_id = client_id
|
||||
LEFT JOIN accounts ON payment_account_id = account_id
|
||||
LEFT JOIN categories ON invoice_category_id = category_id
|
||||
WHERE payment_archived_at IS NULL
|
||||
$payment_client_query
|
||||
$access_permission_query
|
||||
@@ -87,7 +101,9 @@ $income_query =
|
||||
revenue_date,
|
||||
revenue_created_at,
|
||||
0,
|
||||
revenue_description,
|
||||
category_name,
|
||||
revenue_category_id,
|
||||
revenue_client_id,
|
||||
client_name,
|
||||
revenue_amount,
|
||||
@@ -108,8 +124,9 @@ $income_query =
|
||||
|
||||
$income_filter_query =
|
||||
"WHERE DATE(income_date) BETWEEN '$dtf' AND '$dtt'
|
||||
AND (income_source LIKE '%$q%' OR income_client LIKE '%$q%' OR income_account LIKE '%$q%' OR income_method LIKE '%$q%' OR income_reference LIKE '%$q%' OR income_amount LIKE '%$q%')
|
||||
AND (income_source LIKE '%$q%' OR income_category LIKE '%$q%' OR income_client LIKE '%$q%' OR income_account LIKE '%$q%' OR income_method LIKE '%$q%' OR income_reference LIKE '%$q%' OR income_amount LIKE '%$q%')
|
||||
$type_query
|
||||
$category_query
|
||||
$account_query
|
||||
$method_query";
|
||||
|
||||
@@ -155,14 +172,14 @@ $summary_total_income = floatval($row['total_income']);
|
||||
<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/income/income_export.php?<?= $client_url ?>type=<?= urlencode($type_filter) ?>&account=<?= $account_filter ?>&method=<?= urlencode($_GET['method'] ?? '') ?>&dtf=<?= $dtf ?>&dtt=<?= $dtt ?>&q=<?= urlencode($q ?? '') ?>">
|
||||
data-modal-url="modals/income/income_export.php?<?= $client_url ?>type=<?= urlencode($type_filter) ?>&category=<?= $category_filter ?>&account=<?= $account_filter ?>&method=<?= urlencode($_GET['method'] ?? '') ?>&dtf=<?= $dtf ?>&dtt=<?= $dtt ?>&q=<?= urlencode($q ?? '') ?>">
|
||||
<i class="fa fa-fw fa-download mr-2"></i>Export
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php } else { ?>
|
||||
<button type="button" class="btn btn-default ajax-modal"
|
||||
data-modal-url="modals/income/income_export.php?<?= $client_url ?>type=<?= urlencode($type_filter) ?>&account=<?= $account_filter ?>&method=<?= urlencode($_GET['method'] ?? '') ?>&dtf=<?= $dtf ?>&dtt=<?= $dtt ?>&q=<?= urlencode($q ?? '') ?>">
|
||||
data-modal-url="modals/income/income_export.php?<?= $client_url ?>type=<?= urlencode($type_filter) ?>&category=<?= $category_filter ?>&account=<?= $account_filter ?>&method=<?= urlencode($_GET['method'] ?? '') ?>&dtf=<?= $dtf ?>&dtt=<?= $dtt ?>&q=<?= urlencode($q ?? '') ?>">
|
||||
<i class="fa fa-fw fa-download mr-2"></i>Export
|
||||
</button>
|
||||
<?php } ?>
|
||||
@@ -194,6 +211,29 @@ $summary_total_income = floatval($row['total_income']);
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="input-group mb-3 mb-sm-0">
|
||||
<select class="form-control select2" name="category" onchange="this.form.submit()">
|
||||
<option value="">- All Categories -</option>
|
||||
|
||||
<?php
|
||||
$sql_categories_filter = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories
|
||||
WHERE category_type = 'Income'
|
||||
AND (EXISTS (SELECT 1 FROM revenues WHERE revenue_category_id = category_id)
|
||||
OR EXISTS (SELECT 1 FROM payments JOIN invoices ON payment_invoice_id = invoice_id WHERE invoice_category_id = category_id))
|
||||
ORDER BY category_name ASC");
|
||||
while ($row = mysqli_fetch_assoc($sql_categories_filter)) {
|
||||
$filter_category_id = intval($row['category_id']);
|
||||
$filter_category_name = escapeHtml($row['category_name']);
|
||||
?>
|
||||
<option <?php if ($category_filter == $filter_category_id) { echo "selected"; } ?> value="<?= $filter_category_id ?>"><?= $filter_category_name ?></option>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="input-group mb-3 mb-sm-0">
|
||||
<select class="form-control select2" name="account" onchange="this.form.submit()">
|
||||
@@ -217,7 +257,7 @@ $summary_total_income = floatval($row['total_income']);
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-2">
|
||||
<div class="col-md-2">
|
||||
<div class="input-group">
|
||||
<select class="form-control select2" name="method" onchange="this.form.submit()">
|
||||
<option value="">- All Payment Methods -</option>
|
||||
@@ -244,7 +284,7 @@ $summary_total_income = floatval($row['total_income']);
|
||||
<div class="form-group">
|
||||
<label>Date range</label>
|
||||
<input type="text" id="dateFilter" class="form-control" autocomplete="off">
|
||||
<input type="hidden" name="canned_date" id="canned_date" value="<?= escapeHtml($_GET['canned_date']) ?? '' ?>">
|
||||
<input type="hidden" name="canned_date" id="canned_date" value="<?= escapeHtml($_GET['canned_date'] ?? '') ?>">
|
||||
<input type="hidden" name="dtf" id="dtf" value="<?= escapeHtml($dtf ?? '') ?>">
|
||||
<input type="hidden" name="dtt" id="dtt" value="<?= escapeHtml($dtt ?? '') ?>">
|
||||
</div>
|
||||
@@ -317,6 +357,11 @@ $summary_total_income = floatval($row['total_income']);
|
||||
Source <?php if ($sort == 'income_source') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=income_category&order=<?= $disp ?>">
|
||||
Category <?php if ($sort == 'income_category') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<?php if (!$client_url) { ?>
|
||||
<th>
|
||||
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=income_client&order=<?= $disp ?>">
|
||||
@@ -356,6 +401,7 @@ $summary_total_income = floatval($row['total_income']);
|
||||
$income_date = escapeHtml($row['income_date']);
|
||||
$income_invoice_id = intval($row['income_invoice_id']);
|
||||
$income_source = escapeHtml($row['income_source']);
|
||||
$income_category = escapeHtml($row['income_category']);
|
||||
$income_client_id = intval($row['income_client_id']);
|
||||
$income_client = escapeHtml($row['income_client']);
|
||||
$income_amount = floatval($row['income_amount']);
|
||||
@@ -403,9 +449,10 @@ $summary_total_income = floatval($row['total_income']);
|
||||
<?= $income_source ?>
|
||||
</a>
|
||||
<?php } else { ?>
|
||||
<?= $income_source ?>
|
||||
<?= $income_source === '' ? '-' : $income_source ?>
|
||||
<?php } ?>
|
||||
</td>
|
||||
<td><?= $income_category === '' ? '-' : $income_category ?></td>
|
||||
<?php if (!$client_url) { ?>
|
||||
<td>
|
||||
<?php if ($income_client_id) { ?>
|
||||
|
||||
@@ -15,6 +15,13 @@ if (isset($_GET['type']) && !empty($_GET['type']) && in_array($_GET['type'], $in
|
||||
$type_filter = '';
|
||||
}
|
||||
|
||||
// Category Filter
|
||||
if (isset($_GET['category']) && !empty($_GET['category'])) {
|
||||
$category_filter = intval($_GET['category']);
|
||||
} else {
|
||||
$category_filter = '';
|
||||
}
|
||||
|
||||
// Account Filter
|
||||
if (isset($_GET['account']) && !empty($_GET['account'])) {
|
||||
$account_filter = intval($_GET['account']);
|
||||
@@ -74,7 +81,7 @@ ob_start();
|
||||
<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="Source, client, account, method, reference or amount">
|
||||
<input type="text" class="form-control" name="q" value="<?= stripslashes(escapeHtml($q_filter)) ?>" placeholder="Source, category, client, account, method, reference or amount">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -95,6 +102,34 @@ ob_start();
|
||||
</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-tag"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="category">
|
||||
<option value="">- All Categories -</option>
|
||||
|
||||
<?php
|
||||
$sql_categories_filter = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories
|
||||
WHERE category_type = 'Income'
|
||||
AND (EXISTS (SELECT 1 FROM revenues WHERE revenue_category_id = category_id)
|
||||
OR EXISTS (SELECT 1 FROM payments JOIN invoices ON payment_invoice_id = invoice_id WHERE invoice_category_id = category_id))
|
||||
ORDER BY category_name ASC");
|
||||
while ($row = mysqli_fetch_assoc($sql_categories_filter)) {
|
||||
$filter_category_id = intval($row['category_id']);
|
||||
$filter_category_name = escapeHtml($row['category_name']);
|
||||
?>
|
||||
<option <?php if ($category_filter == $filter_category_id) { echo "selected"; } ?> value="<?= $filter_category_id ?>"><?= $filter_category_name ?></option>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Account</label>
|
||||
<div class="input-group">
|
||||
|
||||
@@ -53,6 +53,16 @@ if (isset($_POST['export_income'])) {
|
||||
$account_query = '';
|
||||
}
|
||||
|
||||
// Category Filter - a revenue carries its own category, a payment inherits the one on the
|
||||
// invoice it was paid against. Both come from the same 'Income' category pool.
|
||||
$category = intval($_POST['category'] ?? 0);
|
||||
if ($category) {
|
||||
$category_query = "AND (income_category_id = $category)";
|
||||
} else {
|
||||
// Default - any
|
||||
$category_query = '';
|
||||
}
|
||||
|
||||
// Payment Method Filter
|
||||
if (!empty($_POST['method'])) {
|
||||
$method_query = "AND (income_method = '" . escapeSql($_POST['method']) . "')";
|
||||
@@ -64,7 +74,7 @@ if (isset($_POST['export_income'])) {
|
||||
// Search Filter - mirrors the income page search box
|
||||
$q = escapeSql($_POST['q']);
|
||||
if (!empty($q)) {
|
||||
$search_query = "AND (income_source LIKE '%$q%' OR income_client LIKE '%$q%' OR income_account LIKE '%$q%' OR income_method LIKE '%$q%' OR income_reference LIKE '%$q%' OR income_amount LIKE '%$q%')";
|
||||
$search_query = "AND (income_source LIKE '%$q%' OR income_category LIKE '%$q%' OR income_client LIKE '%$q%' OR income_account LIKE '%$q%' OR income_method LIKE '%$q%' OR income_reference LIKE '%$q%' OR income_amount LIKE '%$q%')";
|
||||
} else {
|
||||
// Default - any
|
||||
$search_query = '';
|
||||
@@ -77,6 +87,32 @@ if (isset($_POST['export_income'])) {
|
||||
$date_query = '';
|
||||
}
|
||||
|
||||
// Filter summary for the export header. This handler was the only one not building it,
|
||||
// so a filtered PDF came out looking like a full export.
|
||||
$filter_summary = [];
|
||||
|
||||
if ($client_id) {
|
||||
$filter_summary['Client'] = $client_name;
|
||||
}
|
||||
if (!empty($_POST['type']) && in_array($_POST['type'], $income_types_array)) {
|
||||
$filter_summary['Type'] = $_POST['type'];
|
||||
}
|
||||
if ($category) {
|
||||
$filter_summary['Category'] = getFieldById('categories', $category, 'category_name');
|
||||
}
|
||||
if ($account) {
|
||||
$filter_summary['Account'] = getFieldById('accounts', $account, 'account_name');
|
||||
}
|
||||
if (!empty($_POST['method'])) {
|
||||
$filter_summary['Payment Method'] = $_POST['method'];
|
||||
}
|
||||
if (!empty($date_from) && !empty($date_to)) {
|
||||
$filter_summary['Date'] = "$date_from to $date_to";
|
||||
}
|
||||
if (!empty($_POST['q'])) {
|
||||
$filter_summary['Search'] = $_POST['q'];
|
||||
}
|
||||
|
||||
// Same union as income.php - payments applied to an invoice, and standalone revenues.
|
||||
// Transfers between accounts are stored as a linked expense + revenue pair, so the revenue leg
|
||||
// is excluded here (transfer_id IS NULL) - moving your own money is not income.
|
||||
@@ -89,7 +125,8 @@ if (isset($_POST['export_income'])) {
|
||||
payment_date AS income_date,
|
||||
payment_created_at AS income_created_at,
|
||||
CONCAT(invoice_prefix, invoice_number) AS income_source,
|
||||
NULL AS income_description,
|
||||
category_name AS income_category,
|
||||
IFNULL(invoice_category_id, 0) AS income_category_id,
|
||||
client_name AS income_client,
|
||||
payment_amount AS income_amount,
|
||||
payment_currency_code AS income_currency_code,
|
||||
@@ -101,6 +138,7 @@ if (isset($_POST['export_income'])) {
|
||||
LEFT JOIN invoices ON payment_invoice_id = invoice_id
|
||||
LEFT JOIN clients ON invoice_client_id = client_id
|
||||
LEFT JOIN accounts ON payment_account_id = account_id
|
||||
LEFT JOIN categories ON invoice_category_id = category_id
|
||||
WHERE payment_archived_at IS NULL
|
||||
$payment_client_query
|
||||
$access_permission_query
|
||||
@@ -112,8 +150,9 @@ if (isset($_POST['export_income'])) {
|
||||
revenue_id,
|
||||
revenue_date,
|
||||
revenue_created_at,
|
||||
category_name,
|
||||
revenue_description,
|
||||
category_name,
|
||||
revenue_category_id,
|
||||
client_name,
|
||||
revenue_amount,
|
||||
revenue_currency_code,
|
||||
@@ -133,6 +172,7 @@ if (isset($_POST['export_income'])) {
|
||||
WHERE 1 = 1
|
||||
$date_query
|
||||
$type_query
|
||||
$category_query
|
||||
$account_query
|
||||
$method_query
|
||||
$search_query
|
||||
@@ -144,7 +184,7 @@ if (isset($_POST['export_income'])) {
|
||||
|
||||
guardExportPdfRowCount($format, $num_rows);
|
||||
|
||||
$export = beginExport('income', $format, $file_name_prepend . 'Income', 'Income', summarizeExportFilters($filter_summary ?? []));
|
||||
$export = beginExport('income', $format, $file_name_prepend . 'Income', 'Income', summarizeExportFilters($filter_summary));
|
||||
|
||||
while ($row = mysqli_fetch_assoc($sql)) {
|
||||
addExportRow($export, $row);
|
||||
|
||||
Reference in New Issue
Block a user