Skip to main content

RulesEngine Class

Zuora

RulesEngine Class

Use the RulesEngine class to invoke Zuora Rules Engine from Apex. The RuleEngine class runs against a single record referred to as the master record. The rules are evaluated and executed in the context of the master record. Typically, the master record is a quote in Zuora Quotes.

The high-level steps to invoke the Rules Engine in your Apex code is as below. See the code sample for more details.

  1. Define the master record.
    When the Rules Engine is run, it starts with the id of the master object.
  2. Optionally, supply a set of rules to run. If the list is not supplied, all the rules associated with the quote will be executed.
  3. Define the child objects of the master record by converting charge groups to DataObject and attaching those to the quote DataObject as children. See the second code sample below for detail.
  4. Initialize the rules engine.
  5. Execute the rules engine.
    • The rules engine can be specified to be applied to specific types of actions.
  6. Extract the changes from the master record and update them back to the quote.

See Custom Action Plugin if you want to implement custom actions in the Rules.

Constructor Signature

Create an instance of the RulesEngine class using the following signatures. The Rules Engine takes in the API name of the master object, specifically, zqu__Quote__c, and optionally a subset of rules.

  • RulesEngine (String masterObjectType)
  • RulesEngine(String masterObjectType, List rulesToRun)

RulesEngine Global Methods

The RulesEngine class provides the following methods to initialize and run rules.

Method Return Type Description
initialize
(Map> dataObjects, Set requiredIds)
void  
run
(zqu.RulesEngine.RuleType type)
zqu.RulesEngineResponse Specify which types of actions to run in the parameter. 

RuleType Enum

When invoking the Rules Engine programmatically, you have the 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.

The following values are supported for the RuleType enum:

  • zqu.RulesEngine.RuleType.ALL
  • zqu.RulesEngine.RuleType.PRICE
  • zqu.RulesEngine.RuleType.PRODUCT
  • zqu.RulesEngine.RuleType.VALIDATION

RulesEngineResponse Class

The Rules Engine returns the RulesEngineResponse class that contains the following attributes. Use the associated global methods to retrieve the value returned.

Attribute Global Method Description
zqu.DataObject Master Object getMasterObject() Returns the master record
List <RuleMessage> getMessages() Returns the message
Boolean isSuccess Returns whether the rules engine ran successfully

RuleMessage Class

The RuleMessage class provides the following global methods to access the actionType, message, messageType, and ruleName from the message response.

Attribute Global Method Description
getActionType() String

Returns the type of action. Possible values:

- PRODUCT

- PRICE

- VALIDATION

- DEBUG

- SYSTEM

getMessage() String Returns the body of the message.
getMessageType() String

Returns the type of message. Possible values:

- DEBUG

- INFO

- WARN

- ERROR

getRuleName() String Returns the name of the Rule that was being executed when this message was logged.

Code Samples

The following code invokes the first five rules defined for a quote and executes them. Steps refer to the steps given at the beginning of this article.

// Step #1
// Set the master quote id. Rules are all run in the context of this record.
// Required Ids are the Ids of records that need to be queried from database.
String quoteId = '<Set Quote ID>';
Set < zqu.CacheId > requiredIds = new Set < zqu.CacheId > ();
requiredIds.add( new zqu.CacheId( 'zqu__Quote__c', quoteId ) );

// Step #2
// Optionally, supply a subset of rules.
List < zqu__ZRule__c > rulesToRun = 
  [SELECT Id, Name, zqu__Json__c, zqu__ActionJson__c FROM zqu__ZRule__c LIMIT 5];

// Step #3
// Convert Charge Groups to DataObject
// and attach those to the quote DataObject as children.
// DataObjects are objects that are in memory, but not in the database.
// For example, ChargeGroups that have not yet been saved
Map < String, List < zqu.DataObject > > dataObjects = makeDataObjects(quoteId);

// Step #4
// Initialize the Rules Engine with the API name of master object 
// and a subset of rules.
zqu.RulesEngine re = new zqu.RulesEngine('zqu__Quote__c', rulesToRun);
re.initialize(dataObjects, requiredIds);

// Step #5
// Execute the Rules Engine.
zqu.RulesEngineResponse response = re.run(zqu.RulesEngine.RuleType.ALL);

System.debug(response);

// Step #6
// Extract the updated Charge Groups, and save them to the Quote through the 
// updateChargeGroups() global methods.
zqu.DataObject quoteDataObject = response.getMasterObject();
List<zqu.DataObject> ratePlanDataObjects 
    = quoteDataObject.getChildren('zqu__QuoteRatePlan__c');

List<zqu.zChargeGroup> chargeGroupsForUpdate = new List<zqu.zChargeGroup>();

for(zqu.DataObject rpDataObject : ratePlanDataObjects) {
    zqu.ZChargeGroupDataObject cgForUpdate = (zqu.ZChargeGroupDataObject) rpDataObject;
    chargeGroupsForUpdate.add( cgForUpdate.getChargeGroup() );
}
zqu.ZQuoteUtil.updateChargeGroups(chargeGroupsForUpdate);

The following code sample shows adding product DataObjects to the quote DataObjects.

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(
      quotesNamespace + 'QuoteRatePlanCharge__c'));
  }

  return new Map < String, List < zqu.DataObject > >{
    quotesNamespace + 'QuoteRatePlan__c' => dataChargeGroups,
    quotesNamespace + 'QuoteRatePlanCharge__c' => dataCharges
  };
}

The sample code above shows how to construct QuoteRatePlan and QuoteCharges from ZChargeGroups and ZCharges, but it does not construct the relationships to the product catalog. When calling the RulesEngine class programmatically, the entire DataObject hierarchy must be constructed and populated with all the information you want to run the rules against.

You can programmatically construct and attach additional object relationships on DataObjects as the following sample code shows.

zqu_ProductRatePlan_c productPlan 
    = [SELECT Id,Name FROM zqu__ProductRatePlan__c LIMIT 1];
    
zqu.DataObject productRatePlanDataObject = new zqu.CommittedDataObject(productPlan);

dataChargeGroup.putParent('zqu_ProductRatePlan_c', productRatePlanDataObject);