- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-01-2020 08:12 AM
Hello!
I have two business rules created. One that closes RITMs when all SCTasks are closed. Then another that closes a request when all RITMs are closed.
Here is my code for both - SCTask Close RITM
When: After
On: Update
Conditions: State changes to Closed Complete, Closed Incomplete, Closed Skipped
(function executeRule(current, previous /*null when async*/ ) {
gs.log('The SCTask Close RITM BR has been triggered by task: ' + current.number);
// Add your code here
var request_item = current.request_item;
var total_task_records = 0;
var task_closed = 0;
var task_incomplete = 0;
var task_skipped = 0;
var tasks = new GlideRecord('sc_task');
tasks.addQuery('request_item', request_item);
tasks.query();
total_task_records = tasks.getRowCount();
gs.log("The RITM " + current.request_item.getDisplayValue() + " has returned " + tasks.getRowCount() + " records. Its current state is " + current.request_item.state.getDisplayValue());
while (tasks.next()) {
gs.log("Checking task " + tasks.number + "'s state. It is: " + tasks.state.getDisplayValue());
//If a task is in a 'Closed Complete' state, add it to the variable
if (tasks.state == 3)
task_closed++;
//If a task is in a 'Closed Incomplete' state, add it to the variable
if (tasks.state == 4)
task_incomplete++;
//If a task is in a 'Closed Skipped' state, add it to the variable
if (tasks.state == 7)
task_skipped++;
} //End While Tasks
if (total_task_records == (task_closed + task_incomplete + task_skipped)) {
var ritm = new GlideRecord('sc_req_item');
if (ritm.get(request_item)) {
if (ritm.state == '-5' || ritm.state == '1' || ritm.state == '2') {
gs.log("All tasks are closed and RITM is not already closed. We're updating RITM " + current.request_item.getDisplayValue() + ".");
if (task_incomplete > 0) {
ritm.state = '4'; //Closed Incomplete also sets Approval to Rejected.
} else if (task_skipped > 0) {
ritm.state = '7'; //Closed Skipped
} else {
ritm.state = '3'; //Closed Complete
}
ritm.update();
} //End If ritm is not already closed
} //End If ritm state update
} //End If all records closed
})(current, previous);
RITM Close Request
When: After
On: Update
Conditions: State changes to Closed Complete, Closed Incomplete, Closed Skipped
(function executeRule(current, previous /*null when async*/ ) {
gs.log('The RITM Close Request BR has been triggered by task: ' + current.number);
// Add your code here
var request = current.request;
var total_ritm_records = 0;
var ritm_closed = 0;
var ritm_incomplete = 0;
var ritm_skipped = 0;
var ritms = new GlideRecord('sc_req_item');
ritms.addQuery('request', request);
ritms.query();
total_ritm_records = ritms.getRowCount();
gs.log("The Request " + current.request.getDisplayValue() + " has returned " + ritms.getRowCount() + " records. Its current state is " + current.request.request_state.getDisplayValue());
while (ritms.next()) {
gs.log("Checking RITM " + ritms.number + "'s state. It is: " + ritms.state);
//If a RITM is in a 'Closed Complete' state, add it to the variable
if (ritms.state == 3)
ritm_closed++;
//If a RITM is in a 'Closed Incomplete' state, add it to the variable
if (ritms.state == 4)
ritm_incomplete++;
//If a RITM is in a 'Closed Skipped' state, add it to the variable
if (ritms.state == 7)
ritm_skipped++;
} //End While RITMs
if (total_ritm_records == (ritm_closed + ritm_incomplete + ritm_skipped)) {
var req = new GlideRecord('sc_request');
if (req.get(request)) {
if (req.request_state == "in_process" || req.request_state == "requested") {
gs.log("All RITMs are closed and Request is not already closed. We're updating Request " + current.request.getDisplayValue() + ".");
if (ritm_incomplete > 0) {
req.request_state = 'closed_incomplete'; //Closed Incomplete
req.state = '4';
req.stage = 'closed_incomplete';
} else if (ritm_skipped > 0) {
req.request_state = 'closed_skipped'; //Closed Skipped
req.state = '7';
req.stage = 'closed_skipped';
} else {
req.request_state = 'closed_complete'; //Closed Complete
req.state = '3';
req.stage = 'closed_complete';
}
req.update();
} //End If request is not already closed
} //End If req state update
} //End If all records closed
})(current, previous);
All of this works fine and dandy when the user creates new SCTasks themselves. The issue I'm running into is when I have a workflow or flow designer that creates a new task AFTER a SCTask is closed (as part of the flow). In this case the above BRs run and close the RITM and Request then there is a newly created SCTask. In this scenario I don't want the BRs to run or to to close the RITM and Request until the flow is done creating new tasks.
What would be the best way to achieve this? Please let me know if anything needs to be clarified.
Thanks in advance!
Dom
Solved! Go to Solution.
- Labels:
-
Service Catalog

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-01-2020 08:19 AM
Hi,
I see your problem statement, why don't you just move these scripts in Flow designer/workflow as last activity ?
The issue you are getting is due to execution order. Refer below for details.
https://docs.servicenow.com/bundle/paris-application-development/page/script/general-scripting/reference/r_ExecutionOrderScriptsAndEngines.html

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-01-2020 08:19 AM
Hi,
I see your problem statement, why don't you just move these scripts in Flow designer/workflow as last activity ?
The issue you are getting is due to execution order. Refer below for details.
https://docs.servicenow.com/bundle/paris-application-development/page/script/general-scripting/reference/r_ExecutionOrderScriptsAndEngines.html
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-01-2020 08:40 AM
Thanks for that link - understanding the full execution order helped. I updated both BRs above to greater than 1000 on order and that did the trick.
Our idea is that if we ever had to make a change to this logic this is one spot to make the change. Now that doesn't mean we couldn't create a sub-flow that gets called too. But then that means we have to "remember" to make sure that sub-flow is in everything we create.
What would you consider to be best practice? Or is it 6 in one and half a dozen in another situation?
Thanks!
Dom

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-01-2020 09:30 AM
I think you can wrap this in a script include and call it whereever you need. You will be able to edit this centrally.
If my answer helped, please mark it answer correct.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-01-2020 10:03 AM
Gotcha, thank you for the tips!
Happy Holidays!
Dom