Configuration Load Rule Executor API

The Configuration Load Rule Executor API invokes all the load event product rules for the specified product. When configuring a nested bundle, set the parentProduct property to the parent product to inherit configuration attributes on the nested bundle.

Required Editions
Available in: Salesforce CPQ Spring ’17 and later
Formats

JSON, Apex

HTTP Method

PATCH

Authentication

Authorization: Bearer token

REQUEST

NameType Description
uidStringRequiredID of the Product2 record .
quoteQuoteModelRequiredCorresponds directly to SBQQ__Quote__c .
configurationConfigurationModelOptionalThe product’s configuration data. Only required if you have an existing configuration from product actions or a previous run-through.
lineItemKeyIntegerOptionalUsed to identify upgrade options in amendment flows.
dynamicOptionSkusList<String>OptionalA list of dynamic option SKUs. Sourced from product options selected in dynamic features.
parentProductProductModelOptionalThe parent product for a nested bundle. Used to inherit configuration attributes from the parent product.

RESPONSE

TypeDescription  
ProductModelRepresentation of product data. See CPQ Models.  

REST Examples 

1curl "https://*yourInstance*.salesforce.com/services/apexrest/SBQQ/ServiceRouter?loader=SBQQ.ConfigAPI.LoadRuleExecutor&uid=a0x5C000000G1CV" \
2    -H "Content-Type: application/json" \
3    -H "Authorization: Bearer YOURAUTHORIZATIONTOKEN" \
4    -X PATCH \
5    -d "@loadRuleContext.json"

The example request body loadRuleContext.json file for running load product rules. This example context value is a JSON-formatted string of the quote model and the configuration model.

1{"context":"{\"quote\":{\"record\":{\"attributes\":{\"type\":\"SBQQ__Quote__c\"},
2     \"Account__c\":\"0014M00001mfEYT\",
3     \"Id\":\"a0c4M00000eE9SgQAK\",
4     \"PricebookId__c\":\"01s61000002xO1h\",
5     \"CurrencyIsoCode\":\"USD\"}},
6     \"configuration\":{\"validationMessages\":[],
7     \"priceEditable\":false,
8     \"optionData\":{\"attributes\":{\"type\":\"SBQQ__ProductOption__c\"}},
9     \"optionConfigurations\":[{\"validationMessages\":[],
10     \"priceEditable\":false,
11     \"optionId\":\"a0U4M00000GJagGUAT\",
12     \"optionData\":{\"attributes\":{\"type\":\"SBQQ__ProductOption__c\",
13     \"url\":\"\/services\/data\/v48.0\/sobjects\/ProductOption__c\/a0U4M00000GJagGUAT\"},
14     \"ConfiguredSKU__c\":\"01t4M000003ru2OQAQ\",
15     \"Id\":\"a0U4M00000GJagGUAT\",
16     \"OwnerId\":\"0056100000148O6AAI\",
17     \"IsDeleted\":false,
18     \"CurrencyIsoCode\":\"USD\",
19     \"SystemModstamp\":\"2020-03-10T20:47:39.000+0000\",
20     \"AppliedImmediately__c\":false,
21     \"Bundled__c\":false,
22     \"DiscountedByPackage__c\":false,
23     \"Number__c\":1,
24     \"OptionalSKU__c\":\"01t4M000003ru2PQAQ\",
25     \"PriceEditable__c\":\"No\",
26     \"ProductConfigurationType__c\":\"Allowed\",
27     \"ProductName__c\":\"W-7145106 Bundle - Nested Option - Level 1 Product #1\",
28     \"QuantityEditable__c\":true,
29     \"Quantity__c\":1,
30     \"Required__c\":false,
31     \"Selected__c\":true,
32     \"System__c\":false,
33     \"Type__c\":\"Component\",
34     \"UpliftedByPackage__c\":false,
35     \"CanOrderSeparately__c\":false},
36     \"optionConfigurations\":[],
37     \"isUpgrade\":false,
38     \"isDynamicOption\":false,
39     \"configuredProductId\":\"01t4M000003ru2PQAQ\",
40     \"configured\":false,
41     \"configurationEntered\":false,
42     \"configurationData\":{\"attributes\":{\"type\":\"SBQQ__ProductOption__c\"}},
43     \"changedByProductActions\":false}],
44     \"isUpgrade\":false,
45     \"isDynamicOption\":false,
46     \"configuredProductId\":\"01t4M000003ru2OQAQ\",
47     \"configured\":false,
48     \"configurationEntered\":false,
49     \"configurationData\":{\"attributes\":{\"type\":\"SBQQ__ProductOption__c\"}},
50     \"changedByProductActions\":false}}"}

Example response body returning product data. The actual response is a JSON formatted string.

1{
2  "record": {
3    "attributes": {
4      "type": "Product2",
5      "url": "/services/data/v42.0/sobjects/Product2/01tA0000005uzfZ"
6    },
7    "Id": "01tA0000005uzfZ",
8    "Name": "Apple"
9  }
10  "options": [],
11  "features": [],
12  "configuration": {}
13}

APEX Examples 

Before saving the LoadRuleRunner example class, make sure that the CPQ Models classes are added as individual Apex classes in your Salesforce org.

1public with sharing class LoadRuleRunner {
2    public ProductModel load(
3        Id productId,
4        QuoteModel quote,
5        Integer lineItemKey,
6        List<String> dynamicOptionSkus,
7        ConfigurationModel configuration,
8        ProductModel parentProduct) {
9        
10        LoadRuleRunnerContext ctx = new LoadRuleRunnerContext(
11            quote,
12            lineItemKey,
13            dynamicOptionSkus,
14            configuration,
15            parentProduct);
16        String productJSON = SBQQ.ServiceRouter.load('SBQQ.ConfigAPI.LoadRuleExecutor', productId, JSON.serialize(ctx));
17        return (ProductModel) JSON.deserialize(productJSON, ProductModel.class);
18    }
19
20    private class LoadRuleRunnerContext {
21        private QuoteModel quote;
22        private ProductModel parentProduct;
23        private Integer lineItemKey;
24        private List<String> dynamicOptionSkus;
25        public ConfigurationModel configuration;
26
27        public LoadRuleRunnerContext(
28            QuoteModel quote,
29            Integer lineItemKey,
30            List<String> dynamicOptionSkus,
31            ConfigurationModel configuration,
32            ProductModel parentProduct) {
33            
34            this.quote = quote;
35            this.parentProduct = parentProduct;
36            this.lineItemKey = lineItemKey;
37            this.dynamicOptionSkus = dynamicOptionSkus;
38            this.configuration = configuration;
39        }
40    }
41}

To demonstrate usage of the LoadRuleRunner class, run the following code in anonymous Apex.

1QuoteModel quote; //Use Read, Add Products, or Calculate APIs to obtain a QuoteModel
2ProductModel product; //Use Read Product or Configuration Loader API to obtain a ProductModel
3
4LoadRuleRunner runner = new LoadRuleRunner();
5ProductModel product = runner.load('a0x5C000000G1CV', quote, null, null, product.configuration, null);
6System.debug(product);