- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
a month ago
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)
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
4 weeks ago
Hi @msomasekhar
I believe you are after this on the finance case for sn_fin_ops.admin role.
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
40onsn_spend_sdc_service_request— verify against your instance choices
Please award kudos if helpful.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
4 weeks ago
@msomasekhar If the intercompany case table is a new scoped application that extends the finance case, then the existing “cancel case” logic provided will automatically apply to any child tables within the Finance Operations workspace through inheritance.
