Adding Options to a Bundle
This adds one or more Options Products to a Bundle product.
If the Quote-to-Cash (QTC) profile is set to split, the system creates two separate ProductConfiguration records for Configuration and Pricing. You must invoke the addOptions API separately for each cart ID to add the option successfully to both configurations. For more information, see Adding Options to Split (Smart) Cart Configurations.
|
API |
Signature |
|---|---|
| addOptions |
webService static Apttus_CPQApi.CPQ.AddOptionsResponseDO addOptions(Id cartId, Integer lineNumber, List selectedOptions) |
|
Request Parameters | ||
|---|---|---|
|
Name |
Type |
Description |
| CartID | ID |
The cart ID |
| lineNumber | Integer |
Line Number of the Bundle Product |
| selectedOptions | List<Apttus_CPQApi.CPQ.SelectedOptionDO> |
List of Options |
|
Data Object - Apttus_CPQApi.CPQ.SelectedOptionDO | ||
|---|---|---|
|
Field |
Type |
Description |
| AttributeValues | List |
List of attributes values. |
| Comments | String |
Comments associated with the record. |
| ComponentId | ID |
Id of the component. |
| ComponentProductId | ID |
Id of the component product. |
| CustomData | Apttus_Config2__LineItem__c |
The values to be set for the custom fields in the CustomFields List |
| CustomFields | List<String> |
List of Custom Field’s API Name |
| EndDate | Date |
The end date. |
| Quantity | Decimal |
The option quantity. |
| SellingTerm | Decimal |
The option selling term. |
| SourceId | ID |
ID of the source option. |
| StartDate | Date |
The start date. You should ensure you use the correct date format. |
Code Sample
Using the sample below you can dynamically add options to a bundled product that the user selects in the cart line item. For example, if the user selects a bundled product, Laptop, in the cart line item you can fetch the configured options for that selected product using the addoptions API. In the sample below, for a selected product you initially fetch the productID. Using the retrieve option groups API getOptionGroupsForPriceListProduct, you can check whether the selected product has option groups associated. If an option group is associated, fetch the option components and create a list comprising the CPQ.SelectedOptionDO. Invoke the addoptions API and pass the cartID, productID, and the list CPQ.SelectedOptionDO.
public void addOptions()
{
string productName='';
Integer lineNumber = 0;
for(LineItemWrapperClass selProdWrap: lstWrapItems)
{
//For a selected bundled product from a cart line item execute the loop below
if(selProdWrap.selected)
{
productName = selProdWrap.ProductName;
lineNumber = Integer.valueOf(selProdWrap.LineNumber);
break;
}
}
//If no product is selected, show an appropriate error message
if(String.isBlank(productName))
{
ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.info, 'Please select at least one Product.'));
}
else
{
List<Apttus_CPQApi.CPQ.SelectedOptionDO> selectedOptDOList = new List<Apttus_CPQApi.CPQ.SelectedOptionDO>();
//For the selected product fetch the product ID
List<Product2> productId = [SELECT Id FROM Product2 WHERE Name = :productName LIMIT 1];
//Execute the getoptionGroups API to fetch the options with option groups
Apttus_CPQApi.CPQ.ProductOptionGroupSearchResultDO result = Apttus_CPQApi.CPQWebService.getOptionGroupsForPriceListProduct(priceListId, productId[0].Id);
//If the selected product has option groups execute the loop below
if(result.HasOptionGroups)
{
List<Apttus_CPQApi.CPQ.ProductOptionGroupDO> prodOptGrpDOList = result.OptionGroups;
for(Apttus_CPQApi.CPQ.ProductOptionGroupDO prodOptGrpDO : prodOptGrpDOList)
{
//For an option group if a product has option components such as quantity execute the loop below
if(prodOptGrpDO.HasOptionComponents)
{
List<Apttus_CPQApi.CPQ.ProductOptionComponentDO> prodOptCompDOList = new List<Apttus_CPQApi.CPQ.ProductOptionComponentDO>();
prodOptCompDOList = prodOptGrpDO.OptionComponents;
//Fetch all the option components for a particular option group.
for(Apttus_CPQApi.CPQ.ProductOptionComponentDO prodOptCompDO :prodOptCompDOList )
{
Apttus_CPQApi.CPQ.SelectedOptionDO selectedOptDO = new Apttus_CPQApi.CPQ.SelectedOptionDO();
selectedOptDO.ComponentId = prodOptCompDO.ComponentId;
selectedOptDO.ComponentProductId = prodOptCompDO.ComponentProductId;
selectedOptDO.Quantity = 1;
selectedOptDOList.add(selectedOptDO);
}
}
}
}
//Invoke the addOptions API and pass the cartID, selected product line number, and the Option List retrieved from the getoptiongroups API
Apttus_CPQApi.CPQ.AddOptionsResponseDO addOptRespDO = Apttus_CPQApi.CPQWebService.addOptions(cartId, lineNumber, selectedOptDOList);
}
}
Adding Options to Split (Smart) Cart Configurations
When working with split carts, follow these steps:
- Query the Quote/Proposal to retrieve both the Config Cart ID (
Apttus_Config2__PrimaryConfigurationId__c) and the Pricing Cart ID (Apttus_Config2__PricingConfigurationId__c). - Call
addOptionswith the Config Cart ID, passing the samelineNumberandselectedOptions. - Call
addOptionswith the Pricing Cart ID, passing the samelineNumberandselectedOptions.
Code Sample: Adding Options to a Split Cart
/**
* Adds options to a bundle on a split (smart) cart.
* For split carts, addOptions must be called separately
* for both Config and Pricing configurations.
*/
public void addOptionsToSplitCart(Id quoteId, Integer lineNumber,
List<Apttus_CPQApi.CPQ.SelectedOptionDO> selectedOptions) {
// Step 1: Retrieve both Cart IDs from the Quote
Apttus_Proposal__Proposal__c quote = [
SELECT Apttus_QPConfig__PrimaryConfigurationId__c,
Apttus_QPConfig__PricingConfigurationId__c
FROM Apttus_Proposal__Proposal__c
WHERE Id = :quoteId
LIMIT 1
];
Id configCartId = quote.Apttus_QPConfig__PrimaryConfigurationId__c;
Id pricingCartId = quote.Apttus_QPConfig__PricingConfigurationId__c;
// Step 2: Add options to the Config Cart
Apttus_CPQApi.CPQ.AddOptionsResponseDO configResponse =
Apttus_CPQApi.CPQWebService.addOptions(configCartId, lineNumber, selectedOptions);
// Step 3: Add options to the Pricing Cart
Apttus_CPQApi.CPQ.AddOptionsResponseDO pricingResponse =
Apttus_CPQApi.CPQWebService.addOptions(pricingCartId, lineNumber, selectedOptions);
}
Integration Details
Use the following information in your integrations with CPQ Web Services API. Refer to Integrating Conga with External Systems for information on how to get started.
Response/Request XML
Example Request<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:cpq="http://soap.sforce.com/schemas/class/Apttus_CPQApi/CPQWebService"
xmlns:cpq1="http://soap.sforce.com/schemas/class/Apttus_CPQApi/CPQ">
<soapenv:Header>
<cpq:SessionHeader>
<cpq:sessionId>00DZ000000NAEIA!ASAAQHmIRqgn4R9Oi1yQjWTIVk4UZmsDe_.eK0Z9z6qLij7Tu.L_Yo8dRA_p8OmhKMeRs4uzCZTadIgQ9fEbDKciXEQYRyaA</cpq:sessionId>
</cpq:SessionHeader>
</soapenv:Header>
<soapenv:Body>
<cpq:addOptions>
<cpq:cartId>a1OZ0000002ZQVZ</cpq:cartId>
<cpq:lineNumber>1</cpq:lineNumber>
<cpq:selectedOptions>
<cpq1:Comments>Some comment</cpq1:Comments>
<cpq1:ComponentId>a1YZ0000003pIGM</cpq1:ComponentId>
<cpq1:ComponentProductId>01tZ0000004lUYI</cpq1:ComponentProductId>
<cpq1:EndDate>2020-06-30</cpq1:EndDate>
<cpq1:Quantity>5</cpq1:Quantity>
<cpq1:SellingTerm>1</cpq1:SellingTerm>
<cpq1:StartDate>2020-05-28</cpq1:StartDate>
</cpq:selectedOptions>
</cpq:addOptions>
</soapenv:Body>
</soapenv:Envelope>
Example Response
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns="http://soap.sforce.com/schemas/class/Apttus_CPQApi/CPQWebService"
xmlns:AddOptionsResponseDO="http://soap.sforce.com/schemas/class/Apttus_CPQApi/CPQ"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<addOptionsResponse>
<result>
<AddOptionsResponseDO:addedOptionLineItems xsi:type="Apttus_Config2__LineItem__c">
<Id>a19Z0000006sPeBIAU</Id>
<Apttus_Config2__AddedBy__c>User</Apttus_Config2__AddedBy__c>
<Apttus_Config2__AllowManualAdjustment__c>true</Apttus_Config2__AllowManualAdjustment__c>
<Apttus_Config2__Comments__c>Some comment</Apttus_Config2__Comments__c>
<Apttus_Config2__ConfigStatus__c>NA</Apttus_Config2__ConfigStatus__c>
<Apttus_Config2__ConfigurationId__c>a1OZ0000002ZQVZMA4</Apttus_Config2__ConfigurationId__c>
<Apttus_Config2__ConstraintCheckStatus__c>NA</Apttus_Config2__ConstraintCheckStatus__c>
<Apttus_Config2__Customizable__c>false</Apttus_Config2__Customizable__c>
<Apttus_Config2__Description__c>Auto_API_OptionProduct1</Apttus_Config2__Description__c>
<Apttus_Config2__EndDate__c>2020-06-30</Apttus_Config2__EndDate__c>
<Apttus_Config2__HasAttributes__c>false</Apttus_Config2__HasAttributes__c>
<Apttus_Config2__HasOptions__c>false</Apttus_Config2__HasOptions__c>
<Apttus_Config2__IsPrimaryLine__c>true</Apttus_Config2__IsPrimaryLine__c>
<Apttus_Config2__IsQuantityModifiable__c>false</Apttus_Config2__IsQuantityModifiable__c>
<Apttus_Config2__ItemSequence__c>2</Apttus_Config2__ItemSequence__c>
<Apttus_Config2__LineNumber__c>1</Apttus_Config2__LineNumber__c>
<Apttus_Config2__LineType__c>Option</Apttus_Config2__LineType__c>
<Apttus_Config2__OptionId__c>01tZ0000004lUYIIA2</Apttus_Config2__OptionId__c>
<Apttus_Config2__ParentBundleNumber__c>1</Apttus_Config2__ParentBundleNumber__c>
<Apttus_Config2__PriceListId__c>a1DZ0000002mg5nMAA</Apttus_Config2__PriceListId__c>
<Apttus_Config2__PricingStatus__c>Pending</Apttus_Config2__PricingStatus__c>
<Apttus_Config2__PrimaryLineNumber__c>4</Apttus_Config2__PrimaryLineNumber__c>
<Apttus_Config2__ProductId__c>01tZ0000004lUXUIA2</Apttus_Config2__ProductId__c>
<Apttus_Config2__ProductOptionId__c>a1YZ0000003pIGMMA2</Apttus_Config2__ProductOptionId__c>
<Apttus_Config2__ProductVersion__c>1.00</Apttus_Config2__ProductVersion__c>
<Apttus_Config2__Quantity__c>5</Apttus_Config2__Quantity__c>
<Apttus_Config2__SellingTerm__c>1</Apttus_Config2__SellingTerm__c>
<Apttus_Config2__StartDate__c>2020-05-28</Apttus_Config2__StartDate__c>
<Apttus_Config2__Uom__c>Each</Apttus_Config2__Uom__c>
</AddOptionsResponseDO:addedOptionLineItems>
</result>
</addOptionsResponse>
</soapenv:Body>
</soapenv:Envelope>
