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:
Thanakorn
2026-09-19 10:58:42 +07:00
parent de760d02da
commit c89b28da4c
32 changed files with 924 additions and 483 deletions
+11 -11
View File
@@ -1035,7 +1035,7 @@ class WarehouseManager {
$sth = $this->pdo->prepare(
"SELECT DISTINCT zone FROM md_bin
WHERE company_id = :company_id AND warehouse = :warehouse
ORDER BY CAST(zone AS UNSIGNED), zone"
ORDER BY REGEXP_REPLACE(zone, '[0-9]+$', ''), CAST(REGEXP_SUBSTR(zone, '[0-9]+$') AS UNSIGNED), zone"
);
$sth->execute([':company_id' => $this->company_id, ':warehouse' => $warehouse_id]);
return $sth->fetchAll(PDO::FETCH_ASSOC);
@@ -1055,7 +1055,7 @@ class WarehouseManager {
$sth = $this->pdo->prepare(
"SELECT DISTINCT aisle FROM md_bin
WHERE company_id = :company_id AND warehouse = :warehouse AND zone = :zone
ORDER BY CAST(aisle AS UNSIGNED), aisle"
ORDER BY REGEXP_REPLACE(aisle, '[0-9]+$', ''), CAST(REGEXP_SUBSTR(aisle, '[0-9]+$') AS UNSIGNED), aisle"
);
$sth->execute([':company_id' => $this->company_id, ':warehouse' => $warehouse_id, ':zone' => $zone]);
return array_column($sth->fetchAll(PDO::FETCH_ASSOC), 'aisle');
@@ -1077,7 +1077,7 @@ class WarehouseManager {
$sth = $this->pdo->prepare(
"SELECT DISTINCT bin FROM md_bin
WHERE company_id = :company_id AND warehouse = :warehouse
ORDER BY CAST(bin AS UNSIGNED), bin"
ORDER BY REGEXP_REPLACE(bin, '[0-9]+$', ''), CAST(REGEXP_SUBSTR(bin, '[0-9]+$') AS UNSIGNED), bin"
);
$sth->execute([':company_id' => $this->company_id, ':warehouse' => $warehouse_id]);
return array_column($sth->fetchAll(PDO::FETCH_ASSOC), 'bin');
@@ -1086,7 +1086,7 @@ class WarehouseManager {
$sth = $this->pdo->prepare(
"SELECT DISTINCT bin FROM md_bin
WHERE company_id = :company_id AND warehouse = :warehouse AND zone = :zone AND aisle = :aisle
ORDER BY CAST(bin AS UNSIGNED), bin"
ORDER BY REGEXP_REPLACE(bin, '[0-9]+$', ''), CAST(REGEXP_SUBSTR(bin, '[0-9]+$') AS UNSIGNED), bin"
);
$sth->execute([':company_id' => $this->company_id, ':warehouse' => $warehouse_id, ':zone' => $zone, ':aisle' => $aisle]);
return array_column($sth->fetchAll(PDO::FETCH_ASSOC), 'bin');
@@ -1915,7 +1915,7 @@ class WarehouseManager {
WHERE company_id = :company_id
AND warehouse = :warehouse
AND product_sku IS NULL
ORDER BY CAST(zone AS UNSIGNED), zone"
ORDER BY REGEXP_REPLACE(zone, '[0-9]+$', ''), CAST(REGEXP_SUBSTR(zone, '[0-9]+$') AS UNSIGNED), zone"
);
$sth->execute([':company_id' => $this->company_id, ':warehouse' => $warehouse_id]);
return $sth->fetchAll(PDO::FETCH_ASSOC);
@@ -1961,7 +1961,7 @@ class WarehouseManager {
{$lot_cond}
{$serial_cond}
)
ORDER BY CAST(r.zone AS UNSIGNED), r.zone"
ORDER BY REGEXP_REPLACE(r.zone, '[0-9]+$', ''), CAST(REGEXP_SUBSTR(r.zone, '[0-9]+$') AS UNSIGNED), r.zone"
);
$sth->execute($params);
return $sth->fetchAll(PDO::FETCH_ASSOC);
@@ -1982,7 +1982,7 @@ class WarehouseManager {
AND warehouse = :warehouse
AND zone = :zone
AND product_sku IS NULL
ORDER BY CAST(aisle AS UNSIGNED), aisle"
ORDER BY REGEXP_REPLACE(aisle, '[0-9]+$', ''), CAST(REGEXP_SUBSTR(aisle, '[0-9]+$') AS UNSIGNED), aisle"
);
$sth->execute([
':company_id' => $this->company_id,
@@ -2033,7 +2033,7 @@ class WarehouseManager {
{$lot_cond}
{$serial_cond}
)
ORDER BY CAST(r.aisle AS UNSIGNED), r.aisle"
ORDER BY REGEXP_REPLACE(r.aisle, '[0-9]+$', ''), CAST(REGEXP_SUBSTR(r.aisle, '[0-9]+$') AS UNSIGNED), r.aisle"
);
$sth->execute($params);
return array_column($sth->fetchAll(PDO::FETCH_ASSOC), 'aisle');
@@ -2055,7 +2055,7 @@ class WarehouseManager {
WHERE company_id = :company_id
AND warehouse = :warehouse
AND product_sku IS NULL
ORDER BY CAST(bin AS UNSIGNED), bin"
ORDER BY REGEXP_REPLACE(bin, '[0-9]+$', ''), CAST(REGEXP_SUBSTR(bin, '[0-9]+$') AS UNSIGNED), bin"
);
$sth->execute([
':company_id' => $this->company_id,
@@ -2071,7 +2071,7 @@ class WarehouseManager {
AND zone = :zone
AND aisle = :aisle
AND product_sku IS NULL
ORDER BY CAST(bin AS UNSIGNED), bin"
ORDER BY REGEXP_REPLACE(bin, '[0-9]+$', ''), CAST(REGEXP_SUBSTR(bin, '[0-9]+$') AS UNSIGNED), bin"
);
$sth->execute([
':company_id' => $this->company_id,
@@ -2130,7 +2130,7 @@ class WarehouseManager {
{$lot_cond}
{$serial_cond}
)
ORDER BY CAST(r.bin AS UNSIGNED), r.bin"
ORDER BY REGEXP_REPLACE(r.bin, '[0-9]+$', ''), CAST(REGEXP_SUBSTR(r.bin, '[0-9]+$') AS UNSIGNED), r.bin"
);
$sth->execute($params);
return array_column($sth->fetchAll(PDO::FETCH_ASSOC), 'bin');