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
|
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.
|
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**
|
### O9 — Inventory accounting policy — **RESOLVED (policy decision: expense at purchase / periodic)**
|
||||||
- Surfaced while fixing O6. The **Trial Balance** computes an inventory asset as opening + purchase bill-lines
|
- **Decision (owner, 2026-06-19):** materials (powder, consumables) are **expensed at purchase**, not
|
||||||
− consumption (perpetual), but the **Balance Sheet** `ComputeBalance` does **not** add inventory purchase
|
capitalized as inventory-for-resale — this is a service business that *uses* materials to deliver a
|
||||||
bill-lines to the asset and instead expenses all bill costs through retained earnings (periodic). So the BS
|
service, it does not sell inventory. So the **periodic** model is correct.
|
||||||
inventory line ≈ opening balance only, and BS vs TB disagree on inventory. O6's consumption relief was
|
- **Implication — no code change needed:**
|
||||||
therefore intentionally **not** applied to the BS (doing so alone would drive inventory negative / unbalance
|
- The Balance Sheet correctly does **not** capitalize inventory (cost hits the P&L at purchase via the
|
||||||
the sheet).
|
bill line categorized to a COGS/expense account). The earlier decision to leave the BS untouched stands.
|
||||||
- **Impact:** Balance Sheet inventory asset is understated and COGS timing differs between BS (periodic) and
|
- Purchase receiving creates a `Purchase`-type `InventoryTransaction` that posts **no** GL — correct.
|
||||||
P&L/TB (now perpetual for consumption). Pre-existing; not a trial-balance imbalance.
|
- The **perpetual** consumption-COGS path (O6: `DR COGS / CR Inventory` on JobUsage/Waste) is **opt-in**:
|
||||||
- **Fix direction:** decide on an inventory accounting policy (perpetual vs periodic) and make the Balance
|
it only fires when an item has *both* `CogsAccountId` and `InventoryAccountId`, which are set **only via
|
||||||
Sheet consistent with the Trial Balance / P&L. Best done as part of the JournalEntry single-source refactor.
|
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
|
## Status
|
||||||
Findings **O1–O8 + the read-path sweep are resolved** on `dev`. **O9 is newly identified and OPEN** (inventory
|
**All findings O1–O9 + the read-path sweep are resolved** on `dev` (O9 by policy decision — expense at
|
||||||
capitalization policy — needs a decision, recommend folding into the JournalEntry single-source refactor).
|
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.
|
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.
|
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
|
- **Phase 4** — post conversion-balance JEs at the cutover date; delete the dead re-derivation code
|
||||||
(~1,000+ lines).
|
(~1,000+ lines).
|
||||||
- **Phase 5** — decide **O9** (perpetual vs periodic inventory) and implement it as JE postings. Perpetual
|
- **Phase 5** — **O9 is already decided: expense at purchase (periodic).** Materials are used to deliver a
|
||||||
falls out naturally: purchases DR Inventory, consumption DR COGS / CR Inventory (O6 already posts the
|
service, not sold, so they are expensed when purchased (bill → COGS/expense account); inventory is **not**
|
||||||
consumption half). This makes the Balance Sheet inventory line consistent with the Trial Balance / P&L.
|
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
|
## Prerequisites before starting
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user