How to expand demand through a bill of materials
This guide shows how to translate bundle demand into part demand and how to
flatten a recursive bill of materials (BOM) using extend.billOfMaterials.
Expand bundle demand into part demand
Define items, a recursive BOM, and orders. Then expand orders to parts and allocate the bundle amount to parts by cost share.
table Items[id] = with
[| as id, as BuyPrice |]
[| "kit", 0 |]
[| "subkit", 0 |]
[| "partA", 2 |]
[| "partB", 3 |]
[| "partC", 5 |]
table BOM = with
[| as Bundle, as Part, as Quantity |]
[| "kit", "subkit", 1 |]
[| "kit", "partC", 2 |]
[| "subkit", "partA", 1 |]
[| "subkit", "partB", 3 |]
expect BOM.id = BOM.Bundle
table Orders = with
[| as OrderId, as Id, as Quantity, as DemandDate, as NetA |]
[| "o1", "kit", 2, date(2024, 1, 10), 200 |]
[| "o2", "subkit", 1, date(2024, 1, 12), 40 |]
expect Orders.id = Orders.Id
table T max 100k = extend.billOfMaterials(
Item: Items.id,
Part: BOM.Part,
Quantity: BOM.Quantity,
DemandId: Orders.OrderId,
DemandValue: Orders.Quantity)
T.DemandDate = same(Orders.DemandDate) by Orders.OrderId at T.DemandId
T.NetA = same(Orders.NetA) by Orders.OrderId at T.DemandId
T.PartPrice = Items.BuyPrice * T.Quantity
T.BundlePrice = sum(T.PartPrice) by T.DemandId
T.NetA = T.NetA * (T.PartPrice / T.BundlePrice)
show table "Expanded" with
Items.id
T.DemandDate
T.Quantity
T.NetA
T.DemandId as "OrderId"
Example output:
| Id | DemandDate | Quantity | NetA | OrderId |
|---|---|---|---|---|
| partA | 2024-01-10 | 2 | 19.04762 | o1 |
| partA | 2024-01-12 | 1 | 7.272727 | o2 |
| partB | 2024-01-10 | 6 | 85.71429 | o1 |
| partB | 2024-01-12 | 3 | 32.72727 | o2 |
| partC | 2024-01-10 | 4 | 95.2381 | o1 |
Flatten a recursive BOM
Expand each bundle into its terminal parts and drop the trivial
bundle -> bundle rows.
table Items[id] = with
[| as id |]
[| "kit" |]
[| "subkit" |]
[| "partA" |]
[| "partB" |]
[| "partC" |]
table BOM = with
[| as Bundle, as Part, as Quantity |]
[| "kit", "subkit", 1 |]
[| "kit", "partC", 2 |]
[| "subkit", "partA", 1 |]
[| "subkit", "partB", 3 |]
expect BOM.id = BOM.Bundle
table T max 100k = extend.billOfMaterials(
Item: Items.id,
Part: BOM.Part,
Quantity: BOM.Quantity,
DemandId: Items.id,
DemandValue: 1)
where T.DemandId != Items.id
show table "Flattened BOM" with
T.DemandId as "Bundle"
Items.id as "Part"
T.Quantity
Example output:
| Bundle | Part | Quantity |
|---|---|---|
| kit | partA | 1 |
| subkit | partA | 1 |
| kit | partB | 3 |
| subkit | partB | 3 |
| kit | partC | 2 |