Record O9 decision: expense materials at purchase (periodic inventory)
Owner decision: this is a service business that uses materials to deliver a service rather than selling inventory, so powder/consumables are expensed at purchase (bill to a COGS/expense account) and inventory is not capitalized on the Balance Sheet. No code change required — the Balance Sheet already behaves this way, and the perpetual consumption-COGS path (O6) is opt-in via item account mappings (set only via CSV import) and stays dormant under this policy. Documents the double-count footgun (do not both expense at purchase and map item COGS/Inventory accounts) and locks the periodic choice into the ledger-refactor plan's Phase 5. All accounting audit findings O1-O9 now resolved. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+18
-13
@@ -193,19 +193,24 @@ parallel with the live postings. The durable fix is to make **every** financial
|
||||
lines and drive all reports/recompute from those lines alone (single source of truth) — O8's write-off already
|
||||
does exactly this, which is why it was the cleanest. Worth considering before the ledger grows further.
|
||||
|
||||
### O9 — Balance Sheet does not capitalize/relieve inventory (periodic vs perpetual) — **OPEN, needs policy decision**
|
||||
- Surfaced while fixing O6. The **Trial Balance** computes an inventory asset as opening + purchase bill-lines
|
||||
− consumption (perpetual), but the **Balance Sheet** `ComputeBalance` does **not** add inventory purchase
|
||||
bill-lines to the asset and instead expenses all bill costs through retained earnings (periodic). So the BS
|
||||
inventory line ≈ opening balance only, and BS vs TB disagree on inventory. O6's consumption relief was
|
||||
therefore intentionally **not** applied to the BS (doing so alone would drive inventory negative / unbalance
|
||||
the sheet).
|
||||
- **Impact:** Balance Sheet inventory asset is understated and COGS timing differs between BS (periodic) and
|
||||
P&L/TB (now perpetual for consumption). Pre-existing; not a trial-balance imbalance.
|
||||
- **Fix direction:** decide on an inventory accounting policy (perpetual vs periodic) and make the Balance
|
||||
Sheet consistent with the Trial Balance / P&L. Best done as part of the JournalEntry single-source refactor.
|
||||
### O9 — Inventory accounting policy — **RESOLVED (policy decision: expense at purchase / periodic)**
|
||||
- **Decision (owner, 2026-06-19):** materials (powder, consumables) are **expensed at purchase**, not
|
||||
capitalized as inventory-for-resale — this is a service business that *uses* materials to deliver a
|
||||
service, it does not sell inventory. So the **periodic** model is correct.
|
||||
- **Implication — no code change needed:**
|
||||
- The Balance Sheet correctly does **not** capitalize inventory (cost hits the P&L at purchase via the
|
||||
bill line categorized to a COGS/expense account). The earlier decision to leave the BS untouched stands.
|
||||
- Purchase receiving creates a `Purchase`-type `InventoryTransaction` that posts **no** GL — correct.
|
||||
- The **perpetual** consumption-COGS path (O6: `DR COGS / CR Inventory` on JobUsage/Waste) is **opt-in**:
|
||||
it only fires when an item has *both* `CogsAccountId` and `InventoryAccountId`, which are set **only via
|
||||
CSV import** (never by normal item creation). Under this policy those mappings should be left empty, so
|
||||
the path stays dormant. O6's recompute fix remains correct and harmless when unused.
|
||||
- **⚠ Footgun to avoid:** do **not** both expense powder at purchase (bill → COGS account) *and* map an
|
||||
item's `CogsAccountId` + `InventoryAccountId` — that would record the cost twice (once at purchase, once at
|
||||
consumption). Keep item COGS/Inventory account mappings empty under the expense-at-purchase policy.
|
||||
|
||||
## Status
|
||||
Findings **O1–O8 + the read-path sweep are resolved** on `dev`. **O9 is newly identified and OPEN** (inventory
|
||||
capitalization policy — needs a decision, recommend folding into the JournalEntry single-source refactor).
|
||||
**All findings O1–O9 + the read-path sweep are resolved** on `dev` (O9 by policy decision — expense at
|
||||
purchase — needing no code change). The optional structural follow-up is the JournalEntry single-source
|
||||
refactor (`docs/ACCOUNTING_LEDGER_REFACTOR.md`), which would prevent the O2/O6/O7/O8 bug class from recurring.
|
||||
Original audit numbering #1–3/#5/#6/#8 remains unrecoverable (see top). Nothing merged to `master` yet.
|
||||
|
||||
@@ -83,9 +83,12 @@ contra-revenue — all disappear because they are simply journal lines.
|
||||
against the old numbers using the snapshot harness below.
|
||||
- **Phase 4** — post conversion-balance JEs at the cutover date; delete the dead re-derivation code
|
||||
(~1,000+ lines).
|
||||
- **Phase 5** — decide **O9** (perpetual vs periodic inventory) and implement it as JE postings. Perpetual
|
||||
falls out naturally: purchases DR Inventory, consumption DR COGS / CR Inventory (O6 already posts the
|
||||
consumption half). This makes the Balance Sheet inventory line consistent with the Trial Balance / P&L.
|
||||
- **Phase 5** — **O9 is already decided: expense at purchase (periodic).** Materials are used to deliver a
|
||||
service, not sold, so they are expensed when purchased (bill → COGS/expense account); inventory is **not**
|
||||
capitalized on the Balance Sheet. In the refactor, post material purchases as `DR COGS / CR AP` (expense
|
||||
immediately) and do **not** emit a separate consumption JE. The opt-in perpetual path (item
|
||||
`CogsAccountId` + `InventoryAccountId`) stays unused under this policy — keep those mappings empty to avoid
|
||||
double-counting. No perpetual inventory asset/relief postings.
|
||||
|
||||
## Prerequisites before starting
|
||||
|
||||
|
||||
Reference in New Issue
Block a user