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  ||  9x 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