woodshop/tests
rob 36d02fcb73 Material-aware pricing: oak ≠ pine
Resolves the v1 simplification where every species cost the same.

- CutItem/StockPiece gain `material`; build_cut_plan and reoptimize group by
  (stock, material) so each bought stick/sheet is a single species; pieces are
  stamped with their material (offcut seeds keep theirs).
- prices.estimate groups by (stock, species) and applies a per-species
  multiplier (DEFAULT_MATERIAL_MULTIPLIERS: SPF 1.0, oak 3.0, walnut 5.5, …),
  persisted to material_multipliers.json. CostLine shows "oak 1x4".
- PriceEditDialog gains a species-multiplier table; BOM Buy list shows species.
- Offcuts carry material so offcut reuse matches species.
- tests: multiplier scales price, default species at base, mixed species on the
  same stock priced separately, multiplier save/load.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 19:48:26 -03:00
..
test_bom_window.py Phase 6: inventory workflows (purchase / record build / use offcuts) 2026-05-30 19:23:24 -03:00
test_cutlist.py Add plywood (sheet stock) 2026-05-30 12:33:49 -03:00
test_cutplan.py Phase 4: batch builds (quantity N) 2026-05-30 19:14:23 -03:00
test_driver.py Carry conversation history so "yes" / "do that" resolve 2026-05-30 15:42:33 -03:00
test_estimate.py Phase 2: finish costs by kind in the estimate 2026-05-30 19:04:44 -03:00
test_geometry.py Add auto-assembly (Make connection) + feature rotation 2026-05-29 17:15:51 -03:00
test_gui_controller.py Carry conversation history so "yes" / "do that" resolve 2026-05-30 15:42:33 -03:00
test_instructions.py Phase 2: structured build instructions (deterministic + optional AI polish) 2026-05-30 14:36:50 -03:00
test_inventory.py Phase 6: inventory workflows (purchase / record build / use offcuts) 2026-05-30 19:23:24 -03:00
test_inventory_window.py Phase 7: shop Inventory window + stats 2026-05-30 19:25:28 -03:00
test_jigs.py Address shop-packet review (consistency, determinism, validation, jigs) 2026-05-30 15:11:02 -03:00
test_layout.py BOM window: tabs + cut-layout nesting + print (phase 1 of shop output) 2026-05-30 13:07:49 -03:00
test_materials.py Phase 1: material + finish fields + color resolver 2026-05-30 19:01:28 -03:00
test_prices.py Material-aware pricing: oak ≠ pine 2026-05-30 19:48:26 -03:00
test_scene.py Phase 1: material + finish fields + color resolver 2026-05-30 19:01:28 -03:00