Interested in a ServiceNow event built for developers? Registration for now[dev]26 is officially open!

Disassociate approvals from workflow is not working through UI action

Majji Koteswar1
Tera Expert

We have a custom UI action "Revert to Assess" in Authorize state of a change request. We have got a requirement to make it visible in Scheduled state as well. We are able to go back to Assess state but approvals are not disassociated. The approval records are still visible in the change request. The below highlighted one is not working and even tried wf_activity as empty. It would be appreciated if someone assist me on the same.

 

Script:

var chgState = current.getValue('state');

if (chgState == '-3') { // Authorize
    current.comments = 'Change has been reverted from Authorize back to Assess';

} else if (chgState == '-2') { // Scheduled
 
    new ChangeRequestStateHandler(current).disassociateApprovalsFromWorkflow(); 

    var querystring = "state=rejected^ORstate=approved^ORstate=not requested";
    var app = new GlideRecord('sysapproval_approver');
    app.addQuery('sysapproval', current.sys_id);
    app.addEncodedQuery(querystring);
    app.query();
    while (app.next()) {
        app.setValue('state', 'not_required');
       // app.setValue('wf_activity', '');
        app.update();
    }

    var querystring2 = "approval=rejected^ORapproval=approved^ORapproval=not requested";
    var app2 = new GlideRecord('sysapproval_group');
    app2.addEncodedQuery(querystring2);
    app2.addQuery('parent', current.sys_id);
    app2.query();
    while (app2.next()) {
        app2.setValue('state', 'not_required');
       // app2.setValue('wf_activity', '');
        app2.update();
    }

    current.setValue('approval', 'not requested');
    current.setValue('u_cab_ready', false);
    current.comments = 'Change has been reverted from Scheduled back to Assess';

    var wf = new global.Workflow();
    wf.restartWorkflow(current);

}

current.setValue('state', '-4'); // Assess
current.update();
action.setRedirectURL(current);
 
Thanks,
Majji
1 REPLY 1

boteeuwen
Kilo Sage

The key part here is the order of execution. I would clean up and disassociate the approvals first, then move the change to Assess and save it, and only after that cancel or restart the workflow. That avoids the new workflow starting while the change is still in Scheduled.

Also use state on sysapproval_approver and approval on sysapproval_group, and consider setWorkflow(false) when updating those approval records so business rules do not fire unexpectedly.
I changed your script with the help of AI:

var chgState = current.getValue('state');

if (chgState == '-3') {
    // Authorize → Assess: add a comment only; no workflow manipulation is required
    current.comments = 'Change has been reverted from Authorize back to Assess';

} else if (chgState == '-2') {
    // Scheduled → Assess

    // 1. Disconnect approvals from the workflow engine
    new global.ChangeRequestStateHandler(current).disassociateApprovalsFromWorkflow();

    // 2. Set user approvals to "Not Required"
    var approverGr = new GlideRecord('sysapproval_approver');
    approverGr.addQuery('sysapproval', current.getUniqueValue());
    approverGr.addQuery('state', '!=', 'cancelled');
    approverGr.query();

    while (approverGr.next()) {
        approverGr.setValue('state', 'not_required');
        approverGr.setValue('wf_activity', '');
        approverGr.setWorkflow(false);
        approverGr.update();
    }

    // 3. Set group approvals to "Not Required"
    var groupApprovalGr = new GlideRecord('sysapproval_group');
    groupApprovalGr.addQuery('parent', current.getUniqueValue());
    groupApprovalGr.addQuery('approval', '!=', 'cancelled');
    groupApprovalGr.query();

    while (groupApprovalGr.next()) {
        groupApprovalGr.setValue('approval', 'not_required');
        groupApprovalGr.setValue('wf_activity', '');
        groupApprovalGr.setWorkflow(false);
        groupApprovalGr.update();
    }

    // 4. Reset change-level fields
    current.setValue('approval', 'not requested');
    current.setValue('u_cab_ready', false);
    current.comments = 'Change has been reverted from Scheduled back to Assess';
}

// 5. Set the state to Assess and save the change
current.setValue('state', '-4');
current.update();

// 6. Restart the workflow only after the change has been saved with state = -4
if (chgState == '-2') {
    var wf = new global.Workflow();
    wf.cancel(current);
    wf.restartWorkflow(current);
}

action.setRedirectURL(current);