Skip to main content

transform map to bulk close catalog tasks without sending notifications

Transform map to close ageing tasks

this transform will:

- close RITM
- cancel RITM workflow
- close associated sc_tasks
- close associated REQ (assuming no other open RITM)
- close associated open approvals


and will by-pass business rules and notifications

only runs if RITM is active and there are open tasks present

obviously requires thorough testing and UAT!


import sheet format (excel)



transform map

ensure 'run business rules' flag is unchecked





transform script

(function transformRow(source, target, map, log, isUpdate) {


    log.info('trMap:BULK CLOSE sc task NO NOTIFICATIONS:: in main script... ' + source.u_request_item);

    if (action == "insert") {

        ignore = true;

        log.error('ACTION ABORTED: trMap:BULK CLOSE sc task NO NOTIFICATIONS:: insert operation aborted, check number ' + source.u_request_item);

    }

    //--make sure tasks are open before proceeding

    var grTasks = new GlideRecord('sc_task');

    grTasks.addActiveQuery();

    grTasks.addQuery('request_item', target.sys_id);

    grTasks.query();

    if (grTasks.getRowCount() < 1) {

        log.error('ACTION ABORTED: trMap:BULK CLOSE sc task NO NOTIFICATIONS:: no active tasks on the RITM ' + source.u_request_item);

    }

})(source, target, map, log, action === "update");

onbefore script

(function runTransformScript(source, map, log, target /*undefined onStart*/ ) {

    

if (target.active == false) {

        ignore = true;

        log.error('ACTION ABORTED: onbefore: trMap:BULK CLOSE sc task NO NOTIFICATIONS:: target record is already closed ' + source.u_request_item);

    } else {

        killWorkflows(target.sys_id);

    }

})(source, map, log, target);


function killWorkflows(RITM_sysid) {

    //--as run business rules is switched off to bypass notifications, need to shut down the workflow

    //--this will also prevent wf running / new tasks being created when the RITM is closed

    var grWF = new GlideRecord('wf_context');

    grWF.addActiveQuery();

    grWF.setLimit(4);

    grWF.addQuery('id', RITM_sysid);

    grWF.query();


    while (grWF.next()) {

grWF.setWorkflow(true);

        grWF.state = 'cancelled';

        grWF.active = false;

        var cancel_sysid = grWF.update();


        log.info('onbefore script: trMap:BULK CLOSE sc task NO NOTIFICATIONS:: cancelled workflow context ' + cancel_sysid + '; ' + target.number);

kill_executing_activities(grWF.sys_id);

    }

}


function kill_executing_activities(wf_context){


var grWFA= new GlideRecord('wf_executing');

grWFA.setLimit(10);

grWFA.addQuery('context', wf_context);

grWFA.addQuery('state', 'waiting');

grWFA.query();

while (grWFA.next()){

grWFA.state='cancelled';

var cancel_sysid= grWFA.update();

log.info('onbefore script: trMap:BULK CLOSE sc task NO NOTIFICATIONS:: cancelled workflow executing activity ' + cancel_sysid + '; ' + target.number);


}

}

onafter script

(function runTransformScript(source, map, log, target /*undefined onStart*/ ) {


    //--close any related records:

    var sSourceCN = source.u_close_note.toString();

    var sCloseNote = "sc task bulk closed via transform map [BULK CLOSE sc task NO NOTIFICATIONS]";

    if (sSourceCN != "") {

        sCloseNote = sSourceCN;

    }



    var sys_id_ritm = target.sys_id;

    //--close any active tasks:

    closeTasks(sys_id_ritm, sCloseNote);

    //--close any active approvals:

    closeApprovals(sys_id_ritm);

    //--close parent REQ:

    closeREQ(target.sys_id, target.request);


    updateWorkNotes(sys_id_ritm, sCloseNote); //--for some reason, struggling to get the field map to work!



})(source, map, log, target);


function closeTasks(RITM_sysid, close_note) {

    var grTasks = new GlideRecord('sc_task');

    grTasks.addActiveQuery();

    grTasks.setLimit(5);

    grTasks.addQuery('request_item', RITM_sysid);

    grTasks.query();

    while (grTasks.next()) {

        grTasks.close_notes = close_note;

        grTasks.state = "7"; //--closed cancelled

        grTasks.active = false;

        grTasks.update();


        log.info('onafter script: trMap:BULK CLOSE sc task NO NOTIFICATIONS:: task closed ' + grTasks.number + '; ' + target.number);

    }

}


function closeREQ(RITM_sys_id, REQ_sysid) {

    //--only shut down the parent REQ if no other RITMs associated (bundled RITMs could still be open)

    var grRITMs = new GlideRecord('sc_req_item');

    grRITMs.addActiveQuery();

    grRITMs.addQuery('sys_id', '!=', RITM_sys_id);

    grRITMs.addQuery('request', REQ_sysid);

    grRITMs.query();

    if (grRITMs.getRowCount() < 1) {


        var grREQ = new GlideRecord('sc_request');

        grREQ.addActiveQuery();

        grREQ.addQuery('sys_id', REQ_sysid);

        grREQ.query();

        if (grREQ.next()) {

            grREQ.request_state = 'closed_cancelled';

            grREQ.active = false;

            grREQ.update();


            log.info('onafter script: trMap:BULK CLOSE sc task NO NOTIFICATIONS:: request closed ' + grREQ.number + '; ' + target.number);

        }

    }

}


function closeApprovals(RITM_sysid) {

    var grAppr = new GlideRecord('sysapproval_approver');

    grAppr.setLimit(50);

    grAppr.addActiveQuery();

    grAppr.addQuery('sysapproval', RITM_sysid);

    grAppr.addQuery('state', 'requested');

    grAppr.query();

    while (grAppr.next()) {

        grAppr.state = 'cancelled';

        grAppr.active = false;

        grAppr.update();


        log.info('onafter script: trMap:BULK CLOSE sc task NO NOTIFICATIONS:: approval closed ' + grAppr.sys_id + '; ' + target.number);

    }

}


function updateWorkNotes(RITM_sysid, work_note) {

    var grRITM = new GlideRecord('sc_req_item');

    if (grRITM.get('sys_id', RITM_sysid)) {

        //grRITM.comments='COMMENT: '+work_note;

        grRITM.work_notes = 'RITM closed via transform map, task close note: ' + work_note;

        grRITM.update();

    }

}


Comments

Popular posts from this blog

ServiceNow check for null or nil or empty (or not)

Haven't tested these all recently within global/local scopes, so feel free to have a play! option 1 use an encoded query embedded in the GlideRecord , e.g.  var grProf = new GlideRecord ( 'x_cls_clear_skye_i_profile' ); grProf . addQuery ( 'status=1^ owner=NULL ' ); grProf . query (); even better use the glideRecord  addNotNullQuery or addNullQuery option 2 JSUtil.nil / notNil (this might be the most powerful. See this link ) example: if ( current . operation () == 'insert' && JSUtil . notNil ( current . parent ) && ! current . work_effort . nil ())  option 3 there might be times when you need to get inside the GlideRecord and perform the check there, for example if the code goes down 2 optional routes depending on null / not null can use gs.nil : var grAppr = new GlideRecord ( 'sysapproval_approver' ); var grUser = new GlideRecord ( 'sys_user' ); if ( grUser . get ( 'sys_id' , current . approver )){...

Code a pause/wait - gs.sleep or gs.wait alternative, pause script for specified seconds (timer)

Code a pause/wait - gs.sleep / gs.wait alternative, pause script for specified seconds (timer)  e.g. 10 seconds: do_sleep ( 10000 ); function do_sleep ( milliseconds ) { var start = new Date (). getTime (); for ( var i = 0 ; i < 1e7 ; i ++) { if (( new Date (). getTime () - start ) > milliseconds ){ gs . print ( 'waking up!' ); break ; } } }