Sunday, April 10, 2016

Salesforce SOQL Rule Engine

Build A Dynamic SOQL based Rule Engine and Evaluate the Rules for a given record on click of Button:

Use Case:
At times we come across an use-case where we wanted to evaluate a set of conditions for a given record and perform certain actions if satisfied. Workflows/Process builders are some of the ways to handle such requirements.

  • Sometimes the expansion of use-cases/complexity/frequent changes limit our ability to respond to it in a quicker way.
  • Too many Workflows with frequently changing criteria or with large criteria set at times hits the formula size limit. It can also impact the performance, makes it harder to maintain.

One way to overcome this is using "SOQL based simplified rule engine" which is configurable and the rules can be configured on the fly. This can be evaluated on a button click per record. If it has to be used in bulk then good to be evaluated as part of batch job in order to respect the Salesforce query limit exceptions.

Steps to build and use a simple SOQL based Rule Engine:
1> Create a custom object/custom metadata type (Available in Winter-16) "Rule Criteria" with following fields:
  • Rule Name, Group Rule Name (used if more than one rules), a long-text area to store the SOQL Rule, Next Rule Name field and sequence incase of multiple rules to be evaluated if the first rule criteria did not meet.
2> On Click of a button fetch the SOQL rule and run against the selected record if returned false if no other rules in the "Next Rule Name" within the "Group of Rules" for the "Rule Group" then end the rule evaluation else evaluate the next rule in the "Rule Group". If returned true check for "Evaluate Next" Flag to evaluate if any next rule defined in the Group else abort the evaluation.

3> Replace the dynamic variables in the stored SOQL in the "Rule Criteria Object" before executing the query for the rule evaluation.


Example:

Evaluate a User record is active followed by if the profile has Salesforce License.

1) Create Rule1 with a user based query with where condition isActive=true
2) Create Rule2 with a profile based query with where condition license name like Salesforce

 Evaluate the above Rule on click of a button for the above scenario:

{!REQUIRESCRIPT("/soap/ajax/32.0/connection.js")}
{!REQUIRESCRIPT("/js/functions.js")}
{!REQUIRESCRIPT("/soap/ajax/32.0/apex.js")}

var user = sforce.connection.getUserInfo();
var result = sforce.connection.query("SELECT RuleName__c,RuleSOQL__c,NextRuleName__c,Evaluate_Rules__c,Group_Rule_Name__c,Rule_Sequence__c from RuleCriteria__c where Group_Rule_Name__c='UserProfileValidation' order by Rule_Sequence__c");
var RuleC = result.getArray("records");
var RuleResult,RuleStr;

for (var i=0; i< RuleC.length; i++) {
        RuleStr = RuleC[i].RuleSOQL__c;
    if(RuleStr.indexOf("{UserId}")>-1)
           RuleStr=RuleStr.replace("{UserId}", "'"+user.userId+"'");

    if(RuleStr.indexOf("{ProfileId}")>-1)
           RuleStr=RuleStr.replace("{ProfileId}", "'"+user.profileId+"'");

    RuleResult = sforce.connection.query(RuleStr);
        if(RuleResult.size>0 && RuleC[i].Evaluate_Rules__c=='true') {
        if(RuleC[i].NextRuleName__c.length>0)
        {
            alert("Rule: "+RuleC[i].RuleName__c+" Passed!");
            continue;
        }
        else
        {
            alert("All Rules Evaluation Passed.");
            //Perform Next steps.
            break;
        }
    }
    else if(RuleResult.size>0)
    {
        alert("All Rules Evaluation Passed.");
        //Perform Next steps.
        break;
    }
}

*** You can install the unpackaged to have the above components from the following link: ***
https://login.salesforce.com/packaging/installPackage.apexp?p0=04t61000000Sk9H

No comments:

Post a Comment