Join the #BuildWithBuildAgent Challenge! Get recognized, earn exclusive swag, and inspire the ServiceNow Community with what you can build using Build Agent.  Join the Challenge.

How to stop the SLA from server Side code ?

AbidSiddiqui
Mega Guru
Mega Guru

Hi Folks,

I have implemented a Cancel button, where I’ve written server-side code to cancel the Task (sc_task).
When the Task gets cancelled, the corresponding RITM and Request also get cancelled.

The problem is — when the Task and RITM are cancelled, the associated SLAs (task and ritm) are not stopping.

In my code, I’ve used current.setWorkflow(false) because I don’t want other Business Rules to run.

Could you please guide me on how to properly stop the SLAs using server-side code in this scenario?

Here is the code from my Cancel button:

// Client-side logic
function cancelsctask() {
    if (
        //g_form.getValue('work_notes') == '' ||
        g_form.getValue('comments') == '' ||
        g_form.getValue('assigned_to') == ''
       
    ) {
        //g_form.setMandatory('work_notes', true);
        g_form.setMandatory('comments', true);
        g_form.setMandatory('assigned_to', true);
        alert('Please fill in additional comments to cancel this task');
        return false;
    } else {
        // Just submit the action, the server script handles the cancellation
        gsftSubmit(null, g_form.getFormElement(), 'cancel_sctask');
    }
}

// Server-side logic
if (typeof window == 'undefined') servercallnow();

function servercallnow() {
    try {
        current.setWorkflow(false);
        current.state = 4; // Cancelled
        current.active = false;
        current.close_code = 'Cancelled';
        current.close_notes = 'Task cancelled by fulfiller.';
        current.update();

        // // Stop SLAs for the current task
        // var sla = new SLA();
        // sla.cancelTaskSLAs(current);
       
        // Count active tasks for the same RITM
        var activeTaskCount = new GlideRecord('sc_task');
        activeTaskCount.addQuery('request_item', current.request_item);
        activeTaskCount.addQuery('active', true);
        activeTaskCount.addQuery('sys_id', '!=', current.sys_id); // Exclude current task
        activeTaskCount.query();

        var count = 0;
        while (activeTaskCount.next()) {
            count++;
        }

        if (count == 0) {
            // Cancel RITM
            var ritm = new GlideRecord('sc_req_item');
            if (ritm.get(current.request_item)) {
                ritm.setWorkflow(false);

                //cancel worflow
                var wfContext = new GlideRecord('wf_context');
    wfContext.addQuery('table', 'sc_req_item');
    wfContext.addQuery('reference', ritm.sys_id); // or 'context' depending on your data
    wfContext.query();
    while (wfContext.next()) {
        var wf = new Workflow();
        wf.cancel(wfContext);
        //gs.print('Cancelled WF: ' + wfContext.sys_id);
    }


                // Cancel Flow Designer flows
        var flowContext = new GlideRecord('sys_flow_context');
flowContext.addQuery('source_record', ritm.sys_id);
        flowContext.query();
        while (flowContext.next()) {
            flowContext.state = 'cancelled';
            flowContext.update();
        }
                ritm.state = 4;
                ritm.stage = 'Request Cancelled';
                ritm.approval = 'approved';
                ritm.work_notes = 'Cancelling RITM as task ' + current.number + ' was cancelled by fulfiller.';
                ritm.comments = current.comments;
                ritm.u_cancelled_by = 'Fulfiller';
                ritm.active = false;
                ritm.update();

                // Stop SLAs for the RITM
               
            }

            // Cancel REQ
            var req = new GlideRecord('sc_request');
            if (req.get(current.request)) {
                var activeRitm = new GlideRecord('sc_req_item');
                activeRitm.addQuery('request', req.sys_id);
                activeRitm.addQuery('active', true);
                activeRitm.query();

                var ritmCount = 0;
                while (activeRitm.next()) {
                    ritmCount++;
                }

                if (ritmCount === 0) {
                    req.setWorkflow(false);
                    req.request_state = 'closed_incomplete';
                    req.state = 4;
                    req.work_notes = 'Cancelling REQ as task ' + current.number + ' was cancelled by fulfiller and no active RITMs found.';
                    req.comments = current.comments;
                    req.active = false;
                    req.update();
                } else {
                    gs.info('REQ not cancelled as there are still active RITMs.');
                }
            }
        }

        action.setRedirectURL(current);
    } catch (e) {
        gs.error('Error during task cancellation: ' + e.message);
    }
}

 

 
3 REPLIES 3

Marcos Kassak
Kilo Sage
Kilo Sage

Hi @AbidSiddiqui,

 

Interesting setup. One thing that stands out immediately: why not handle this through Pause/Cancel conditions in the SLA definitions themselves?

 

That’s usually the cleanest way to stop SLAs when tasks or RITMs get cancelled. Instead of forcing it through code, you define a condition like state == X (for Cancelled), and the SLA engine takes care of the rest.

 

Also, worth noting, but if you’re setting current.setWorkflow(false), you’re likely bypassing any Flow/SLA updates tied to the state change. That might explain why the SLAs are still running.

 

Hope it helps you,

 

If you found my answer helpful or correct ✔️ in any way, please don't forget to mark it to help future readers! 👍

 

--

 

Kind regards,


Marcos Kassak

ServiceNow MVP 2024, 2025 
Solution Architect  🎯

Hi Marcos , 

Thanks for the response , 
Yes that is correct I am setting "current.setWorkflow(false)," because i have few BR's that i don't want to run. yes its bypassing any Flow/SLA updates state change.
Sla is not getting state change update. (in SLA we already have stop condition matching with this ).

That is why i am trying to do it by server side code.

Thanks

Hi Marcos,

Do you have any suggestions on how I should approach this?
I’m trying to handle it using server-side code in my UI action button.
While it successfully updates fields like stage (to completed) and end time, the SLA timeline still shows as running when I check it.

Thanks!