Inventory and costing
Sub-ledger 2, migration0004.
Goods in, value through work in progress, finished goods out, cost of goods sold.
The chain flows one way
Every movement’sunit_cost and value is stamped immutably on the movement at post time.
That is design decision D5, and it is the reason the costing checks have teeth.
Because a movement’s cost is frozen, a later price change cannot retroactively move both the WIP-in and the WIP-out legs together.
In the v12 workbook, stock_movement!G is a live formula.
Change a price and both legs move, so “WIP nets to zero” is a tautology: it is true by construction and therefore tests nothing.
Here it is a real check, and it can fail.
The account legs
Typed inventory adjustments
An inventory adjustment derives its direction from signed quantity and signed value and chooses the inventory account from the item’s typed classification. A caller cannot choose an arbitrary debit/credit account to reinterpret the sign, and inconsistent sign combinations refuse. AP/AR control-account corrections use typed adjustment notes rather than the generic adjustment surface. The Close inventory family reuses the same read-only Books inventory-to-GL tie-out instead of maintaining a second formula. Open GRNI, missing historical evidence or an unreadable native register therefore remains partial/inconclusive in both surfaces rather than passing in Close while Books reports a break.Two ideas that carry the family
GRNI is the accrual between receipt and invoice. Goods arrive before the bill does.2010 holds the liability from receipt at PO price, and the supplier’s bill clears it - which is also the point where input VAT lands on 1300 and the AP obligation opens.
2010 has no TT200 code because it is a management accrual that nets to zero by the time a return is filed.
Landed cost allocates exactly.
Freight, duty and handling are spread across the received quantities using money.allocate_exact, so the shares sum to the source amount to the dong.
No residue, no rounding account.
The derived balances
Nothing here is stored.The Close checksums this family runs
Twenty-two fixed checks, plus one explainable balance per stock item. The must-be-zero ones include:Where it is enforced
The test that would fail if it broke
backend/tests/test_costing.py covers the operations.
backend/tests/test_v12_inventory_parallel_run.py is the fidelity test: it runs the workbook’s worked data through the sub-ledger and asserts the total_154 figures to four decimal places.
What goes wrong without it
A live-formula costing model does not produce wrong numbers so much as unfalsifiable ones. Every reconciliation passes because both sides recompute from the same current price, so the model reports health regardless of whether the underlying data is right. The specific damage is in margin. COGS is the largest single number in a manufacturing P&L, and if it is derived from a cost that moves after the fact, then last quarter’s gross margin changes when this quarter’s supplier price does.Related
- The seven sub-ledgers - the costing-to-payroll and costing-to-VAT edges
- Money is Decimal, always -
allocate_exact, which the landed-cost check rests on - Nothing stored that can be derived - the failure class this family illustrates best
- The Close checksums - the costing family in the full surface