Fix QA review findings: server-side validation, notes encoding, dashboard totals
Validate document lines on the server and recompute their totals, store notes with quotes/markup/emoji (utf8mb4, idempotent escaping, decode in form fields), exclude transfers from company-wide stock in/out, count revenue from confirmed orders only, one low-stock rule everywhere, list unapproved lots, natural bin sort, stable order/PO sort, status tiles that add up.
This commit is contained in:
+33
-5
@@ -23,7 +23,7 @@
|
||||
</div>
|
||||
|
||||
<div class="row g-5 mb-5">
|
||||
<div class="col-lg-3 col-sm-6 col-12">
|
||||
<div class="col-xl-2 col-lg-4 col-sm-6 col-12">
|
||||
<div class="card p-4">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<div class="icon-shape icon-md bg-primary bg-opacity-10 text-primary rounded-2">
|
||||
@@ -36,7 +36,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-sm-6 col-12">
|
||||
<div class="col-xl-2 col-lg-4 col-sm-6 col-12">
|
||||
<div class="card p-4">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<div class="icon-shape icon-md bg-warning bg-opacity-10 text-warning rounded-2">
|
||||
@@ -49,7 +49,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-sm-6 col-12">
|
||||
<div class="col-xl-2 col-lg-4 col-sm-6 col-12">
|
||||
<div class="card p-4">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<div class="icon-shape icon-md bg-info bg-opacity-10 text-info rounded-2">
|
||||
@@ -62,7 +62,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-sm-6 col-12">
|
||||
<div class="col-xl-2 col-lg-4 col-sm-6 col-12">
|
||||
<div class="card p-4">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<div class="icon-shape icon-md bg-danger bg-opacity-10 text-danger rounded-2">
|
||||
@@ -75,7 +75,33 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-2 col-lg-4 col-sm-6 col-12">
|
||||
<div class="card p-4">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<div class="icon-shape icon-md bg-success bg-opacity-10 text-success rounded-2">
|
||||
<i class="ti ti-circle-check fs-4"></i>
|
||||
</div>
|
||||
<div>
|
||||
<p class="mb-0 text-muted small">Paid</p>
|
||||
<h3 class="fw-bold mb-0" id="stat_paid">—</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-2 col-lg-4 col-sm-6 col-12">
|
||||
<div class="card p-4">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<div class="icon-shape icon-md bg-secondary bg-opacity-10 text-secondary rounded-2">
|
||||
<i class="ti ti-ban fs-4"></i>
|
||||
</div>
|
||||
<div>
|
||||
<p class="mb-0 text-muted small">Void</p>
|
||||
<h3 class="fw-bold mb-0" id="stat_void">—</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-5">
|
||||
<div class="col-12">
|
||||
@@ -224,6 +250,8 @@
|
||||
$('#stat_total').text(format_number(all.length));
|
||||
$('#stat_draft').text(format_number(all.filter(i => String(i.status) === '0').length));
|
||||
$('#stat_issued').text(format_number(all.filter(i => String(i.status) === '1').length));
|
||||
$('#stat_paid').text(format_number(all.filter(i => String(i.status) === '2').length));
|
||||
$('#stat_void').text(format_number(all.filter(i => String(i.status) === '4').length));
|
||||
$('#stat_overdue').text(format_number(all.filter(i => is_overdue(i)).length));
|
||||
|
||||
alasql('CREATE TABLE IF NOT EXISTS invoice_list');
|
||||
|
||||
+18
-4
@@ -30,7 +30,7 @@
|
||||
|
||||
<!-- Stat cards -->
|
||||
<div class="row g-5 mb-5">
|
||||
<div class="col-lg-3 col-sm-6 col-12">
|
||||
<div class="col-lg col-sm-6 col-12">
|
||||
<div class="card p-4">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<div class="icon-shape icon-md bg-primary bg-opacity-10 text-primary rounded-2">
|
||||
@@ -43,7 +43,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-sm-6 col-12">
|
||||
<div class="col-lg col-sm-6 col-12">
|
||||
<div class="card p-4">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<div class="icon-shape icon-md bg-warning bg-opacity-10 text-warning rounded-2">
|
||||
@@ -56,7 +56,20 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-sm-6 col-12">
|
||||
<div class="col-lg col-sm-6 col-12">
|
||||
<div class="card p-4">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<div class="icon-shape icon-md bg-danger bg-opacity-10 text-danger rounded-2">
|
||||
<i class="ti ti-building-warehouse fs-4"></i>
|
||||
</div>
|
||||
<div>
|
||||
<p class="mb-0 text-muted small">Pending Warehouse</p>
|
||||
<h3 class="fw-bold mb-0" id="stat_pending">—</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg col-sm-6 col-12">
|
||||
<div class="card p-4">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<div class="icon-shape icon-md bg-info bg-opacity-10 text-info rounded-2">
|
||||
@@ -69,7 +82,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-sm-6 col-12">
|
||||
<div class="col-lg col-sm-6 col-12">
|
||||
<div class="card p-4">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<div class="icon-shape icon-md bg-secondary bg-opacity-10 text-secondary rounded-2">
|
||||
@@ -215,6 +228,7 @@
|
||||
|
||||
// Stat cards
|
||||
$('#stat_total').text(format_number(all.length));
|
||||
$('#stat_pending').text(format_number(all.filter(o => parseInt(o.status) === -2).length));
|
||||
$('#stat_draft').text(format_number(all.filter(o => parseInt(o.status) === 0).length));
|
||||
$('#stat_confirmed').text(format_number(all.filter(o => parseInt(o.status) === 1).length));
|
||||
$('#stat_completed').text(format_number(all.filter(o => parseInt(o.status) === -1).length));
|
||||
|
||||
Reference in New Issue
Block a user