User-generated business rule trigger conditions

Luke Van Epen
Tera Guru

Here's the scenario:

As a power user (team leader, process manager), I want to be able to define a list of trigger conditions (Rules) that will result in a record being added to a table. This could be 5 rules or 500 rules long. The record that gets created will need to contain: The user who triggered the rule and the rule itself that was triggered.

 

What I believe to be the approach:

I have a (preferably single) business rule that will trigger an event, that event will run a script action to generate a record in the database.

The script action will be predefined, and only take a couple parameters such as the User who did it and the Rule they triggered.

The condition of the Business Rule will call a script include that will loop through all of the conditions in the Rules table, and if any match, the business rule will run.

 

There are a couple of obvious issues i see with this, namely performance, since this BR will be running on task, it will check every single update of any Task record through possibly dozens of conditions before continuing.

Can anyone think of a better way of getting this outcome? The idea is that once the solution is built it requires no admin maintenance, the process people define the rules and new records just keep getting generated.

1 ACCEPTED SOLUTION

Luke Van Epen
Tera Guru

After a bunch of digging I've got a solution working. It requires minor admin maintenance since each new Table that the user wants to write a rule for will need to have a corresponding Business Rule running on that task with the same condition being checked. 

On the user-facing 'Rule' table, add a Condition filter

Then on the business rule, you can call a script include that will use GlideFilter to check whether an updated record matches. Note that the below example is oversimplified to my actual solution to convey the GlideFilter application more clearly.

E.g.

User-facing Rule record:

  • Table: Task
  • Condition: Active is True

Business Rule:

  • When: Async, Insert & Update
  • Table: Task

Condition:

new CustomScriptInclude().matchesCondition(current)

CustomScriptInclude:

matchesCondition: function(recordGR){
		var rulesGR = new GlideRecord('user_facing_rules_table');
		rulesGR.addQuery('table',recordGR.sys_class_name); //you can make this more dynamic by checking for parent tables but thats another thing
		rulesGR.query();
		while(rulesGR.next()){
			if(GlideFilter.checkRecord(recordGR,rulesGR.condition)){
				return true;
			}
		}
		return false;
	},

 

 

Also even though the above calls are async, you can still access the 'rulesGR' record again in the execution script of the business rule once the condition evaluates to true by checking the condition again, to perform some logic that relies on data in the user-facing Rule record. There's probably a cleaner way to do that but it works so I'll just roll with it for now

View solution in original post

1 REPLY 1

Luke Van Epen
Tera Guru

After a bunch of digging I've got a solution working. It requires minor admin maintenance since each new Table that the user wants to write a rule for will need to have a corresponding Business Rule running on that task with the same condition being checked. 

On the user-facing 'Rule' table, add a Condition filter

Then on the business rule, you can call a script include that will use GlideFilter to check whether an updated record matches. Note that the below example is oversimplified to my actual solution to convey the GlideFilter application more clearly.

E.g.

User-facing Rule record:

  • Table: Task
  • Condition: Active is True

Business Rule:

  • When: Async, Insert & Update
  • Table: Task

Condition:

new CustomScriptInclude().matchesCondition(current)

CustomScriptInclude:

matchesCondition: function(recordGR){
		var rulesGR = new GlideRecord('user_facing_rules_table');
		rulesGR.addQuery('table',recordGR.sys_class_name); //you can make this more dynamic by checking for parent tables but thats another thing
		rulesGR.query();
		while(rulesGR.next()){
			if(GlideFilter.checkRecord(recordGR,rulesGR.condition)){
				return true;
			}
		}
		return false;
	},

 

 

Also even though the above calls are async, you can still access the 'rulesGR' record again in the execution script of the business rule once the condition evaluates to true by checking the condition again, to perform some logic that relies on data in the user-facing Rule record. There's probably a cleaner way to do that but it works so I'll just roll with it for now