Allow Cancel Active Cases with reason

msomasekhar
Tera Contributor

Hi Team, I need to allow below requirement Could you please help me on this .

 

As an finance admin
I want the ability to cancel an active  case from the workspace (Finance Operation Workspace) 

finance admin need the ability to terminate an active Inter company Balance Confirmation process when the case should no longer proceed.

 

A workspace action shall be provided that allows authorized users to cancel an active case. Prior to cancellation, the user must provide a cancellation reason. The reason shall be recorded on the case and the case state shall be transitioned to Cancelled.


--- Authorized Users ---

Only users with the Finace admin role shall be permitted to cancel  cases.

 

--- Eligible Cases ---

The Cancel action shall only be available when the case is in an active/open state.

The action shall not be available for:

Cancelled cases
Closed cases

 

--- Cancellation Reason ---

A cancellation reason shall be required before the cancellation can be completed.

--- Auditability ---

The cancellation reason shall be recorded within the case activity/history by posting to the Comments field.


### Workspace Action ###

--- Button Label ---

Cancel Case

--- Modal Title ---

Cancel Intercompany Case

--- Modal Fields ---
Cancellation Reason (required)

 

1 ACCEPTED SOLUTION

TroyP0581187515
ServiceNow Employee

Hi @msomasekhar 
I believe you are after this on the finance case for sn_fin_ops.admin role. 

TroyP0581187515_0-1790256077820.png

Here are the steps to achieve this. 

 

Setup

1. Script Include — ExtFinanceCaseService
Extends sn_fin_ops.FinanceCaseService. Create in sn_fin_ops scope, Accessible from = All application scopes.

 

var ExtFinanceCaseService = Class.create();
ExtFinanceCaseService.prototype = Object.extendsObject(sn_fin_ops.FinanceCaseService, {

    type: 'ExtFinanceCaseService',

    showCancelCaseUIAction: function(caseRecord) {
        if (gs.nil(caseRecord) || Object.keys(caseRecord).length == 0 || !caseRecord.canWrite())
            return false;
        var inactiveStates = ['40', '50', '60'];
        return gs.hasRole('sn_fin_ops.admin') &&
               inactiveStates.indexOf(caseRecord.getValue('state')) == -1;
    },

    cancelCase: function(caseRecord, cancellationReason) {
        if (gs.nil(caseRecord) || Object.keys(caseRecord).length == 0 || !caseRecord.canWrite())
            return;
        caseRecord.setValue('state', '40');
        caseRecord.comments = cancellationReason;
        caseRecord.update();
    },

    performUIAction: function(caseRecord, uiAction) {
        var extActionMap = {
            CANCEL_CASE: this.cancelCase.bind(this)
        };
        if (extActionMap[uiAction])
            return extActionMap[uiAction](caseRecord);
        return this.super.performUIAction.call(this, caseRecord, uiAction);
    }

});


2. Script Include — ExtFCMAjaxUtil
Extends sn_fin_ops.FCMAjaxUtil. Create in sn_fin_ops scope, Accessible from = All application scopes, Client callable = true.

var ExtFCMAjaxUtil = Class.create();
ExtFCMAjaxUtil.prototype = Object.extendsObject(sn_fin_ops.FCMAjaxUtil, {

    type: 'ExtFCMAjaxUtil',

    ajaxCancelCase: function() {
        var caseId = this.getParameter('sysparm_case_sys_id');
        var cancellationReason = this.getParameter('sysparm_cancellation_reason');
        var caseRecord = new GlideRecord('sn_spend_sdc_service_request');
        if (!caseRecord.get(caseId)) {
            this.newItem().setAttribute('result', 'false');
            return;
        }
        var svc = new sn_fin_ops.ExtFinanceCaseService();
        svc.cancelCase(caseRecord, cancellationReason);
        this.newItem().setAttribute('result', 'true');
    }

});

 

3. UI Action

Field Value
Name Cancel Case
Table sn_spend_sdc_service_request
Active true
Show in Workspace true
Client true
Action name cancel_case
Show insert false
Show update true
Condition new sn_fin_ops.ExtFinanceCaseService().showCancelCaseUIAction(current)

 

Script:

if (typeof window == 'undefined') {
    var reason = current.getValue('comments');
    new sn_fin_ops.ExtFinanceCaseService().cancelCase(current, reason);
    gs.addInfoMessage(gs.getMessage('Case {0} has been cancelled', 
        [current.getDisplayValue('number')]));
    action.setRedirectURL(current);
}

 

Workspace Client Script:

function onClick(g_form) {

    function cancelCase(cancellationReason) {
        var ga = new GlideAjax('sn_fin_ops.ExtFCMAjaxUtil');
        ga.addParam('sysparm_name', 'ajaxCancelCase');
        ga.addParam('sysparm_case_sys_id', g_form.getUniqueValue());
        ga.addParam('sysparm_cancellation_reason', cancellationReason);
        ga.getXMLAnswer(function() {
            g_form.reload();
        });
    }

    var fields = [{
        type: 'textarea',
        name: 'cancellation_reason',
        label: getMessage('Cancellation Reason'),
        mandatory: true
    }];

    g_modal.showFields({
        title: getMessage('Cancel Finance Case'),
        confirmTitle: getMessage('Cancel Case'),
        instruction: getMessage('Please provide a reason for cancelling this case.'),
        fields: fields,
        size: 'md'
    }).then(function(fieldValues) {
        var cancellationReason = fieldValues.updatedFields[0].value;
        cancelCase(cancellationReason);
    });
}

 

Key points

  • Both SIs extend OOB classes — upgrade safe, no OOB modifications
  • Role check uses sn_fin_ops.admin — update to match your instance role if you have created child finance case tables
  • Cancelled state value is 40 on sn_spend_sdc_service_request — verify against your instance choices

Please award kudos if helpful.

View solution in original post

5 REPLIES 5

Mark Manders
Tera Patron

You provided the entire solution. What is your question?


Please mark any helpful or correct solutions as such. That helps others find their solutions.
Mark

Hi @Mark Manders I need to achive that by doing development on how to do part i stuck .Could you please provide guidelines or steps to achive this ?

 

TroyP0581187515
ServiceNow Employee

Hi @msomasekhar 
I believe you are after this on the finance case for sn_fin_ops.admin role. 

TroyP0581187515_0-1790256077820.png

Here are the steps to achieve this. 

 

Setup

1. Script Include — ExtFinanceCaseService
Extends sn_fin_ops.FinanceCaseService. Create in sn_fin_ops scope, Accessible from = All application scopes.

 

var ExtFinanceCaseService = Class.create();
ExtFinanceCaseService.prototype = Object.extendsObject(sn_fin_ops.FinanceCaseService, {

    type: 'ExtFinanceCaseService',

    showCancelCaseUIAction: function(caseRecord) {
        if (gs.nil(caseRecord) || Object.keys(caseRecord).length == 0 || !caseRecord.canWrite())
            return false;
        var inactiveStates = ['40', '50', '60'];
        return gs.hasRole('sn_fin_ops.admin') &&
               inactiveStates.indexOf(caseRecord.getValue('state')) == -1;
    },

    cancelCase: function(caseRecord, cancellationReason) {
        if (gs.nil(caseRecord) || Object.keys(caseRecord).length == 0 || !caseRecord.canWrite())
            return;
        caseRecord.setValue('state', '40');
        caseRecord.comments = cancellationReason;
        caseRecord.update();
    },

    performUIAction: function(caseRecord, uiAction) {
        var extActionMap = {
            CANCEL_CASE: this.cancelCase.bind(this)
        };
        if (extActionMap[uiAction])
            return extActionMap[uiAction](caseRecord);
        return this.super.performUIAction.call(this, caseRecord, uiAction);
    }

});


2. Script Include — ExtFCMAjaxUtil
Extends sn_fin_ops.FCMAjaxUtil. Create in sn_fin_ops scope, Accessible from = All application scopes, Client callable = true.

var ExtFCMAjaxUtil = Class.create();
ExtFCMAjaxUtil.prototype = Object.extendsObject(sn_fin_ops.FCMAjaxUtil, {

    type: 'ExtFCMAjaxUtil',

    ajaxCancelCase: function() {
        var caseId = this.getParameter('sysparm_case_sys_id');
        var cancellationReason = this.getParameter('sysparm_cancellation_reason');
        var caseRecord = new GlideRecord('sn_spend_sdc_service_request');
        if (!caseRecord.get(caseId)) {
            this.newItem().setAttribute('result', 'false');
            return;
        }
        var svc = new sn_fin_ops.ExtFinanceCaseService();
        svc.cancelCase(caseRecord, cancellationReason);
        this.newItem().setAttribute('result', 'true');
    }

});

 

3. UI Action

Field Value
Name Cancel Case
Table sn_spend_sdc_service_request
Active true
Show in Workspace true
Client true
Action name cancel_case
Show insert false
Show update true
Condition new sn_fin_ops.ExtFinanceCaseService().showCancelCaseUIAction(current)

 

Script:

if (typeof window == 'undefined') {
    var reason = current.getValue('comments');
    new sn_fin_ops.ExtFinanceCaseService().cancelCase(current, reason);
    gs.addInfoMessage(gs.getMessage('Case {0} has been cancelled', 
        [current.getDisplayValue('number')]));
    action.setRedirectURL(current);
}

 

Workspace Client Script:

function onClick(g_form) {

    function cancelCase(cancellationReason) {
        var ga = new GlideAjax('sn_fin_ops.ExtFCMAjaxUtil');
        ga.addParam('sysparm_name', 'ajaxCancelCase');
        ga.addParam('sysparm_case_sys_id', g_form.getUniqueValue());
        ga.addParam('sysparm_cancellation_reason', cancellationReason);
        ga.getXMLAnswer(function() {
            g_form.reload();
        });
    }

    var fields = [{
        type: 'textarea',
        name: 'cancellation_reason',
        label: getMessage('Cancellation Reason'),
        mandatory: true
    }];

    g_modal.showFields({
        title: getMessage('Cancel Finance Case'),
        confirmTitle: getMessage('Cancel Case'),
        instruction: getMessage('Please provide a reason for cancelling this case.'),
        fields: fields,
        size: 'md'
    }).then(function(fieldValues) {
        var cancellationReason = fieldValues.updatedFields[0].value;
        cancelCase(cancellationReason);
    });
}

 

Key points

  • Both SIs extend OOB classes — upgrade safe, no OOB modifications
  • Role check uses sn_fin_ops.admin — update to match your instance role if you have created child finance case tables
  • Cancelled state value is 40 on sn_spend_sdc_service_request — verify against your instance choices

Please award kudos if helpful.

HI @TroyP0581187515  thanks for your Detailed Solution It's really helps allot. Shall we use Same script include logic and codes to showcase Cancel case ui action for Intercompany case table?