Scenario: I built a custom ApexREST Endpoint that our eCommerce team is going to call to create Opportunities and Zuora Quotes/Quote Charges in Salesforce. The code successfully creates a zQuote in memory, then passes the zQuote Data to the zqu.Quote.createNewInstance() class to create the quote correctly. After we build and save the quote, I then build a list of chargeGroups using zqu.zQuoteUtil.getChargeGroup(Quote_Id,RatePlan_Id), and add them to the quote using zqu.zQuoteUtil.addChargeGroups to add the list. What that leaves me with is a Quote, with Quote Rate Plans and Quote Rate Plan Charges. I want to run this newly created quote and related child Rate Plans/Charges through all of our Zuora Rules Engine rules. We have rules that are designed to add additional rate plans based on the rate plans that are already on the quote, as well as rules to set discounts and special prices. So, I found the RulesEngine class which is supposed to be for running rules programmatically. I followed the documentation and the example code provided in the RulesEngine Class documentation. The response.getMessages() is returning the messages for the rules I expected to run, so it's finding the rules, the response.isSuccess() is returning TRUE, but the rules don't appear to be committing any changes to the quote or related charges. The rules should be adding an additional product, and discounting a product. However, when I look at the quote in Salesforce, I don't see those Charges listed in the related lists If I re-calculate and re-save the items on the quote (from the Salesforce UI), then the rules run again (from the UI) and correctly insert the expected new products/discounts. So I know the rules themselves are working, but I cannot get them to successfully commit the changes to Salesforce through the RulesEngine via Apex. What am I doing wrong? Here is my code for creating the quote/running the quote through the rules engine: zqu__Quote__c zQuote = new zqu__Quote__c(Name = 'eCommerce Sale Quote ' + acct.Id,
zqu__Account__c = acct.Id,
zqu__Opportunity__c = opt.Id,
zqu__BillToContact__c = cont.Id,
zqu__SoldToContact__c = cont.Id,
zqu__Service_Activation_Date__c = System.today(),
zqu__StartDate__c = System.today(),
zqu__SubscriptionType__c = capitalize(quoteType));
zqu.Quote theQuote = zqu.Quote.createNewInstance(zQuote);
theQuote.buildAndSave();
List<zqu.zChargeGroup> chargeGroups = new List<zqu.zChargeGroup>();
for(zqu__ProductRatePlan__c prp : ratePlanList){
zqu.zChargeGroup chargeGroup = zqu.zQuoteUtil.getChargeGroup(theQuote.getId(),prp.Id);
chargeGroups.add(chargeGroup);
}
System.debug('charge Groups: ' + chargeGroups);
List<zqu.zChargeGroup> addedChargeGroup = zqu.zQuoteUtil.addChargeGroups(chargeGroups);
System.debug('Charge Groups Added: ' + addedChargeGroup);
Id quoteId = theQuote.getId();
Set<zqu.CacheId> requiredIds = new Set<zqu.CacheId>();
requiredIds.add(new zqu.CacheId('zqu__Quote__c',quoteId));
Map<String,List<zqu.DataObject>> dataObjects = makeDataObjects(quoteId);
zqu.RulesEngine re = new zqu.RulesEngine('zqu__Quote__c');
re.initialize(dataObjects, requiredIds);
zqu.RulesEngineResponse response = re.run(zqu.RulesEngine.RuleType.ALL);
finalMap.put('Account',acct.Id);
finalMap.put('Contact',cont.Id);
finalMap.put('Opportunity',opt.Id);
finalMap.put('Quote',theQuote.getId());
finalMap.put('Rules Engine Response',String.valueOf(response));
finalMap.put('Rules Engine Object',String.valueOf(response.getMasterObject()));
finalMap.put('Rules Engine Messages',String.valueOf(response.getMessages()));
finalMap.put('Rules Engine Success',String.valueOf(response.isSuccess())); Here is the context of the makeDataObjects method that I copied from the Documentation: private static Map<String, List<zqu.DataObject>> makeDataObjects(Id quoteId) {
List <zqu.DataObject> dataChargeGroups = new List <zqu.DataObject> ();
List <zqu.DataObject> dataCharges = new List <zqu.DataObject> ();
List <zqu.ZChargeGroup> chargeGroups = zqu.zQuoteUtil.getChargeGroups(quoteId);
// Create a DataObject for ZChargeGroup (QuoteRatePlan)
// and ZCharges (QuoteRatePlanCharge).
for(zqu.ZChargeGroup chargeGroup : chargeGroups){
zqu.DataObject dataChargeGroup = new zqu.ZChargeGroupDataObject(chargeGroup);
dataChargeGroups.add(dataChargeGroup);
dataCharges.addAll(dataChargeGroup.getChildren(
'zqu__' + 'QuoteRatePlanCharge__c'));
}
return new Map <String, List<zqu.DataObject>>{
'zqu__' + 'QuoteRatePlan__c' => dataChargeGroups,
'zqu__' + 'QuoteRatePlanCharge__c' => dataCharges
};
}
... View more