Add date-range search on GL posting date

This commit is contained in:
mosaic 2026-07-08 16:03:07 +00:00
parent 67e20fba9f
commit 5568cab816
4 changed files with 27 additions and 2 deletions

View File

@ -315,6 +315,8 @@ function currentSearchFilters() {
text: document.getElementById('s-text').value,
year: document.getElementById('s-year').value,
month: document.getElementById('s-month').value,
dateFrom: document.getElementById('s-date-from').value,
dateTo: document.getElementById('s-date-to').value,
level: document.getElementById('s-level').value,
includeVoided: document.getElementById('s-voided').checked,
};
@ -407,7 +409,7 @@ function renderPagination(elId, state, loadFn) {
document.getElementById('s-search-btn').addEventListener('click', () => loadSearch(0));
document.getElementById('s-clear-btn').addEventListener('click', () => {
['s-customer', 's-text'].forEach((id) => (document.getElementById(id).value = ''));
['s-customer', 's-text', 's-date-from', 's-date-to'].forEach((id) => (document.getElementById(id).value = ''));
['s-product', 's-package', 's-customertype', 's-brand', 's-year', 's-month'].forEach((id) => (document.getElementById(id).value = ''));
document.getElementById('s-level').value = 'customer';
document.getElementById('s-voided').checked = false;

View File

@ -122,6 +122,11 @@
<select id="s-year"><option value="">Any year</option></select>
<select id="s-month"><option value="">Any month</option></select>
</div>
<div class="filter-row date-range-row">
<label class="date-field"><span>GL date from</span><input type="date" id="s-date-from" /></label>
<label class="date-field"><span>to</span><input type="date" id="s-date-to" /></label>
<span class="hint">Filters on the actual GL posting date; leave either side blank for an open-ended range.</span>
</div>
<div class="filter-row">
<label class="level-toggle">
<span>Results level:</span>

View File

@ -134,6 +134,15 @@ body { margin: 0; background: var(--bg); color: var(--text); }
font-size: 0.88rem;
}
.filter-row input[type=text] { flex: 1; min-width: 180px; }
.date-range-row { align-items: center; }
.date-field { display: flex; align-items: center; gap: 8px; font-size: 0.85rem; color: var(--muted); }
.date-field input[type=date] {
padding: 7px 10px;
border: 1px solid var(--border);
border-radius: 6px;
font-size: 0.88rem;
font-family: inherit;
}
button {
padding: 8px 16px;
border: none;

View File

@ -267,7 +267,7 @@ app.get('/api/new-packages', async (req, res) => {
function buildTransactionFilters(query) {
const {
product, package: pkg, customer, text, customerType, brand,
year, month, yearFrom, monthFrom, yearTo, monthTo, includeVoided,
year, month, yearFrom, monthFrom, yearTo, monthTo, dateFrom, dateTo, includeVoided,
} = query;
const where = [];
const params = [];
@ -317,6 +317,15 @@ function buildTransactionFilters(query) {
params.push(parseInt(yearTo, 10) * 12 + parseInt(monthTo, 10));
where.push(`(year * 12 + month) <= $${params.length}`);
}
const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
if (dateFrom && DATE_RE.test(dateFrom)) {
params.push(dateFrom);
where.push(`gl_date >= $${params.length}`);
}
if (dateTo && DATE_RE.test(dateTo)) {
params.push(dateTo);
where.push(`gl_date <= $${params.length}`);
}
return { whereSql: where.length ? `WHERE ${where.join(' AND ')}` : '', params };
}