Functional Weave
Code in Rust

manufacturing.bom-cost@1.0.0

README.md

2,034 bytes · view raw

# manufacturing.bom-cost

The standard cost of one unit of a product, rolled up through its bill of
materials by cost element:

- **material**: every bought-in item (a BOM leaf) at its standard unit cost,
  times the total quantity one product needs across every level, scrap
  included;
- **labour**: every operation on the product and on each sub-assembly, run
  time x labour rate per hour, times how many of that item one product needs;
- **overhead**: the same run time x overhead rate per hour (overhead absorbed
  on operation hours).

Quantities come from `manufacturing.bom-explode` for a build of one, so scrap,
fractional quantities (3/4 m of timber) and parts used at several levels are
handled exactly as there, and a BOM with a cycle is refused with the same
error.

**Cost element roll-up.** A sub-assembly's labour stays labour and its
materials stay material all the way up (the "cost component split" of ERP
systems), rather than the sub-assembly's total becoming "material" of its
parent. That is what a cost sheet or variance analysis needs.

**Exact, then rounded once per element.** Every product is computed as an exact
fraction of a minor unit (120 seconds at £17.50 an hour is 58.33p) and each
element is rounded once, by `mode`, at the end. Rounding each operation
separately drifts: in the second vector the operations rounded down one by
one come to 485p of labour, the exact sum rounded down to 486p. `total` is
material + labour + overhead after rounding, so the cost sheet adds up.

**Rules.** Every bought-in item in the BOM needs exactly one entry in
`materialCosts`; a missing one, a duplicate, or an entry for an item that has
its own BOM (its cost is rolled up, not looked up) is an error. Costs and rates
must be in `currency` and not negative; operation times are whole seconds, not
negative. Entries for items outside this product are ignored, so a whole cost
file and routing file can be passed. Set-up time is not included: amortise it
into `seconds` per unit for the batch size you cost at.