- 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: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:34 AM
Hello your solution is also fine but i think the solution which i was provided is easy to understand for the developer which have less knowledge of JavaScript (coding) but your solution is also fine thanks for your response
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-18-2025 08:45 AM
since you asked for optimized version, hence I shared the same.
I believe when the developer has good experience and knows what's the best practice, they should be able to understand the above code as well.
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 09:20 AM
Okay thanks brother
bro please check the below i have face another issue related to the email notification please have a look and response if you have any idea