The Pattern known as "Bill Of Materials" offers mainly given a certain Product to obtain the list (bill) of materials necessary to build it.
This pattern applies when there is an entity that can be composed of other entities of the same type.
The data that follow this pattern fulfill the following properties:
1. An entity can be composed of many other entities of the same type.
2. Each of these component entities can also be composed of other entities.
3. An entity can be a component of many entities.
The canonical example is the Products of a manufacturing company, where each Product is composed of other Products that themselves are also composed of products.
To implement this pattern just two GenexusTransaction are needed:
Product
{
ProductId*
ProductName
}
Composition
{
CompoundProductId* subtype of ProductId
CompoundProductName subtype of ProductName
ComponentProductId* subtype of ProductId
ComponentProductName subtype of ProductName
CompositionQuantity // quantity of the component product present in the composed product
}
The most interesting GeneXus procedure is the 'Bill of Materials' itself: given an initial product and a quantity of it to build, returns the list of materials (and quantities) needed.
There are to variants of this procedure, the one that returns all the product (included the intermediate ones) or just return the raw materials (the leaves of the tree).
There are also two ways to implement it, using recurvise programming (valid for the .NET or Java generators) or using an stack. In both cases an SDT is returned with the list of products:
BillOfMaterialSDT collection (Item)
ProductId
Quantity
Name: PBillOfMaterial
Rules:
parm(in:&ProductId, in:&InitialQuantity, out:&BillOfMaterialsSDT);
For each
where CompoundProductId = &ProductId
PAddInBoMSDT.call(ComponentProductId, &InitialQuantity*CompositionQuantity, &BillOfMaterialsSDT) // delete it to just returns the raw materials
PBillOfMaterial.call(ComponentProductId, &InitialQuantity*CompositionQuantity, &BillOfMaterialsSDT)
when none
PAddInBoMSDT.call(&ProductId, &InitialQuantity, &BillOfMaterialsSDT)
endfor
Name: AddInBoMSDT
Rules:
parm(&ProductId, &Quantity, &BillOfMaterialsSDT);
Source:
? = Boolean.False
for &item in &BillOfMaterialsSDT
if &item.ProductId = &ProductId
&item.Quantity = &Quantity
? = Boolean.True
endif
endfor
if not ?
&BillOfMaterialsSDT.Add(&ProductId, &Quantity) // this is pseudocode
endif
This procedure returns all the component products (intermediate products and raw materials), but it's easy to modify it for just returning the raw material deleting the first call to PAddInBoMSDT.