You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Sales: snapshot the list price on the order line (discount foundation) #720
Add ListUnitPriceMinorUnits to SalesOrderItem, captured from the product's DefaultPriceMinorUnits at line creation. Discount is then derived as ListUnitPrice − UnitPrice and is stable forever.
The line already snapshots ProductTypeSnapshot, EggGradeId, BaseUnitFactor
and UnitPrice (spec §10.5) but not the list price it was sold against, so
today there is no stored fact saying a sale was discounted.
Without the snapshot, "was this discounted?" would be computed live against
today's catalog price: raise a product's price next month and every past sale
retroactively becomes a discount; drop it and real discounts vanish. The order
screen, the history badge and the report would each drift, and they would drift differently. This is the same rule already written into §10.5 for BaseUnitFactor — redefining a carton must not reinterpret recorded orders.
Scope
ListUnitPriceMinorUnits (nullable long) on SalesOrderItem, set in SalesOrderItem.Create from the product read that AddOrderItemHandler
already performs. Nullable on purpose — a product with no default price
has no list price, and that is a different fact from "sold at list".
Never re-resolved on SalesOrderItem.Update: editing quantity or price does
not change what the list price was when the line was written.
Exposed on the order item API response so the read surfaces can use it.
Null list price. Does an egg product now require a DefaultPriceMinorUnits, or do we keep it optional and render those lines as no list price? Either is fine; silently showing them as 0% off is not — that
is the version that lets a discount hide.
Pre-migration orders have no snapshot and must read as unknown, not as
zero discount, in every consumer. Worth asserting in a test now so a later
slice cannot regress it into a ?? 0.
Acceptance
A line added against a priced product stores that product's price at that
moment.
Changing the product's default price afterwards does not change any stored
line's ListUnitPriceMinorUnits. This is the test that matters.
A line added against a product with no default price stores NULL.
Part of #719.
What
Add
ListUnitPriceMinorUnitstoSalesOrderItem, captured from the product'sDefaultPriceMinorUnitsat line creation. Discount is then derived asListUnitPrice − UnitPriceand is stable forever.Why this blocks everything else in #719
The line already snapshots
ProductTypeSnapshot,EggGradeId,BaseUnitFactorand
UnitPrice(spec §10.5) but not the list price it was sold against, sotoday there is no stored fact saying a sale was discounted.
Without the snapshot, "was this discounted?" would be computed live against
today's catalog price: raise a product's price next month and every past sale
retroactively becomes a discount; drop it and real discounts vanish. The order
screen, the history badge and the report would each drift, and they would drift
differently. This is the same rule already written into §10.5 for
BaseUnitFactor— redefining a carton must not reinterpret recorded orders.Scope
ListUnitPriceMinorUnits(nullablelong) onSalesOrderItem, set inSalesOrderItem.Createfrom the product read thatAddOrderItemHandleralready performs. Nullable on purpose — a product with no default price
has no list price, and that is a different fact from "sold at list".
SalesOrderItem.Update: editing quantity or price doesnot change what the list price was when the line was written.
NULL.specs/product/specs.md§10.5 updated to name the fourth snapshot alongsidethe existing three.
docs/schema/(chore(schema): generate PostgreSQL schema documentation #417) in the same PR.Decide before writing code
DefaultPriceMinorUnits, or do we keep it optional and render those lines asno list price? Either is fine; silently showing them as 0% off is not — that
is the version that lets a discount hide.
zero discount, in every consumer. Worth asserting in a test now so a later
slice cannot regress it into a
?? 0.Acceptance
moment.
line's
ListUnitPriceMinorUnits. This is the test that matters.NULL.UpdateItemleavesListUnitPriceMinorUnitsuntouched.NULL.Repo rules
InitialCreate.SalesOrder.Version, with aparallel-race integration test.