Custom Action Plugin
Use the Custom Action Plugin to configure additional actions you want to trigger via Zuora Rules Engine. The Custom Action Plugin interface class, zqu.CustomActionPlugin
, contains the following interface methods:
perform
isUpdateAction
isAddRemoveAction
isValidateAction
Perform Method
In the perform
method, define the logic this custom action will execute. See the sample code below for an example implementation of the perform
method.
The method takes the following input parameters.
Input | Data Type | Description |
---|---|---|
masterObject | zqu.DataObject | Contains the record that the rule is currently running against and its related data. This will generally be a Quote record. |
attributes | Map<String, Object> | A map of parameters that can be defined by an admin when configuring a custom action. |
logs | String[] | A list of strings that get printed to the Rules Engine log when the rules engine executes the action. |
Rule Types Methods
When initiating the Rules Engine programmatically, you have an option to specify which types of actions to run. For example, calling the Rules Engine with the Rule Type of VALIDATION will only evaluate rules with a Validation action.
By default, the Rules Engine runs all actions.
When defining a custom action, set the following methods to return true
to specify the types of this action.
Method | Rule Types that Can Invoke this Action |
---|---|
isUpdateAction() | ALL or PRICE |
isAddRemoveAction() | ALL or PRODUCT |
isValidateAction() | ALL or VALIDATION |
Constructors
Using the following constructors, you can instantiate different types of DataObjects to add new data during a custom action.
Contructor | Description |
---|---|
new ZChargeGroupDataObject new ZChargeGroupDataObject | Creates a new ChargeGroup, retrieved through the zqu.zQuoteUtil.getChargeGroup global method. QuoteRatePlan fields can be retrieved from this record, even if it has not yet been saved to the database. Charge objects can be retrieved from an instance of this object using: getChildren('zqu__QuoteRatePlanCharge__c') |
new PlaceholderChargeGroupDataObject | Represents a charge group to be added after rules execution completes. Charge and Plan details are not accessible from this instance, but because it does not call getChargeGroups, it runs more quickly and makes no SOQL queries. |
new CommittedDataObject | Represents an SObject record inserted into the Database. Not used for Product Actions. |
Sample Code
The below sample code implements a custom action that updates charges, removes and adds rate plans, and validates the quote.
global with sharing class MyCustomActionPlugin implements zqu.CustomActionPlugin{ global void perform(zqu.DataObject masterObject, Map < String, Object > attributes, String[] logs){ // Read values from Quote Object String quoteId = (String)masterObject.get('Id'); logs.add('QuoteId=' + quoteId); // Read values set in Rule Configuration String attributeMsg = (String)attributes.get('msg'); logs.add('Attribute Message=' + attributeMsg); // Read values from child objects. List < zqu.DataObject > plans = masterObject.getChildren('zqu__QuoteRatePlan__c'); logs.add('# of plans: ' + plans.size() ); // Updating Charges and Tiers List < zqu.DataObject > charges = masterObject.getChildren('zqu__QuoteRatePlanCharge__c'); logs.add('# of charges: ' + plans.size() ); Decimal chargeListPrice = 10, tierListPrice = 10, tierDiscount = 50; for (zqu.DataObject charge : charges) { // Update the list price at the charge level // for 'Flat Fee Pricing' charge type. if (charge.get('zqu__Model__c') == 'Flat Fee Pricing') { charge.put('zqu__ListPrice__c', chargeListPrice); logs.add('Updating list price of charge (' + charge.get('Name') + ') to ' + chargeListPrice + '.'); chargeListPrice += 10; } // Update the tier details, List Price, Discount, Effective Price. if (charge.get('zqu__ChargeType__c') == 'Recurring' && (charge.get('zqu__Model__c') == 'Tiered Pricing' || charge.get('zqu__Model__c') == 'Volume Pricing')) { // Get the list of tiers for the charge object and // modify the tier information. zqu.ZChargeDataObject chargeObject = (zqu.ZChargeDataObject) charge; List<zqu__QuoteCharge_Tier__c> tiers = chargeObject.getCharge().chargeTiersObjects; if (tiers != null && tiers.size() > 0) { for (zqu__QuoteCharge_Tier__c tier : tiers) { tier.zqu__Price__c = tierListPrice; tier.zqu__Discount__c = tierDiscount; tier.zqu__Effective_Price__c = (tierListPrice / 2); tierListPrice += 10.00; } logs.add('Updating the tiers of charge (' + charge.get('Name') + ').'); // Populate the changed tier informations. chargeObject.rePopulateCustomChargeTiers(tiers); } } } // Removing Charge Group for(zqu.DataObject plan : plans){ String targetProduct = 'Orange Box'; if((String) plan.get('zqu__QuoteProductName__c') == targetProduct){ logs.add('You have a ' + targetProduct + ' plan.'); plan.flagRemoved(); logs.add(targetProduct + ' Removed.'); } } // Add Product (Adds immediately, allows access to Charge details) zqu.DataObject addedPlan = new zqu.ZChargeGroupDataObject(masterObject, '01t36000002i9ki'); // Set ProductRatePlan reference. zqu__ProductRatePlan__c prp = new zqu__ProductRatePlan__c(Id=productRatePlanId); zqu.DataObject dataProductRatePlan = new zqu.CommittedDataObject(prp); addedPlan.putParent('zqu__ProductRatePlan__c', dataProductRatePlan); addedPlan.flagAdded(); masterObject.addChild('zqu__QuoteRatePlan__c', addedPlan); // Add Product (Adds after rules are run, does not allow access // to Charge details) zqu.DataObject toBeAddedPlan = new zqu.PlaceholderChargeGroupDataObject('01t36000002i9ki'); toBeAddedPlan.flagAdded(); masterObject.addChild('zqu__QuoteRatePlan__c', toBeAddedPlan); // Validation Error if(plans.size() > 2){ throw new zqu.CustomValidationException( 'You cannot have more than two plans on a quote.'); } logs.add('==='); } global Boolean isUpdateAction() { return true; } global Boolean isAddRemoveAction() { return true; } global Boolean isValidateAction() { return true; } }