Configuration Validator API

The Configuration Validator API runs selection, validation, and alert product rules and configurator-scoped price rules against the input configuration model and returns an updated configuration model.

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.
configurationConfigurationModelRequiredThe product’s configuration data.
eventStringRequiredEvent type of product and price rules to run. Options are “Load”, “Save”, “Edit”, and “Always”.
upgradedAssetIdStringOptionalAsset ID when upgrading a bundle.

RESPONSE

TypeDescription  
ConfigurationModelThe product’s configuration data. This is the same Configuration Model that was passed in the request, but the data will be changed based on Product Actions from Product and Price Rules that ran. See CPQ Models.  

REST Examples 

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

The example request body configValidatorContext.json file for running product and price rules. This example context value is a JSON-formatted string of the quote model, configuration model, and event type.

1{"context":"{\"quote\":{\"record\":{\"attributes\":{\"type\":\"SBQQ__Quote__c\"},
2    \"Account__c\":\"0012F00000ayBPwQAM\",
3    \"Id\":\"a0z2F000000xGLpQAM\",
4    \"PricebookId__c\":\"01s2F0000011yApQAI\",
5    \"CurrencyIsoCode\":\"USD\"}},
6    \"configuration\":{\"validationMessages\":[],
7    \"priceEditable\":false,
8    \"optionData\":{\"attributes\":{\"type\":\"SBQQ__ProductOption__c\"}},
9    \"optionConfigurations\":[{\"validationMessages\":[],
10    \"priceEditable\":false,
11    \"optionId\":\"a0o2F000001Yi4JQAS\",
12    \"optionData\":{\"attributes\":{\"type\":\"SBQQ__ProductOption__c\",
13    \"url\":\"\/services\/data\/v48.0\/sobjects\/ProductOption__c\/a0o2F000001Yi4JQAS\"},
14    \"ConfiguredSKU__c\":\"01t2F000004XoPLQA0\",
15    \"Id\":\"a0o2F000001Yi4JQAS\",
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\":\"Nested Option 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\":\"01t2F000004XoPLQA0\",
40    \"configured\":false,
41    \"configurationEntered\":false,
42    \"configurationData\":{\"attributes\":{\"type\":\"SBQQ__ProductOption__c\"}},
43    \"changedByProductActions\":false}],
44    \"isUpgrade\":false,
45    \"isDynamicOption\":false,
46    \"configuredProductId\":\"01t2F000004XoPLQA0\",
47    \"configured\":false,
48    \"configurationEntered\":false,
49    \"configurationData\":{\"attributes\":{\"type\":\"SBQQ__ProductOption__c\"}},
50    \"changedByProductActions\":false},
51    \"event\":\"Edit\"}"}

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

1{
2    "validationMessages": ["Incorrect quantity for Product A"],
3    "priceEditable": false,
4    "optionId": null,
5    "optionData": {
6         "attributes": {
7             "type": "SBQQ_ProductOption_c"
8         }
9    },
10    "optionConfigurations": [],
11    "listPrice": null,
12    "isUpgrade": false,
13    "isDynamicOption": false,
14    "inheritedConfigurationData": null,
15    "hiddenOptionIds": null,
16    "dynamicOptionKey": null,
17    "disabledOptionIds": null,
18    "configuredProductId": "01t3D000005Th8oQAC",
19    "configured": false,
20    "configurationData": {
21        "attributes": {
22            "type": "SBQQ_ProductOption_c"
23        },
24        "SBQQ_UnitPrice_c": null
25    },
26    "changedByProductActions": false
27}

APEX Examples 

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

1public with sharing class ConfigValidator {
2    public ConfigurationModel load(
3        Id productId,
4        QuoteModel quote,
5        ConfigurationModel configuration,
6        String event,
7        String upgradedAssetId) {
8    
9        ValidatorContext ctx = new ValidatorContext(
10            quote,
11            configuration,
12            event,
13            upgradedAssetId);
14        String configJSON = SBQQ.ServiceRouter.load('SBQQ.ConfigAPI.ConfigurationValidator', productId, JSON.serialize(ctx));
15        return (ConfigurationModel) JSON.deserialize(configJSON, ConfigurationModel.class);
16    }
17    
18    private class ValidatorContext {
19        private QuoteModel quote;
20        private ConfigurationModel configuration;
21        private String event;
22        private String upgradedAssetId;
23    
24        public ValidatorContext(
25            QuoteModel quote,
26            ConfigurationModel configuration,
27            String event,
28            String upgradedAssetId) {
29    
30            this.quote = quote;
31            this.configuration = configuration;
32            this.event = event;
33            this.upgradedAssetId = upgradedAssetId;
34        }
35    }
36}

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

1QuoteModel quote; //Use Read, Add Products, or Calculate APIs to obtain a QuoteModel
2     ProductModel product; //Use Read Product or Configuration Loader API to obtain a ProductModel
3     
4     ConfigValidator validator = new ConfigValidator();
5     ConfigurationModel config = validator.load('01t2F000004XoPLQA0', quote, product.configuration, 'Edit', null);
6     System.debug(config);