- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-23-2025 09:57 PM - edited ‎07-24-2025 12:14 PM
Write a BR - If there are four RITM attached to one Request, then state of request should set as following combinations-
1. If any RITM is in closed incomplete state and Incomplete reason is withdrawn by requester then state should set as - "Closed Cancelled"
2. If any RITM is in Closed Incomplete state than state of request should state as "Closed Incomplete"
3. If any RITM is in closed Complete state than state of request should set as "Closed Complete"
4. Else If RITM is in closed skipped state than state of request should set as "Closed Skipped"
Request state should not set to closed incomplete, complete or skipped or cancelled, If their are any RITM active. For example. If there are two RITM and one of them is in closed complete but other is still active than state of request should not change till both RITM's get active false or closed.
If any RITM is Closed Incomplete and incomplete_reason == withdrawn_by_requester, set Request to Closed Cancelled.
If any RITM is Closed Incomplete, set Request to Closed Incomplete.
If any RITM is Closed Complete, set Request to Closed Complete.
If any RITM is Closed Skipped, set Request to Closed Skipped.
Do not update the Request state if any RITM is still active.
For that I have wrote below business rule on sc_req_item table with below conditions but not working.
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-24-2025 04:16 AM
try this
(function executeRule(current, previous) {
// Run only if state has changed
if (!current.state.changes())
return;
// Constants - update as per your instance!
var CLOSED_COMPLETE = 3;
var CLOSED_INCOMPLETE = 4;
var CLOSED_SKIPPED = 7;
var INCOMPLETE_WITHDRAWN = '3'; // Confirm this value on your instance
// Step 1: Check if any requested item (RITM) in this request is still active
var activeAgg = new GlideAggregate('sc_req_item');
activeAgg.addQuery('request', current.request);
activeAgg.addQuery('active', true);
activeAgg.addAggregate('COUNT');
activeAgg.query();
if (activeAgg.next() && activeAgg.getAggregate('COUNT') > 0) {
// There is at least one active RITM. Do NOT update parent request state.
return;
}
// Step 2: Aggregate counts of all RITMs grouped by state and incomplete_reason
var agg = new GlideAggregate('sc_req_item');
agg.addQuery('request', current.request);
agg.groupBy('state');
agg.groupBy('incomplete_reason');
agg.addAggregate('COUNT');
agg.query();
// Flags to track RITM states
var hasWithdrawn = false;
var hasClosedIncomplete = false;
var hasClosedComplete = false;
var hasClosedSkipped = false;
while (agg.next()) {
var state = parseInt(agg.getValue('state'), 10);
var reason = agg.getValue('incomplete_reason') || '';
if (state === CLOSED_INCOMPLETE) {
if (reason == INCOMPLETE_WITHDRAWN) {
hasWithdrawn = true;
} else {
hasClosedIncomplete = true;
}
} else if (state === CLOSED_COMPLETE) {
hasClosedComplete = true;
} else if (state === CLOSED_SKIPPED) {
hasClosedSkipped = true;
}
}
// Determine new state for the sc_request based on priority
var newReqState = '';
if (hasWithdrawn) {
newReqState = 'closed_cancelled';
} else if (hasClosedIncomplete) {
newReqState = 'closed_incomplete';
} else if (hasClosedComplete) {
newReqState = 'closed_complete';
} else if (hasClosedSkipped) {
newReqState = 'closed_skipped';
}
// Step 3: Update the parent request state only if changed
if (newReqState) {
var reqGR = new GlideRecord('sc_request');
if (reqGR.get(current.request) && reqGR.request_state != newReqState) {
reqGR.request_state = newReqState;
reqGR.update();
}
}
})(current, previous);
If my response helped please mark it correct and close the thread so that it benefits future readers.
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-23-2025 10:09 PM - edited ‎07-23-2025 10:10 PM
Hi @Pratiksha KC ,
You probably have to write business rule in sc_req_item table with condition active changes to false
And check whether the current RITM's request have multiple RITM,
If yes, then check whether they are active or inactive
If all are inactive, Keep your script accordingly to set Request state
If I could help you with your Query then, please hit the Thumb Icon and mark as Correct !!
Thanks, GP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-23-2025 10:24 PM
your business rule should be After Update on RITM and not REQ
Condition: State Changes
Script:
(function executeRule(current, previous) {
// Only trigger when state changes
if (current.state.changes()) {
// Parent Request record
var reqGR = new GlideRecord('sc_request');
if (!reqGR.get(current.request + '')) return; // sanity check
// Gather all RITMs for this request
var ritmGR = new GlideRecord('sc_req_item');
ritmGR.addQuery('request', current.request);
ritmGR.query();
// Priority flags
var hasActive = false;
var hasWithdrawn = false;
var hasClosedIncomplete = false;
var hasClosedComplete = false;
var hasClosedSkipped = false;
// State values (verify in your instance)
var CLOSED_COMPLETE = 3;
var CLOSED_INCOMPLETE = 4;
var CLOSED_SKIPPED = 7;
var INCOMPLETE_WITHDRAWN = '3'; // Or correct value in your environment
while (ritmGR.next()) {
if (ritmGR.active) {
hasActive = true;
break; // If any active, we do not update parent state
}
var state = parseInt(ritmGR.getValue('state'), 10);
if (state === CLOSED_INCOMPLETE) {
var reason = ritmGR.getValue('incomplete_reason');
if (reason == INCOMPLETE_WITHDRAWN) {
hasWithdrawn = true;
} else {
hasClosedIncomplete = true;
}
} else if (state === CLOSED_COMPLETE) {
hasClosedComplete = true;
} else if (state === CLOSED_SKIPPED) {
hasClosedSkipped = true;
}
}
// Update parent Request state only if all RITMs are NOT active
var newReqState = '';
if (!hasActive) {
if (hasWithdrawn) {
newReqState = 'closed_cancelled';
} else if (hasClosedIncomplete) {
newReqState = 'closed_incomplete';
} else if (hasClosedComplete) {
newReqState = 'closed_complete';
} else if (hasClosedSkipped) {
newReqState = 'closed_skipped';
}
if (newReqState && reqGR.request_state != newReqState) {
reqGR.request_state = newReqState;
reqGR.update();
}
}
}
})(current, previous);
If my response helped please mark it correct and close the thread so that it benefits future readers.
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-23-2025 11:21 PM - edited ‎07-23-2025 11:22 PM
For this logic, your business rule should be configured to run After Update on the RITM (sc_req_item) table, not on the REQ (sc_request).
Condition: Trigger only when the State changes.
Script Overview:
(function executeRule(current, previous) {
// Only proceed if the state of the RITM has changed
if (!current.state.changes()) {
return;
}
// Retrieve the parent request record
var req = new GlideRecord('sc_request');
if (!req.get(current.request + '')) {
return;
}
// Retrieve all RITMs for this request
var ritm = new GlideRecord('sc_req_item');
ritm.addQuery('request', current.request);
ritm.query();
// State tracking flags
var hasActive = false;
var hasWithdrawn = false;
var hasClosedIncomplete = false;
var hasClosedComplete = false;
var hasClosedSkipped = false;
// Constants (ensure these match your sys_choice values)
var CLOSED_COMPLETE = 3;
var CLOSED_INCOMPLETE = 4;
var CLOSED_SKIPPED = 7;
var INCOMPLETE_WITHDRAWN = '3'; // Adjust this based on your instance value
// Loop through each RITM under the request
while (ritm.next()) {
if (ritm.active) {
hasActive = true;
break; // No need to continue if any RITM is still active
}
var state = parseInt(ritm.getValue('state'), 10);
if (state === CLOSED_INCOMPLETE) {
var reason = ritm.getValue('incomplete_reason');
if (reason === INCOMPLETE_WITHDRAWN) {
hasWithdrawn = true;
} else {
hasClosedIncomplete = true;
}
} else if (state === CLOSED_COMPLETE) {
hasClosedComplete = true;
} else if (state === CLOSED_SKIPPED) {
hasClosedSkipped = true;
}
}
// Only update the request state if no RITMs are active
if (!hasActive) {
var newRequestState = '';
if (hasWithdrawn) {
newRequestState = 'closed_cancelled';
} else if (hasClosedIncomplete) {
newRequestState = 'closed_incomplete';
} else if (hasClosedComplete) {
newRequestState = 'closed_complete';
} else if (hasClosedSkipped) {
newRequestState = 'closed_skipped';
}
// Only update if the state is changing
if (newRequestState && req.request_state !== newRequestState) {
req.request_state = newRequestState;
req.update();
}
}
})(current, previous);
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-24-2025 12:15 AM
Hello Pratiksha,
Here's the below code for the query as posted in the community page;
Code below:
(function executeRule(current, previous /*null when async*/) {
// Get the parent request
var request = current.request;
if (!request) return;
// Check if any RITMs are still active
var activeRITM = new GlideRecord('sc_req_item');
activeRITM.addQuery('request', request);
activeRITM.addQuery('active', true);
activeRITM.query();
if (activeRITM.hasNext()) {
// At least one RITM still active – do not update request
return;
}
// Now check all completed RITMs for statuses
var ritmGR = new GlideRecord('sc_req_item');
ritmGR.addQuery('request', request);
ritmGR.query();
var setClosedCancelled = false;
var setClosedIncomplete = false;
var setClosedComplete = false;
var setClosedSkipped = false;
while (ritmGR.next()) {
if (ritmGR.state == '8' && ritmGR.incomplete_reason == 'withdrawn_by_requester') {
// Closed Incomplete + Withdrawn by Requester
setClosedCancelled = true;
} else if (ritmGR.state == '8') {
// Closed Incomplete
setClosedIncomplete = true;
} else if (ritmGR.state == '3') {
// Closed Complete
setClosedComplete = true;
} else if (ritmGR.state == '4') {
// Closed Skipped
setClosedSkipped = true;
}
}
// Update request based on priority
var requestGR = new GlideRecord('sc_request');
if (requestGR.get(request)) {
if (setClosedCancelled) {
requestGR.setValue('request_state', 'closed_cancelled'); // Replace with actual value from dictionary
} else if (setClosedIncomplete) {
requestGR.setValue('request_state', 'closed_incomplete');
} else if (setClosedComplete) {
requestGR.setValue('request_state', 'closed_complete');
} else if (setClosedSkipped) {
requestGR.setValue('request_state', 'closed_skipped');
}
requestGR.update();
}
})();
Requirements
You have a Request (sc_request) with 4 associated RITMs (sc_req_item).
The Request state should only update when all RITMs are inactive (i.e., not active).
Once all RITMs are inactive, set the Request's state based on the following priority:
Request State Mapping (Priority Order)
Closed Cancelled: If any RITM is closed_incomplete AND incomplete_reason == withdrawn_by_requester.
Closed Incomplete: If any RITM is closed_incolplete.
Closed Complete: If any RITM is closed_complete.
Closed Skipped: If any RITM is closed_skipped.
Suggested Business Rule Setup
Table: sc_req_item
When: after Update
Condition: curent.active.changesTo(false) (This ensures it only triggers when RITM becomes inactive)
Please try it, this would fix it.