We've updated the ServiceNow Community Code of Conduct, adding guidelines around AI usage, professionalism, and content violations. Read more

Parent REQs need to be closed when the child RITMs are not open

divyadhanda
Mega Guru

I want to write a fix script to update the parent Req is open when child RITMs/Sctasks are not open (Cancelled, Closed incomplete, closed complete).

7 REPLIES 7

Dr Atul G- LNG
Tera Patron

Hi @divyadhanda 

Sorry, I didn’t quite understand this. When the RITM, SCTASK, not open and REQ are all in the Open state, is that expected behavior, or am I missing something here? Could you please provide more details?

*************************************************************************************************************
Regards
Dr. Atul G. - Learn N Grow Together
ServiceNow Techno - Functional Trainer
LinkedIn: https://www.linkedin.com/in/dratulgrover
YouTube: https://www.youtube.com/@LearnNGrowTogetherwithAtulG
Topmate: https://topmate.io/dratulgrover [ Connect for 1-1 Session]

****************************************************************************************************************

ManishS14752344
Tera Contributor

Hi @divyadhanda ,
From what I understood from your requirements, I think this might work for you

var reqGR = new GlideRecord('sc_request');
reqGR.addQuery('state', '!=', 1); // Not already Open
reqGR.query();

var count = 0;
var updated = 0;

while (reqGR.next()) {
    var parentSysId = reqGR.getUniqueValue();
    var allChildrenClosed = true;
    
    // Check RITMs
    var ritmGR = new GlideRecord('sc_req_item');
    ritmGR.addQuery('request', parentSysId);
    ritmGR.addQuery('state', 'NOT IN', '1,2'); // Exclude Open, In Progress
    ritmGR.query();
    
    if (ritmGR.hasNext()) {
        allChildrenClosed = false; // Found open RITM
    }
    
    // Check scTasks if any RITMs exist
    if (allChildrenClosed) {
        var taskGR = new GlideRecord('sc_task');
        taskGR.addQuery('request_item', 'IN', getAllRITMs(parentSysId));
        taskGR.addQuery('state', 'NOT IN', '1,2'); // Exclude Open, In Progress
        taskGR.query();
        
        if (taskGR.hasNext()) {
            allChildrenClosed = false; // Found open scTask
        }
    }
    
    // Update parent if all children closed
    if (allChildrenClosed) {
        reqGR.state = 1; // Open
        reqGR.update();
        updated++;
        gs.info('Updated REQ ' + reqGR.number + ' to Open');
    }
    
    count++;
}

gs.info('Processed ' + count + ' REQs, updated ' + updated + ' parents');

function getAllRITMs(parentSysId) {
    var ritmIds = [];
    var ritmGR = new GlideRecord('sc_req_item');
    ritmGR.addQuery('request', parentSysId);
    ritmGR.query();
    
    while (ritmGR.next()) {
        ritmIds.push(ritmGR.getUniqueValue());
    }
    return ritmIds.join(',');
}

 

Hope it helps

 

-------------------------------------------------------------------------------------------------------------------------------------------------

If my response helped, please mark it as helpful

Ankur Bawiskar
Tera Patron

@divyadhanda 

you want to do this for older REQs?

If yes then here is your fix script

note: please test in DEV and TEST before running in PROD

(function() {
    var req = new GlideRecord('sc_request');
    req.addQuery('state', '!=', 1); // Not already open
    req.query();
    
    var count = 0;
    while (req.next()) {
        // Check if ALL RITMs AND SCTASKs are closed (state 3,4,7)
        var hasOpenRitm = false;
        var ritm = new GlideRecord('sc_req_item');
        ritm.addQuery('request', req.sys_id);
        ritm.addQuery('state', 'NOT IN', '3,4,7');
        ritm.query();
        if (ritm.next()) hasOpenRitm = true;
        
        var hasOpenTask = false;
        var task = new GlideRecord('sc_task');
        task.addQuery('request', req.sys_id);
        task.addQuery('state', 'NOT IN', '3,4,7');
        task.query();
        if (task.next()) hasOpenTask = true;
        
        // Reopen if no open children
        if (!hasOpenRitm && !hasOpenTask) {
            req.state = 1; // Open
            req.update();
            count++;
            gs.info('Reopened: ' + req.number);
        }
    }
    gs.info('Updated ' + count + ' requests');
})();

Also going forward you can write After update BR on sc_task to close RITM and REQ when last scTask is closed

After Update: sc_task

Condition: State [Changes To] Closed Complete/Closed Incomplete/Close Skipped

Script:

(function executeRule(current, previous /*null when async*/ ) {

    // Add your code here
    var gr = new GlideRecord('sc_task');
    gr.addQuery('request_item', current.request_item);
    gr.addQuery('active', true);
    gr.query();
    if (!gr.next()) {

        // close RITM
        var ritm = current.request_item.getRefRecord();
        ritm.state = 3;
        ritm.update();

        // close REQ
        var req = current.request.getRefRecord();
        req.state = 3;
        req.update();
    }

})(current, previous);

💡 If my response helped, please mark it as correct and close the thread 🔒— this helps future readers find the solution faster! 🙏

Regards,
Ankur
Certified Technical Architect  ||  10x ServiceNow MVP  ||  ServiceNow Community Leader

But i want to fetch only the open REQs whose child RITMs/Sctasks are not open, 

 

For those open req's. I need to update as Request.state=close