Appendix D: Understand the Add to Cart BML – Customized Integrations (19C and Earlier)
Users with legacy integration sites (19C and earlier) who have previously customized their Add to Cart BML need to modify their BML to include site-specific reference file locations.
The following provides the Add to Cart BML for Customized Integrations 19C and Earlier:
// Rec Item Properties
part = String[1];
quantity = String[1];
price = String[1];
selected = String[1];
sparepaths = String[1];
sparepaths[0] = "/configuration/configureResponse/spare/rule/item/part";
sparepaths[1] = "/configuration/configureResponse/spare/rule/item/quantity";
sparepaths[2] = "/configuration/configureResponse/spare/rule/item/price";
sparepaths[3] = "/configuration/configureResponse/spare/rule/item/selected";
// BOM Item Properties
bomItem = String[1];
bomItem[0] = "/configuration/configureResponse/bomItem";
// Model/Price Properties
models = string[1];
configIdSearch = string[1];
currpath = String[1];
totalPrices = string[1];
bomTotals = string[1];
models[0] = "/configuration/configureResponse/item/model";
configIdSearch[0] = "/configuration/configureResponse/item/@configurationId";
currpath[0] = "/configuration/configureResponse/attributes/attribute[@_variableName='currencyCode']/value";
totalPrices[0] = "/configuration/configureResponse/price/totalPrice";
bomTotals[0] = "/configuration/configureResponse/price/bomPrice";
priceTotal = 0.0;
baseModelPrice = 0.0;
recurringSubtotal = 0.0;
// Extract data from configXML
outputModel = readxmlsingle(configXML, models);
outputConfigIds = readxmlsingle(configXML, configIdSearch);
currXML = readxmlsingle(configXML, currpath);
currency = get(currXML, currpath[0]);
outputPrices = readxmlsingle(configXML, totalPrices);
bomPrices = readxmlsingle(configXML, bomTotals);
output1 = readxmlmultiple(configXML, sparepaths);
bomItemXMLDict = readxmlsingle(configXML, bomItem);
bomItemString = get(bomItemXMLDict, "/configuration/configureResponse/bomItem");
payloadTemplate = urldatabyget("https://cpq-046.us.example.com/bmfsweb/slc10xgj/image/CommerceCloud/AddToCartPayload-Cloud.txt", "", "");
model1 = "";
totalPrice1 = "";
// Get Model data
for model in models {
model1 = get(outputModel, model);
}
// Get Price data
for totalPrice in totalPrices {
totalPrice1 = get(outputPrices, totalPrice);
totalPrice0 = replace(totalPrice1, ",", "");
if (isnumber(substring(totalPrice0, 1))) {
totalPrice2 = getcurrencyvalue(totalPrice1, currency);
priceTotal = priceTotal + totalPrice2;
}
}
baseModelPrice = priceTotal;
// Add BOM total price
if (containskey(bomPrices, bomTotals[0])) {
for bomPrice in bomTotals {
bomTotal = get(bomPrices, bomPrice);
bomTotalReplace = replace(bomTotal, ",", "");
if (isnumber(substring(bomTotalReplace, 1))) {
bomTotalPrice = getcurrencyvalue(bomTotal, currency);
priceTotal = bomTotalPrice + priceTotal;
}
}
}
// Get ConfigID
configId = "";
for id in configIdSearch {
configId = get(outputConfigIds, id);
}
// Get Recommended Items
for sparepath in sparepaths {
if (find(sparepath, "part") < > -1) {
part = get(output1, sparepath);
}
elif(find(sparepath, "quantity") < > -1) {
quantity = get(output1, sparepath);
}
elif(find(sparepath, "price") < > -1) {
price = get(output1, sparepath);
}
elif(find(sparepath, "selected") < > -1) {
selected = get(output1, sparepath);
}
}
// Format Rec Items payload
recItemList = "";
if (isnull(part)) {
print("No Recommended Items");
} else {
recItems = sizeofarray(part);
recItemsInt = integer[recItems];
i = 0;
for recItem in recItemsInt {
if (selected[i] == "true") {
//recurring price from parts BMQL
part_num = part[i];
partCustomFields = bmql("SELECT part_number, custom_field5, custom_field4, custom_field6, custom_field8 FROM _parts WHERE part_number = $part_num");
recItemPayloadTemplate = urldatabyget("https://cpq-046.us.example.com/bmfsweb/slc10xgj/image/CommerceCloud/Recommended_Items_Payload-Cloud.txt", "", "");
recItemPayloadTemplate = replace(recItemPayloadTemplate, "{{quantity}}", quantity[i]);
recItemPayloadTemplate = replace(recItemPayloadTemplate, "{{part}}", part[i]);
for each in partCustomFields {
if (get(each, "custom_field8") == "Recurring") {
recItemPayloadTemplate = replace(recItemPayloadTemplate, "{{pricePeriod}}", get(each, "custom_field4"));
recItemPayloadTemplate = replace(recItemPayloadTemplate, "{{recurringPrice}}", get(each, "custom_field5"));
recItemPayloadTemplate = replace(recItemPayloadTemplate, "{{duration}}", get(each, "custom_field6"));
//recurringSubtotal = recurringSubtotal + get(each, "custom_field5");
} else {
childPayloadJson = json(recItemPayloadTemplate);
jsonremove(childPayloadJson, "recurringCharge");
recItemPayloadTemplate = jsontostr(childPayloadJson);
}
}
//remove region specific formatting for price
sPrice0 = substring(price[i], 1);
sPrice0 = replace(sPrice0, ",", "");
if (isnumber(sPrice0)) {
priceTotal = priceTotal + atof(sPrice0);
recItemPayloadTemplate = replace(recItemPayloadTemplate, "{{price}}", sPrice0);
} else {
recItemPayloadTemplate = replace(recItemPayloadTemplate, "{{price}}", "0");
}
if (recItemList == "") {
recItemList = recItemPayloadTemplate;
} else {
recItemList = recItemList + "," + recItemPayloadTemplate;
}
}
i = i + 1;
}
}
// Get the BOM Items
if (isnull(bomItemString)) {
print "No BOM Items";
bomItemString = "";
payloadTemplate = replace(payloadTemplate, "{{BomItems}}", bomItemString);
} else {
// Get part numbers for each BOM item, convert to string array for bmql
bomJson = json(bomItemString);
// Remove extraneous BOM fields (may have to revert if CC was expecting to use them)
jsonpathremove(bomJson, "$..variableName");
jsonpathremove(bomJson, "$..definition");
jsonpathremove(bomJson, "$..category");
// Replacing all 0 prices with actual number 0
bomPriceArray = jsonpathgetmultiple(bomJson, "$.._price_unit_price_each");
replace_lookup = boolean[];
bomPricesString = jsonarraytostr(bomPriceArray);
bomPricesString = replace(replace(replace(bomPricesString, "\"", ""), "[", ""), "]", "");
bomPricesStringArray = split(bomPricesString, ",");
i = 0;
for each in bomPricesStringArray {
append(replace_lookup, isnumber(each));
i = i + 1;
}
i = 0;
for each in replace_lookup {
if (i == 0 and each == false) {
jsonpathset(bomJson, "$.fields._price_unit_price_each", "0");
}
elif(each == false) {
str = "$.children[" + string(i - 1) + "].fields._price_unit_price_each";
jsonpathset(bomJson, str, "0");
}
i = i + 1;
}
bomItemString = jsontostr(bomJson);
bomPartsArray = jsonpathgetmultiple(bomJson, "$..partNumber");
bomPartsString = jsonarraytostr(bomPartsArray);
bomPartsString = replace(replace(replace(bomPartsString, "\"", ""), "[", ""), "]", "");
bomPartsStringArray = split(bomPartsString, ",");
bomParts = bmql("SELECT part_number, custom_field5, custom_field4, custom_field6, custom_field8 FROM _parts WHERE part_number IN $bomPartsStringArray");
// Get path for each part, add recurringCharge to them all
for each in bomParts {
partField = "\"partNumber\":\"" + get(each, "part_number") + "\",";
recurringTemplate = "\"recurringCharge\":{ \"amount\":,\"frequency\":,\"duration\":},";
if (get(each, "custom_field8") == "Recurring") {
recurringTemplate = replace(recurringTemplate, "frequency\":", "frequency\":\"" + get(each, "custom_field4") + "\"");
recurringTemplate = replace(recurringTemplate, "amount\":", "amount\":\"" + get(each, "custom_field5") + "\"");
recurringTemplate = replace(recurringTemplate, "duration\":", "duration\":\"" + get(each, "custom_field6") + "\"");
} else {
recurringTemplate = "";
}
bomItemString = replace(bomItemString, partField, partField + recurringTemplate);
}
// Unflatten
bomItemString = replace(bomItemString, "\"partNumber\":", "\"catalogRefId\":");
bomItemString = replace(bomItemString, "On Request", "0"); // This may only fix English users
bomJson = convertbomtohier(json(bomItemString));
payloadTemplate = replace(payloadTemplate, "{{BomItems}}", jsontostr(bomJson));
}
// Format main template with subcomponents and properties
payloadTemplate = replace(payloadTemplate, "{{commerceItemId}}", "");
payloadTemplate = replace(payloadTemplate, "{{ConfigId}}", configId);
payloadTemplate = replace(payloadTemplate, "{{model}}", model1);
payloadTemplate = replace(payloadTemplate, "{{totalPrice}}", string(priceTotal));
payloadTemplate = replace(payloadTemplate, "{{basePrice}}", string(baseModelPrice));
payloadTemplate = replace(payloadTemplate, "{{currency}}", currency);
payloadTemplate = replace(payloadTemplate, "{{ChildItems}}", recItemList);
return payloadTemplate;