The Zurich release has arrived! Interested in new features and functionalities? Click here for more

How to stop the SLA from server Side code ?

AbidSiddiqui
Tera Contributor

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!