Configuration BOM Mapping Rules
Overview
BOM Mapping rules associate BOM items and attributes to Oracle CPQ Configuration attributes and Commerce line items. Simple Table-based Configuration rules are defined using the BOM Item Mapping Data Table and optionally the BOM Attribute Mapping Data Table. Advanced BML-based rules can then be used in addition to the Table-based rules to refine the mapping results. In rare cases, BOM Item Mapping tables are not used at all, and administrators use advanced BML-based Rules to establish Configuration and Commerce association with BOM items. If BOM Mapping tables are not used, administrators can use advance BML-based Rules to establish Configuration and Commerce association. Advanced BML-based rules can be used in addition to the Table-based rules to refine the mapping results.
Rule Types
Configuration BOM Item Mapping
BOM item mapping associates BOM items to Configuration attributes. During Configuration, whenever the configuration state is changed, the Configuration BOM Mapping Rules are invoked to map Configuration attributes to BOM items. The following image illustrates BOM item and Configuration attribute associations. For Example: When the "areYouLookingForALaptopOrDesktop" Configuration attribute is "Laptop", the root BOM item with the Variable Name "LP94777" is created.
At the next child level, if the "processor" configuration attribute is "INTEL", the child BOM item "LAPPRO1101" is created. If it is "AMD", the child BOM item "LAPPRO1109" is created. The child BOM item is created under the root BOM item. Their hierarchical relationship is defined in the BOM Item Definition table. A child BOM item is created only if its parent BOM item is created.
For more information about BOM item instances, refer to the BOM Instances section. The BOM Item Definition provides the default quantity in the BOM instance. The definition node also comes from BOM Item Definition.
Items in the BOM instance, created by BOM item mapping, must exist in the BOM Item Definition. The hierarchy of BOM item mapping is entirely based on the BOM Item Definition. As a result, a child BOM item is generated only if its parent BOM item is included.
Reconfiguration BOM Item Mapping
During reconfiguration, the Launch Configuration attributes are mapped from the BOM item instance. Refer to the JSON Representation of a BOM Item image for the following example. If “LP94777” is the BOM instance root BOM item, when the Configuration session is launched, the "areYouLookingForALaptopOrDesktop” Configuration attribute is set to "Laptop". Similarly, if the child BOM item "LAPPRO1109" exists, the "processor" Configuration attribute is set to "AMD".
If the BOM Mapping rule values conflict with sales side data, Configuration rules attempt to set the same Configuration attribute with different values. If the attribute is not a Multi Select Menu, a runtime error occurs.
It is considered a match when the sales side Configuration attribute value is "equal", or "the same as" the mapped value. However, if the Configuration attribute is a Multi Select Menu, the comparison operator is inclusively "contains". In other words, as long as the Multi Select Menu attribute contains the value required by the rule, it is considered a match.
Best Practice Recommendation: Maintain a 1-to-1 mapping between a BOM item and a Configuration attribute value.
The table-based reverse mapping sets the Configuration attributes based on which BOM items and BOM attributes exist in the BOM instance. It does not attempt to modify the Configuration attributes based on which BOM items or BOM attributes are absent in the BOM instance. Refer the "LAPPRO1109" BOM item example above for the following description. If the BOM instance contains "LAPPRO1109", the "processor" Configuration attribute is set to "AMD" accordingly. If the BOM instance does not contain "LAPPRO1109", the table-based reverse mapping does not attempt to set the "processor" attribute, even if it happens to be "AMD". If the "processor" attribute must be set to a specific value when "LAPPRO1109" is not present, advanced BML can be used to set the value, refer to From BOM Launch Configurations for more information.
When a Commerce Model line that contains a captured Sales BOM is reconfigured, mapping from BOM to Launch Configuration invokes the following actions:
- The Configuration is restored to the values saved on the Model line
- The Sales BOM items are validated against the current BOM Item Definition. Invalid items are removed.
- If Table-based BOM Mapping rules exist, they are invoked first, to map the BOM instance values to the Configuration attributes.
- If "From BOM to Configuration” advanced BML-based BOM mapping rules that are defined, they are invoked next, using the defined order.
Special attention should be paid to selector configuration attributes. If the selector (search input) value needs to be overridden via BOM Mapping, the Configuration attribute must be set to auto-locked. This is consistent with the current Configuration behavior: the selector recommended value is preferred, unless the attribute is auto-locked during reconfiguration. The auto-lock must be defined in the attribute, instead of being dynamically set by a Recommendation rule.
BOM Attribute Configuration Rules
Similar to BOM item mapping, the BOM attribute mapping is also bidirectional. From Configuration to BOM, the target values are set based on the source types and values. From BOM to Launch Configuration, the initial Configuration attribute values are set from source to target.
BOM attribute mapping is used to set a BOM attribute, the quantity of the BOM item, or a Commerce line attribute. Under each BOM item, administrators can define many BOM attributes using attribute mapping.
Conflicting end values occur if multiple BOM attribute mappings attempt to set the same attribute to different values. Similar results can occur From BOM to Launch Configuration, if Configuration rules attempt to set the same Configuration attribute with different values. These events will generate runtime errors.
The BOM Attribute Mapping table identifies the attribute Target and Source. In the following JSON sample, the “attributes” node stores BOM attribute Target Types, and the “fields” node stores Line attribute Target Types.
{ "partNumber": "BP3025", "quantity": 1, "variableName": "BP3025", "definition": { "SequenceNum": 2020, "ItemId": "3025", "ItemType": "Standard Item", "Optional": "N" }, "attributes": { "BSO3901": {"value": "H~V"}, "BSN3095": {"value": ""} }, "fields" : { "lineActionCode", "Add" }, "explodedQuantity": 1, "children": [] }
During Configuration, BOM Mapping rules are invoked when changes to Configuration attribute values are saved. BOM Mapping rules run after Recommendation rules, but before Recommended Item rules. If the Configuration contains multiple nodes, BOM Mapping rules are only run in the last node, similar to Recommended Item rules.
BOM Mapping rules are invoked as follows:
- Simple Table-based BOM Mapping rules – During set up, a Configuration Model can be associated with different BOMs using multiple BOM Mapping rules. However, on the sales side, only one Table-based BOM Mapping rule should apply. In other words, a given Configuration state on the sales side can only be associated with one Sales BOM.
- Advanced BML-based BOM Mapping rules – BML-based rules are actuated in order, if they are defined. This allows administrators to revise the BOM instance using BML scripts. The BML revised result is an updated JSON BOM instance, which must conform the BOM Item Definition.
During Configuration, administrators can reference the current BOM instance by using the system Configuration attribute _bm_bom_instance
. If the BOM instance is not null, it can be viewed in the Pipeline Viewer. The Pipeline Viewer displays which Configuration attributes and BOM Mapping rules were used to create the BOM instance.
If the BOM instance is not null, pricing of the BOM parts occurs. If the price is not zero, it is displayed in the Configuration Pricing section.
Note: The root BOM item should not have an assigned price. If the root Part Number has a defined price, BOM pricing ignores the defined price. The BOM price displayed during Configuration is the unit price, while the pricing displayed in quotes is the total using an exploded quantity.
By default, BOM Mapping is executed at the current time. When the BOM is stored into a quote, the effective date of the BOM Mapping can be set on the line attribute “Line BOM Effective Date” field of the root BOM item line, (i.e. the Model line). This effective date is honored when:
- A Sales BOM that is extracted from a quote is validated
- A BOM instance is reconfigured
In the latter case, the effective date only applies to Configuration BOM Mapping Rules. Other Configuration rules do not honor the BOM Mapping effective date.
Mapping to Single Select Pick List Attributes
Beginning in Release 18B, Oracle CPQ provides BOM Mapping support for Single Select Pick Lists, which are also known as Dynamic Menus. When a Single Select Pick List option is selected, the applicable BOM Mapping rules are invoked to add parts to a Transaction based on the Single Select Pick List selection. The Single Select Pick List attribute type can be created in Configuration for Text, Integer, and Float data types.
Note: To ensure proper operation of the BOM Mapping rules, the variable names referenced for the Single Select Pick List options must match the Configurable Attribute variable names and values in the BOM Item Mapping table.
Mapping to Configurable Array Attributes
Beginning in Release 18B, Oracle CPQ provides BOM Mapping support for Configurable Array Attributes. The options selected during Configuration can be used to populate BOM items and attributes in the BOM instance.
BOM Item Mapping for Configurable Array Attributes
When Configurable array attributes are used with BOM Item Mapping, the Array Set row items are mapped to a matching BOM item. The mapping should be one-to-one between the Array Set row and a BOM item.
For example: In the following BOM Item Mapping Data Table there are two BOM items displayed under the "SoftwareRootBOM" item:
- AntiVirusItem - Part Number "antiVirusPart", ConfigAttrVarName "softwareType", and ConfigAttrValue "Enterprise Anti-Virus"
- EncryptionItem - Part Number "encryptionPart", ConfigAttrVarName "softwareType", and ConfigAttrValue "EncryptionSoftware"
Customers can use Configurable Array Sets to define BOM items to be selected during Configuration.
For example: The following image displays an Application Software Configuration item with three items: "Enterprise Anti-Virus", "Encryption Software", and "Encryption Software".
When these BOM items are selected during Configuration, the following BOM Instance is generated:
{ "variableName": "SoftwareRootBOM", "partNumber": "softwareSelectionPart", "quantity": 1, "category": "sales", "children": [{ "variableName": "AntiVirusItem", "partNumber": "antiVirusPart", "quantity": 1 }, { "variableName": "EncryptionItem", "partNumber": " encryptionPart", "quantity": 1 }, { "variableName": "EncryptionItem", "partNumber": "encryptionPart", "quantity": 1 }] }
IMPORTANT:
- When configurable array attributes from an array set are used in more than one BOM item mappings, the same array attributes form the set must be used in all BOM item mappings.
- Refer to BOM Mapping Configurable Array Attribute Restrictions for more restrictions on BOM item mappings and explanations.
BOM Attribute Mapping for Configurable Array Attributes
When Configurable Array Attributes are used with BOM Item Mapping, related BOM Attribute Mappings can use additional Configurable Array Attributes from the same array set. The additional Configurable Array Attributes for a BOM item are mapped to Attribute Mapping items.
For example: In the following BOM Attribute Mapping Data Table, two Configurable Attributes are displayed:
- supportType - TargetType "BOM_ATTRIBUTE", TargetVariableName "Support", and SourceType "CONFIG_ATTRIBUTE".
- softwareQuantity - TargetType "QUANTITY" and SourceType "CONFIG_ATTRIBUTE".
Customers can also use Configurable Array Sets to define BOM item attributes to be selected during Configuration.
For example: The following image displays an Application Software Configuration with three items:
- "Enterprise Anti-Virus" with "Gold" support and quantity "2"
- "Encryption Software" with "Silver" support and quantity "1"
- "Encryption Software" with "Platinum" support and quantity "3"
When these BOM items and attributes are selected during Configuration, the following BOM Instance is generated:
{ "variableName": "SoftwareRootBOM", "partNumber": "softwareSelectionPart", "quantity": 1, "category": "sales", "children": [{ " variableName": "AntiVirusItem", "partNumber": "antiVirusPart", "quantity": 2, "attributes": {"Support": {value: "Gold"}} }, { " variableName": "EncryptionItem", "partNumber": " encryptionPart", "quantity": 1, "attributes": {"Support": {value: "Silver"}} }, { " variableName": "EncryptionItem", "partNumber": " encryptionPart", "quantity": 3, "attributes": {"Support": {value: "Platinum"}} }] }
IMPORTANT:
- BOM Attributes can be mapped to both Configurable Array Attributes and non-array type Configurable Attributes.
- Refer to BOM Mapping Configurable Array Attribute Restrictions for restrictions on BOM attribute mappings
Reconfiguration of Configurable Array Attributes
During reconfiguration, the array set is initialized to be consistent with the BOM items in the quote. For example: If a quote contains a single BOM item that maps to the array set, the size of the array set is set to one.
A more complicated use case occurs when some of the array-set attribute domain values are not mapped to BOM items. In the case, during reconfiguration the unmapped records are left unmodified. For example:
- A Configuration array set "Dessert" is defined, with an attribute called "DessertType" with three options: Coffee, Ice cream and Cake. "Ice-cream" is mapped to BOM item "BOMIcecream", "Cake" is mapped to BOM item "BOMCake", but "Coffee" is not mapped.
- On the sales side, there are only two rows in the "Dessert" menu, one is "Coffee", and the other is "Cake".
- When a user selects “Cake” during Configuration, a Sales BOM is created, containing a BOM item "BOMCake".
- When the BOM instance is saved to a quote, there is a part line corresponding to "BOMCake".
- When the quote is reconfigured, the "BOMCake" part line is replaced by "BOMIcecream".
- During reconfiguration, the BOM mapping from BOM to Launch Configuration replaces the "Cake" in the "Dessert" array set with "Ice cream", but leaves "Coffee" is unchanged, as Coffee is never involved in the BOM mapping.
IMPORTANT: Refer to BOM Mapping Configurable Array Attribute Restrictions, to view restrictions that are enforced, primarily to maintain one-to-one mapping between a row in the array set and a BOM item.
Administration
Create Configuration BOM Mapping Rules
Administrators create Configuration BOM Mapping rules at the Model level. BOM Mapping rules associate Configuration attributes to the BOM items. Use simple Table-Based Rules, advanced BML-Based Rules, or both for BOM Mapping.
Perform the following steps to create a Configuration BOM Mapping rule.
-
Navigate to the Model Administration List page.
Admin > Catalog Definition > Product Families > Product Lines > Models
-
Select BOM Mapping from the Navigation drop-down menu, and click List.
-
Click Add to set up a new BOM Mapping Configuration rule.
- Continue to one of the following procedures:
Define Simple Table-Based BOM Mapping Rules
A simple table-based BOM mapping rule uses the BOM item mapping data table to declaratively map the configuration attributes to BOM items.
Note: The BOM Item Definition and BOM Item Mapping tables must be activated to use simple Table-based Configuration rules. If the BOM Item Mapping table is not activated, advanced BML-based must be used.
- Enter a Name, Variable Name, and Description for the new BOM Mapping Configuration rule.
-
Define the Condition Type for BOM mapping rules.
Beginning in Release 18B, administrators can define a logic condition that specifies when a rule should run.
There are three options:- Always True: The rule will fire automatically, every time, because a specific condition does not need to be met.
-
Simple Condition: The rule will fire based on defined condition attributes, operators, and values that are selected from drop-down menus.
When Simple Condition is enabled, administrators can define Attributes, Operators, Values, Range Operators, and Range Values for the desired condition. They can also Add Rows and set the Order of Operations to provide multiple conditions.
-
Advanced Condition: The rule will fire based on an advanced function written with BML.
The advanced function is meant for complex condition logic. Administrators use BML to define conditions in the Function Editor. After selecting the Advanced Condition type, administrators select the View/Edit the BML Function to access the Function Editor.
IMPORTANT: Simple and Advanced Conditions are only evaluated during Configuration; these conditions are NOT evaluated during Reconfiguration.
- Select a Target BOM from the drop-down menu. The target BOM is an available BOM in the BOM root items list.
- Select a Target Commerce Process, if BOM attributes are mapped to line attributes.
-
Click Save and View Details.
Validate Table-based BOM Mapping Rules
If there are validation errors for the BOM item mapping or its children BOM attribute mappings, an error icon is shown up on the BOM item.
Click on the item Variable Name link, for details about the error.
As shown in the following image, there is a typo of the configurable attribute name. It should be "processor" instead of "processors".
In the following example, the following error is displayed after the administrator selects Save and View Details. The BOM Item Definition table had more than one root item under LP94777. Each Table-based BOM Mapping rule can only map to a single root BOM item tree. If the data table contains more than one root BOM item under a single BOM mapping rule, it is a validation error.
When creating BOM Item Configuration rules, administrators can define multiple BOM mapping rules, each being associated with different root BOM items. However, on the sales side, only one of the table-based BOM mapping rules should apply, based on the Configuration attribute and value defined in the root BOM item mapping. In other words, a given Configuration state on the sales side can only be associated with a single Sales BOM.
Define Advanced BML-Based BOM Mapping Rules
Advanced BML-based Configuration rules use BML to map between Configuration attributes and BOM items.
Two BML expressions can be defined for the two-way mapping:
From Configuration to BOM Items
BML from configuration to BOM is generally used to revise the BOM instance created by the table-based mapping, though it is possible to use BML-based mapping without the simple, table-based mapping. Use the _bm_bom_instance
Configuration system attribute to acquire the BOM instance as a JSON object. The BML script should return a JSON object, which is used to set the BOM instance held by the configuration session.
The BOM instance created by the BML-based mapping must conform to the BOM Item Definition. The instance is validated against the current BOM Item Definition to verify:
- BOM items are valid;
- The following line item fields exist:
variableName
,partNumber
, andquantity
.
For BML-based Configuration rule examples, refer to the following samples.
The following example uses BML JSON functions to double the child BOM item quantities.
//-------------------------------------------------------------- // Sample BML from Configuration to BOM // // Double the quantities of the direct child BOM items of the root BOM / // Input Attributes: // _bm_bom_instance: the BOM item instance in JSON // // Output: // The BOM item instance in JSON //------------------------------------------------------------- // Get the first level child BOM items size = 0; children = jsonget(_bm_bom_instance, "children", "jsonarray"); if (isnull(children) == false) { size = jsonarraysize(children); } // Loop through child BOM items. // No-op if the children is empty or does not exist. indices = range(size); for index in indices { bomItem = jsonarrayget(children, index, "json"); qty = jsonget(bomItem, "quantity", "integer"); jsonput(bomItem, qty * 2); } return _bm_bom_instance;
Note: jsonget
fetches children by reference, and jsonarrayget
returns bomItem by reference.
As a result, updating bomItem directly updates _bom_item_instance
.
The following example creates the BOM item, and appends it to the "children" node of the parent BOM item.
// Sample code snippet to add a child BOM item to the root tb1 = json(); jsonput(tb1, "variableName", "TB1"); jsonput(tb1, "partNumber", "40mb_100gb"); jsonput(tb1, "quantity", 3); // Get the "children" node by reference. // Subsequent changes to "children" directly update _bm_bom_instance children = jsonget(_bm_bom_instance, "children", "jsonarray"); if (isnull(children)) { jsonput(_bm_bom_instance, "children", jsonarray()); children = jsonget(_bm_bom_instance, "children", "jsonarray"); } // Append the child BOM item. jsonarrayappend(children, tb1);
The following sample BOM instance is created:
{ "partNumber": "telecom_package", "quantity": 2, "isModel": false, "explodedQuantity": 2, "category": "sales", "variableName": "TBRoot", "children": [ { "partNumber": "40mb_100gb", "quantity": 3, "isModel": false, "explodedQuantity": 6, "variableName": "TB1" }] }
Notes:
explodedQuantity
is automatically updated once all BML-based BOM mapping rules are executed and does not need to be set in BML.isModel
will default to False and does not need to be set in BML. This option is only set to True for System Configuration.
Create a Root BOM from Scratch Sample
If table-based BOM mapping rules do not exist, a root BOM can be created from scratch. In this special case, the _bm_bom_instance
system attribute starts as an empty skeleton without the part number or variable name: {"category": "sales", "isModel": false}
//-------------------------------------------------------------- // Sample BML from Configuration to BOM // Create the root BOM from scratch when there are no table-based BOM mapping rules // // Input Attributes: // _bm_bom_instance: the BOM item instance in JSON. It starts as a skeleton as // {"category": "sales", "isModel": false}, // without the part number or variable name. // Output: // The BOM item instance in JSON //------------------------------------------------------------- // The following three fields are mandatory fields to create a BOM item jsonput(_bm_bom_instance, "variableName", "TBRoot"); jsonput(_bm_bom_instance, "partNumber", "telecom_package"); jsonput(_bm_bom_instance, "quantity", 1); return _bm_bom_instance;
This results in the following BOM:
{ "partNumber": "telecom_package", "quantity": 2, "isModel": false, "explodedQuantity": 2, "category": "sales", }
explodedQuantity
is automatically updated once all BML-based BOM mapping rules are executed and does not need to be set in BML.
In BML from Configuration to BOM, the input attribute _bm_bom_instance is never null. If the BOM item instance does not exist for the current Configuration session, an empty skeleton without the part number or variable name is sent.
There are subtle differences between table-based mapping and BML-based mapping. If table-based mapping is defined, it is always fired first. It creates a brand new BOM instance each time it is invoked and BML-based mapping can then make additional adjustments to that BOM. In this case, the BML does not have to be idempotent. However, if table-based mapping is not defined, the BML mapping receives the BOM instance created from the previous update as the starting point and the BML then must be idempotent.
For example: a BML-based BOM mapping creates a warranty BOM item based on configurable attribute "Select Warranty". If table-based mapping is defined, the table-based mapping creates a new BOM instance before the BML mapping is fired each time. However, if table-based mapping is not defined, the BML can work on a BOM instance from the previous update and must account for the possibility that the warranty BOM item may have been created in the previous update. Without that logic, a duplicate warranty BOM item may be created each time the end user clicks "Update".
The following example removes the last child BOM item from the root BOM.
//-------------------------------------------------------------- // Sample BML from Configuration to BOM // Remove the last child BOM item. // // Input Attributes: // _bm_bom_instance: the BOM item instance in JSON // // Output: // The BOM item instance in JSON //------------------------------------------------------------- size = 0; children = jsonget(_bm_bom_instance, "children", "jsonarray"); if (isnull(children) == false) { size = jsonarraysize(children); } if (size > 0) { jsonarrayremove(children, size - 1); } return _bm_bom_instance;
For more complicated cases, JSON path can be used. For example: in Oracle EBS, optional class BOM items are defined to serve as containers of optional items. In this example, all empty optional class items that do not have child items are removed.
//-------------------------------------------------------------- // Sample BML from Configuration to BOM // Remove empty optional class items. // An empty optional class item is as such: // - Its "definition" contains Itemtype == 'CLASS'. // - Its "children" is empty // // Input Attributes: // _bm_bom_instance: the BOM item instance in JSON // // Output: // The BOM item instance in JSON //------------------------------------------------------------- jsonpathremove(_bm_bom_instance, "$..children[?(@.definition.ItemType=='CLASS' && @.children.length()==0)]"); return _bm_bom_instance;
Note: Release 18B provides support for removal of empty "Option Class" BOM items in table-based mapping. Refer to the BOM Item Definition Table "Option Class" BOM Item Type section for more details.
In the following example, BML is used to insert the "membership card type" BOM attribute, based on the customer rating. It also illustrates how to use BML to implement comparison operators other than equal.
//-------------------------------------------------------------- // Sample BML from Configuration to BOM // Set the membership card type based on the customer rating // If 70 <= customerRating, set cardType = Platinum // If 30 <= customerRating < 70, set cardType = Gold // else set cardType = Silver // // Input Attributes: // _bm_bom_instance: the BOM item instance in JSON // customerRating: an integer from 0 to 100. // // Output: // The BOM item instance in JSON //------------------------------------------------------------- // Locate the membership card BOM item membershipCard =jsonpathgetsingle(_bm_bom_instance, "$..children[?(@.variableName == 'MembershipCard')]", "json"); if (isnull(membershipCard) == false) { // Create cardType BOM attribute cardTypeValue = "Silver"; if (70 <= customerRating) { cardTypeValue = "Platinum"; } elif ((30 <= customerRating) AND (customerRating < 70)) { cardTypeValue = "Gold"; } cardType = json(); jsonput(cardType, "label", "Membership Card Type"); jsonput(cardType, "value", cardTypeValue); // Attach the cardType BOM attribute attributes = jsonget(membershipCard, "attributes", "json"); if (isnull(attributes)) { jsonput(membershipCard, "attributes", json()); attributes = jsonget(membershipCard, "attributes", "json"); } jsonput(attributes, "cardType", cardType); } return _bm_bom_instance;
Configurable Array Attributes Sample
This example demonstrates how to use configurable array attributes to create BOM items. The BML code loops through the software array set and creates the corresponding BOM item based on the software type selected.
//--------------------------------------------------------------- // Sample BML from Configuration to BOM // Create BOM items based-on configurable array attributes // // Input Attributes: // _bm_bom_instance: the BOM item instance in JSON // softwareArraySize: int // softwareType: string[] // softwareQuantity: integer[] // softwareSupport: string[] // // Output: // The BOM item instance in JSON //------------------------------------------------------------- // Set up the root BOM item jsonput(_bm_bom_instance, "variableName", "SoftwareRootBOM"); jsonput(_bm_bom_instance, "partNumber", "softwareSelectionPart"); jsonput(_bm_bom_instance, "quantity", 1); // Set up children children = jsonarray(); indices = range(softwareArraySize); for index in indices { software = softwareType[index]; variableName = ""; partNumber = ""; if (software == "Enterprise Anti-Virus") { variableName = "AntiVirusItem"; partNumber = "antiVirusPart"; } elif (software == "Enterprise Anti-Spam") { variableName = "AntiSpamItem"; partNumber = "antiSpamPart"; } else { continue; } // Create the child BOM item item = json(); jsonput(item, "variableName", variableName); jsonput(item, "partNumber", partNumber); jsonput(item, "quantity", softwareQuantity[index]); //Add BOM attributes attributes = json(); attr = json(); jsonput(attr, "value", supportType[index]); jsonput(attributes, "Support", attr); jsonput(item, "attributes", attributes); jsonarrayappend(children, item); } jsonput(_bm_bom_instance, "children", children); return _bm_bom_instance;
Manufacturing BOM vs Sales BOM
BOM mapping can occur in two scenarios. During a normal Configuration flow, a Sales BOM is created via BOM mapping. In addition, the getbom
BML function can be used to create a manufacturing BOM for fulfillment integration. Both scenarios trigger all defined BOM mapping rules. Inside the BML-based BOM mapping, the category field of _bm_bom_instance
is used to indicate whether the BML is triggered for sales or manufacturing BOM mapping.
// No operations are performed if the BML is invoked for a manufacturing BOM. // This check is only required when getbom is used to extract the manufacturing BOM category = jsonget(_bm_bom_instance, "category"); //"sales" or "manufacturing" if (category == "manufacturing") { return _bm_bom_instance; }
The JSON path functions can be used to provide versatile modification of JSON objects.
Refer to the JSON Functions topic for detailed information for the following JSON path functions:
-
jsonpathgetsingle
-
jsonpathgetmultiple
-
jsonpathcheck
-
jsonpathremove
From BOM to Launch Configuration
At the beginning of reconfiguration, BML can be used to set initial configuration attribute values to be consistent with the input BOM instance when the configurator is launched. The _bm_bom_instance
configuration system attribute is used to acquire the BOM instance as a JSON object. The BML execution returns name-value pairs in JSON to set the configuration attributes:
- The key is the configuration attribute variable name.
- The values are typically strings, but any data that can be properly converted to string is acceptable.
- If the configuration attribute is MSM or an array attribute, the value should be a JSON array of strings.
Expected Format
An unlimited number of variable and value pairs can be added, but variables cannot be duplicated.
{"<configuration variable name>":"<value>", etc.}
The following table provides Configurable Attribute examples.
Configurable Attributes |
Sample Value |
Comment |
---|---|---|
Integer Attribute |
"1" |
|
1 |
Interpreted as "1" |
|
Boolean Attribute |
"true" |
|
"false" |
||
true |
Interpreted as "true" |
|
false |
Interpreted as "false" |
|
Integer Array (or MSM) Attribute |
["1", "2", "3"] |
For array attributes, three rows exist in the array set. For MSM, menu item "1", "2", "3" are checked. |
[1, 2, 3] |
Interpreted as ["1", "2", "3"] |
|
Boolean Array Attribute |
["true", "false", "true"] |
|
[true, false, true] |
Interpreted as ["true", "false", "true"] |
Override Simple Configurable Attribute Sample
In the following example, we set the customer rating to be consistent with the membership card type, if the customer rating is not in the range that is consistent with the card type.
//-------------------------------------------------------------- // Sample BML from BOM to Launch Configuration // // Set the membership card type based on the customer rating if the current customer // rating is inconsistent with the card type // If cardType == Platinum and customerRating < 70, set customerRating = 85 // If cardType == Gold and customerRating not in [30,70), set customerRating = 50 // If cardType == Silver and customerRating not in [0, 30), set customerRating = 15 // // Input Attributes: // _bm_bom_instance: the BOM item instance in json // customerRating: an integer from 0 to 100. // // Output: // attributeOverrides, json as a name-value pair to set configuration attribute values //-------------------------------------------------------------- attributeOverrides = json(); if(isnull(_bm_bom_instance) == false){ cardTypeValue = jsonpathgetsingle(_bm_bom_instance, "$..children[?(@.variableName == 'MembershipCard')].attributes.cardType.value"); if ((cardTypeValue == "Platinum") AND (customerRating < 70)) { jsonput(attributeOverrides, "customerRating", 85); } elif (cardTypeValue == "Gold" AND (customerRating < 30 OR customerRating >= 70)) { jsonput(attributeOverrides, "customerRating", 50); } elif (cardTypeValue == "Silver" AND customerRating > 30) { jsonput(attributeOverrides, "customerRating", 15); } } return attributeOverrides;
Note the null check for _bm_bom_instance
. Unlike from configuration to BOM, _bm_bom_instance
can be null for BML to handle from BOM to configuration. Furthermore, from BOM to configuration is always invoked in the context of sales BOM.
Override Configurable Array Attributes Sample
The following is a more complicated example that sets the values of configurable array attributes. It is the reverse mapping of the previous Configurable Array Attributes Sample.
//-------------------------------------------------------------- // Sample BML from BOM to Launch Configuration // This example sets software array sets based on the enterprise software BOM items. // // Input Attributes: // _bm_bom_instance: the BOM item instance in JSON // // Output: // attrOverrides, json as a name-value pair to set configuration attribute values //-------------------------------------------------------------- attrOverrides = json(); // _bm_bom_instance might be null. It is prudent to check. if(isnull(_bm_bom_instance)) { return attrOverrides; } size = 0; children = jsonget(_bm_bom_instance, "children", "jsonarray"); if (isnull(children) == false) { size = jsonarraysize(children); } softwareTypes = jsonarray(); softwareQuantities = jsonarray(); softwareSupports = jsonarray(); // Loop through "children". No operations are performed if children do not exist // or are empty. indices = range(size); for index in indices { item = jsonarrayget(children, index, "json"); software = ""; variableName = jsonget (item, "variableName"); if (variableName == "AntiVirusItem") { software = "Enterprise Anti-Virus"; } elif (variableName == "AntiSpamItem") { software = "Enterprise Anti-Spam"; } else { continue; } quantity = jsonget(item, "quantity", "integer"); support = jsonpathgetsingle(item, "$.attributes.Support.value"); jsonarrayappend(softwareTypes, software); jsonarrayappend(softwareQuantities, quantity); jsonarrayappend(softwareSupports, support); } jsonput(attrOverrides, "softwareType", softwareTypes); jsonput(attrOverrides, "softwareQuantity", softwareQuantities); jsonput(attrOverrides, "softwareSupport", softwareSupports); // set the correct size for the array set jsonput(attrOverrides, "softwareSize", jsonarraysize(softwareTypes)); return attrOverrides;
BOM Item Definition Tree References
The BOM Item Definition is hierarchical. The “BomItemDef.ParentVariableName
” recursively points to its parent “BomItemDef's VariableName”. The BOM Item Definition hierarchy, along with its BOM Attribute Definition children, and BOM Attribute Translation grandchildren forms a BOM item definition tree.
To ease queries and migration, all BOM definition entities must include the root BOM Item Definition Variable Name:
-
BomItemDef.RootVariableName
-
BomAttributeDef.RootBomItemVarName
-
BomAttributeTranslation.RootBomItemVarName
BOM Item Mapping Tree References
The BOM Item Map and its children BOM Attribute Maps form a BOM Item Mapping Tree, based on the BOM Item Tree. A BOM Mapping Configuration rule should only reference a single BOM Item Mapping Tree.
To ease queries and migration, all BOM Mapping entities must include the BOM Mapping rule location “productFamilyVarName:productLineVarName:modelVarName:configRuleVarName
”, in the following Data Table columns:
-
BomItemMap.ParenBomMapVarName
-
BomAttrMap.RootBomMapVarName
In the rare case where two Configuration Models use the same BOM item mappings, as defined in the Data Tables, the wildcard rule location can be used, in the format of *:configRuleVarName
. Exact BOM Mapping rule locations have a higher precedent over wildcard rule locations. A BOM Mapping Configuration rule attempts to load its BOM Item Mapping Tree that uses an exact rule location first. If there are no BOM Item Mapping Data Table records matching the exact rule location, will the BOM Mapping Configuration rule attempt to load a BOM Item Mapping Tree that uses a wildcard rule location. This means that a BOM Mapping Configuration rule loads its BOM Item Mapping Tree using either the exact rule location or the wildcard rule location, but it never loads both locations.
BOM Mapping Configurable Array Attribute Restrictions
The following restrictions on configurable array attribute mapping are enforced, primarily to maintain one-to-one mapping between a row in the array set and a BOM item.
Sequence |
Mapping |
Rule |
Sample Validation Error Message |
---|---|---|---|
1 |
BOM Item Mapping |
A BOM item mapping can use more than one configurable array attribute, but they must be all from the same array set. |
The following example is illegal:
The BOM item mapping BOM1 is mapped from the following configuration array attributes in different array sets: Drink, Car. |
2 |
BOM Item Mapping |
A configurable array attribute should not be used more than once in a single BOM item mapping. |
The following example is illegal:
The configuration attribute DrinkType is used more than once in the BOM item mapping BOM1. |
3 |
BOM Item Mapping |
If two BOM item mappings use configurable array attributes from the same array set, the array attributes must be the same in both BOM item mappings. |
The following example is illegal: BOM1|drinkType=Coffee|drinkSize=Medium BOM2|drinkType=Tea BOM item mapping BOM1 and BOM2 must be mapped from same configuration array attributes from the same array set. |
4 |
BOM Item Mapping |
If two BOM item mappings use configurable array attributes, the combination of array attributes and values must be unique. In other words, the same combination of configurable array attributes and values cannot be used to map to two different BOM items. |
The following example is illegal: BOM1|drinkType=Coffee|drinkSize=Medium BOM2|drinkType=Coffee|drinkSize=Medium BOM item mapping BOM1 and BOM2 are mapped from exactly same values for configuration array attributes. |
5 |
BOM Item Mapping |
If a BOM item mapping uses a configuration array attribute, it is illegal for one of its hierarchical parent BOM item mapping (including parent, grandparent, ...) to use configurable array attributes (whether or not from the same array set). |
The following example is illegal: BOM1|drinkType=Coffee BOM2 (parent: BOM1) drinkSize=Medium Configuration array attributes cannot be used in nested BOM item mapping. Configuration attribute drinkSize is an array attribute, but BOM item mapping coffeeMapping, a hierarchical parent, is already mapped with array attribute(s) drinkType. |
6 |
BOM Attribute Mapping |
If an attribute mapping uses a configurable array attribute, its containing BOM item mapping must use at least one configurable array attributes. |
The following example is illegal:
Cannot map to an array type configuration attribute drinkType as the parent BOM item mapping is not mapped to an array type attribute. |
7 |
BOM Attribute Mapping |
If an attribute mapping uses a configurable array attribute, the containing BOM item mapping must use one or more configurable array attributes from the same array set. |
The following example is illegal:
Cannot map to a configuration attribute in the array set Car as its parent BOM item mapping maps to an attribute in a different array set Dessert. |
8 |
BOM Attribute Mapping |
Attribute mapping cannot use the same configurable array attributes that are used in its containing BOM item mapping. |
The following example is illegal: BOM1|drinkType=Coffee (attribute mapping: drinkType=Coffee) Cannot map to the same array attribute drinkType as used in the parent BOM item mapping. |
9 |
BOM Attribute Mapping |
If configurable array attributes are used in BOM attribute mappings, the same array attributes should be used in BOM attribute mappings of all BOM item mappings that use the same configurable array set. This is similar to Rule (3) of BOM item mapping. |
The following example is illegal: BOM1|drinkType=Coffee (attribute mapping: drinkSize=Medium) BOM2|drinkType=Tea (no attribute mapping) Validation error will be added in a future release. |
Notes
Note: When a BOM Mapping rule updates an attribute for a sub-level model in a multi-level BOM, a reference is created that records the relationship to the originating model. Since each item will only retain the current and one previous reference, this may cause unexpected behavior when BOM hierarchies with four or more levels are reconfigured. If a model has two or more parent models with their own BOM Mapping rules that apply attribute changes before creating a transaction, Commerce attribute changes for that item will revert to the last saved Configuration if the multi-level BOM is reconfigured.