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:
@@ -1229,6 +1229,48 @@ CREATE TABLE IF NOT EXISTS `document_number_sequences` (
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
|
||||
", 'document_number_sequences');
|
||||
|
||||
// ── utf8mb4 ───────────────────────────────────────────────────────────────────
|
||||
// Older tables were created as utf8mb3, which cannot hold 4-byte characters
|
||||
// (emoji, some CJK). With the connection on utf8mb4 a note containing one was
|
||||
// rejected by the server and the whole save rolled back. Convert whatever is
|
||||
// still utf8mb3, including the per-warehouse td_stock_<id> tables, to the
|
||||
// collation the existing utf8mb4 tables already use so joins keep working.
|
||||
foreach ([$db1, $db2] as $db_name) {
|
||||
try {
|
||||
$st = $pdo->prepare("SELECT TABLE_COLLATION FROM information_schema.TABLES
|
||||
WHERE TABLE_SCHEMA = ? AND TABLE_TYPE = 'BASE TABLE' AND TABLE_COLLATION LIKE 'utf8mb4\\_%'
|
||||
GROUP BY TABLE_COLLATION ORDER BY COUNT(*) DESC LIMIT 1");
|
||||
$st->execute([$db2]);
|
||||
$target = $st->fetchColumn();
|
||||
if (!$target) {
|
||||
$target = $pdo->query("SELECT COLLATION_NAME FROM information_schema.COLLATIONS
|
||||
WHERE CHARACTER_SET_NAME = 'utf8mb4' AND IS_DEFAULT = 'Yes' LIMIT 1")->fetchColumn() ?: 'utf8mb4_general_ci';
|
||||
}
|
||||
if (!preg_match('/^utf8mb4_[a-z0-9_]+$/', $target)) $target = 'utf8mb4_general_ci';
|
||||
|
||||
$st = $pdo->prepare("SELECT TABLE_NAME FROM information_schema.TABLES
|
||||
WHERE TABLE_SCHEMA = ? AND TABLE_TYPE = 'BASE TABLE'
|
||||
AND (TABLE_COLLATION LIKE 'utf8mb3\\_%' OR TABLE_COLLATION LIKE 'utf8\\_%')
|
||||
ORDER BY TABLE_NAME");
|
||||
$st->execute([$db_name]);
|
||||
$legacy = $st->fetchAll(PDO::FETCH_COLUMN);
|
||||
if (!$legacy) { skip("utf8mb4: `{$db_name}` (already converted)"); }
|
||||
foreach ($legacy as $tbl) {
|
||||
run($pdo, "ALTER TABLE `{$db_name}`.`{$tbl}` CONVERT TO CHARACTER SET utf8mb4 COLLATE {$target}", "utf8mb4: {$db_name}.{$tbl}");
|
||||
}
|
||||
run($pdo, "ALTER DATABASE `{$db_name}` CHARACTER SET utf8mb4 COLLATE {$target}", "utf8mb4: database `{$db_name}` default");
|
||||
} catch (PDOException $e) {
|
||||
fail("utf8mb4 conversion of `{$db_name}`: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
$pdo->exec("USE `{$db2}`");
|
||||
|
||||
// td_purchase_order totals were decimal(15,2) while its lines are decimal(18,4);
|
||||
// match the other document headers.
|
||||
foreach (['subtotal', 'discount', 'tax', 'shipping_fee', 'grand_total'] as $col) {
|
||||
run($pdo, "ALTER TABLE `{$db2}`.`td_purchase_order` MODIFY `{$col}` decimal(18,4) NOT NULL DEFAULT 0.0000", "td_purchase_order.{$col} decimal(18,4)");
|
||||
}
|
||||
|
||||
// ── Summary ───────────────────────────────────────────────────────────────────
|
||||
$total = $ok_count + $skip_count + $err_count;
|
||||
echo "\n\033[1m=== Done ===\033[0m\n";
|
||||
|
||||
Reference in New Issue
Block a user