Commit Graph

3 Commits

Author SHA1 Message Date
rob 01c4dee0bc Fix material/inventory boundary + offcut-preservation (Codex review)
1. Offcut reuse was lost on optimize: Find better layout / Best of 100 / Try
   alternative now pass available=self._available(); reoptimize seeds preserve
   owned/source so a locked offcut stays owned (not silently bought).
2. Inventory is now species-aware end to end: purchase/consume/adjust/on_hand/
   available_stock and record_build key by (stock, material); plan_consumption
   and Mark-purchased group by species; PurchaseDialog shows species and prices
   at the species rate; price-book save backs out the multiplier to the SPF base.
   A spruce on-hand no longer satisfies an oak cut.
3. Cross-species placement is now invalid: validate_cut_plan and the GUI drop
   path reject an oak cut on a spruce piece.
4. Yield is bought-only and consistent: _score divides bought-used by bought-area
   (owned offcuts excluded); the Shopping tab's yield matches.

tests: locked-reopt keeps owned offcut, species-aware on-hand, cross-species
validate, yield excludes owned, optimize preserves the offcut toggle. 203 pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 20:01:23 -03:00
rob 2b76317a3f Phase 6: inventory workflows (purchase / record build / use offcuts)
Wires the ledger into the BOM window via three workflows (Codex's
workflow-first UX), plus an offcut-consuming planner.

- StockPiece gains owned/source; build_cut_plan(available=) seeds the packer
  from owned offcuts (reusing the seeded-packing) so they're consumed before
  buying. Score reports stock_count = pieces to BUY (offcuts free) + owned_count;
  prices.estimate and the Buy list exclude owned pieces.
- BOM header: "Build units", an opt-in "Use shop offcuts" toggle, and
  "Mark purchased…" / "Record build…" buttons.
- PurchaseDialog: confirm qty + price each, opt-in "save prices to price book".
- RecordBuildDialog: shows consumed stock + each offcut with Keep/Burn/Trash/
  Ignore before committing (the moment to correct reality).
- Ledger.record_build takes per-offcut dispositions; used offcuts are consumed
  from the bin; build cost snapshot logged.
- tests: offcut toggle drops buy-count to 0, record-build writes the ledger.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 19:23:24 -03:00
rob 30a10adabc Phase 5: event-sourced inventory ledger model
inventory.py — shop-wide, append-only event log; current state derived by
folding (Codex's recommendation). Lean and plumbing-only.

- Events: purchase / consume / create_offcut / discard / adjustment /
  build_recorded. Ledger.load/save to $XDG_DATA_HOME/woodshop/inventory.json.
- Primitives: purchase, adjust, consume_offcut, discard_offcut, record_build
  (deducts consumed stock, keeps/discards each produced offcut).
- Derived: on_hand(), offcut_bin(), available_stock() (one Piece shape for full
  stock + offcuts — the AvailableStock interface), builds(), stats() (spent,
  units built, offcuts kept/burned/trashed, per-project units).
- plan_consumption(plan): derive consumed stock + reusable offcuts from a CutPlan.
- tests: purchase/consume, adjustment, keep/discard offcuts, consume removes
  from bin, plan_consumption, available_stock, save/load, cross-project stats.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 19:16:28 -03:00