diff --git a/src/lib/server/order-assistant-core.test.ts b/src/lib/server/order-assistant-core.test.ts index 762f5f8..323a891 100644 --- a/src/lib/server/order-assistant-core.test.ts +++ b/src/lib/server/order-assistant-core.test.ts @@ -550,6 +550,19 @@ describe("buildOrderLineFillPatch", () => { expect(patch?.markup_percent).toBe(50); }); + it("clamps a loss-making markup at 0, like every other order-line write", () => { + // The customer's price is below the quote's cost. The margin chip + // shows the real margin from cost + selling; the stored markup + // follows the app's convention of never going negative. + const patch = buildOrderLineFillPatch( + fillLine({ selling_price: 8 }), + fillQuoteLine({ cost_price: 10, selling_price: 12 }), + FILL_CTX, + ); + expect(patch?.markup).toBe(0); + expect(patch?.markup_percent).toBe(0); + }); + it("adds the price doubt when the customer price differs by more than 5%", () => { const patch = buildOrderLineFillPatch( fillLine({ selling_price: 16.64 }), diff --git a/src/lib/server/order-assistant-core.ts b/src/lib/server/order-assistant-core.ts index 243855f..eefbcf5 100644 --- a/src/lib/server/order-assistant-core.ts +++ b/src/lib/server/order-assistant-core.ts @@ -260,7 +260,11 @@ export function buildOrderLineFillPatch( // The resulting selling price: the customer's own price when there is // one, otherwise the quoted price. const selling = customerPrice > 0 ? customerPrice : quotedPrice; - const markup = cost > 0 && selling > 0 ? round2(((selling - cost) / cost) * 100) : 0; + // Clamped at 0, like every other write to an order line's markup + // (`orders-service.ts` stores `Math.max(0, computedMarkup)`). A line + // that sells below cost still shows its true margin on screen, because + // the margin chip works from cost and selling, not from this field. + const markup = cost > 0 && selling > 0 ? Math.max(0, round2(((selling - cost) / cost) * 100)) : 0; const supplier = (line.supplier ?? "").trim() || (quoteLine.supplier ?? ""); const sku = (line.sku ?? "").trim() || (quoteLine.sku ?? "");