# 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.