From 965f3e3bbe02e941dc366201a9db025588e30e64 Mon Sep 17 00:00:00 2001 From: SJCoetz Date: Thu, 6 Aug 2026 11:56:51 +0200 Subject: [PATCH] docs(pdf): restore poSubtotal JSDoc + clarify fallback uses || not ?? Co-authored-by: Orca --- src/lib/pdf/format.ts | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/lib/pdf/format.ts b/src/lib/pdf/format.ts index 1f49cf0..150783a 100644 --- a/src/lib/pdf/format.ts +++ b/src/lib/pdf/format.ts @@ -41,9 +41,18 @@ export function quoteSubtotal(items: { quantity: number; selling_price: number } /** * Sum of (order_qty ?? quantity) * cost_price across PO items. Differs - * from `quoteSubtotal()` in using supplier-facing cost and order quantity. - * A blank or zero order_qty falls back to quantity so it never zeroes a line. - * Rounds to 2dp so the printed table doesn't show floating-point dust. + * from `quoteSubtotal()` in two ways: + * 1. Multiplies by `cost_price` (the supplier-facing price), not + * `selling_price` (the customer-facing price). + * 2. Prefers `order_qty` when set, falls back to `quantity` so a + * blank `order_qty` (the common case when the operator hasn't + * adjusted the supplier-facing qty yet) never zeroes the line. + * A literal `order_qty: 0` is also treated as missing — that's + * almost always an operator mistake. + * + * Rounds to 2dp so the printed table doesn't show floating-point dust + * (1.0000000003 R etc). The supplier-facing PO uses this for both + * `Subtotal` and the base of the `VAT (15%)` line. */ export function poSubtotal( items: { order_qty?: number | null; quantity: number; cost_price: number }[] @@ -51,6 +60,9 @@ export function poSubtotal( return Math.round( items.reduce( (sum, it) => + // `||` (not `??`) is intentional: we want `order_qty: 0` to fall through + // to `quantity`, since a literal 0 on a PO line is almost always an + // operator mistake (blank input) rather than a real "zero qty". sum + (Number(it.order_qty) || Number(it.quantity) || 0) * (Number(it.cost_price) || 0),