- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-18-2025 07:49 AM
I've created a scheduled job to automatically close Demands when all associated Stories are in a closed state. I'd like to get some feedback on the script, particularly regarding efficiency and best practices.
The script iterates through active Demands and checks the state of their related Stories. If all Stories are closed, the Demand is automatically closed and a closure note is added.
Here's the script
var demand = new GlideRecord('dmn_demand');
demand.addActiveQuery();
demand.query();
while (demand.next()) {
var demandSysId = demand.sys_id;
var story = new GlideRecord('rm_story');
story.addQuery('demand', demandSysId);
story.query();
var total = story.getRowCount();
var close = 0;
while (story.next()) {
if (story.state == '3') {
close++;
}
}
if (total == close) {
gs.log("All stories closed for demand: " + demand.number);
demand.state = '9';
demand.u_closure_note = 'All stories completed';
demand.acceptance_criteria='All the stories of this demand is closed now ';
demand.update();
} else {
gs.log(" open stories in demand: " + demand.number);
}
}
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-18-2025 08:12 AM
try this optimized version
1) use GlideAggregate to reduce nested queries
2) removed getRowCount()
3) use setWorkflow(false) and autoSysFields(false) to skip updating timestamp, disables business rules etc on update
4) use try catch block to handle exception
(function executeRule(current, previous) {
var demandGr = new GlideRecord('dmn_demand');
demandGr.addActiveQuery();
demandGr.addQuery('state', '!=', '9'); // Skip already closed demands
demandGr.query();
while (demandGr.next()) {
var storyAgg = new GlideAggregate('rm_story');
storyAgg.addQuery('demand', demandGr.sys_id);
storyAgg.addAggregate('COUNT');
storyAgg.addQuery('state', '!=', '3'); // 3 = closed state
storyAgg.query();
if (storyAgg.next()) {
var openStories = storyAgg.getAggregate('COUNT');
if (openStories === 0) {
closeDemand(demandGr);
}
}
}
function closeDemand(demand) {
try {
demand.setWorkflow(false); // Bypass workflows for bulk operations
demand.autoSysFields(false); // Skip audit fields updates
demand.state = '9';
demand.u_closure_note = 'All stories completed';
demand.acceptance_criteria = 'All stories for this demand are closed';
demand.update();
gs.info('[Demand Closure] Closed: ' + demand.number);
} catch (e) {
gs.error('[Demand Closure] Failed for ' + demand.number + ': ' + e);
}
}
})();
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
‎06-18-2025 08:35 AM
Hello @muneermajeed ,
Pleaser find optimize version as below.
var demand = new GlideRecord('dmn_demand');
demand.addActiveQuery();
demand.query();
while (demand.next()) {
var demandSysId = demand.sys_id;
var story = new GlideRecord('rm_story');
story.addQuery('demand', demandSysId);
story.query();
if (story.next()) {
// Check if there are any stories NOT in closed state (state != 3)
var openStory = new GlideRecord('rm_story');
openStory.addQuery('demand', demandSysId);
openStory.addQuery('state', '!=', '3'); //Assuming '3' is the closed state for story
openStory.query();
if (!openStory.hasNext()) {
demand.state = '9'; // Assuming '9' is the closed state
demand.u_closure_note = 'All stories completed';
demand.acceptance_criteria = 'All the stories of this demand are closed now';
demand.update();
} else {
gs.log("Open stories exist in demand: " + demand.number);
}
}
}
If this solution helped please mark it helpful and correct.
Sunny