How to create a copy case UI action

Daniel R2
Kilo Sage

Hi,

 

We are currently trying to create a UI action to appear in CSM/FSM Workspace, that copies a case and creates a new case with the same information.

 

We have added the following script to the 'Workspace Client Script' field on the UI Action

 

 

var gr = current.sys_id.toString();
var newCase = new GlideRecord('sn_customerservice_case');
newCase.initialize();

newCase.from_email = current.from_email;
newCase.short_description = current.short_description;
newCase.company = current.company;
newCase.category = current.category;
newCase.subcategory = current.subcategory;
newCase.email_body = current.email_body;
newCase.work_notes = "Copied from Case " + current.number;
newCase.insert();

 

 

However, our cases are attached to a variety of tables extended from the 'sn_customerservice_cases' table. The new copied cases should be created on the exact same table as the original case. How can I ensure It is created on the same table, from one UI action

7 REPLIES 7

@Daniel R2 

that's correct. unless you have the record sysId you cannot copy

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader

@Ankur Bawiskar - How can we achieve copying the attachments otherwise?

Ramya V
Kilo Sage

Creating a "Copy Case" UI Action in CSM/FSM Workspace

The following code enables a "Copy Case" UI action in CSM/FSM Workspace, which duplicates a case and creates a new one with the same information. It also handles attachments: if the source record has attachments, the system prompts the user to copy them. If confirmed, the attachments are copied to the new case.

Prerequisites

  1. Ensure that Client Callable is set to true in the Script Include.
  2. Create a system property (sys_properties.list):
    • Name: sn_customerservice_case.copy_attach
    • Value: true
    • This property determines whether attachments should be copied when duplicating a case by default.
  3. Script Include

    Ensure that Client Callable is set to true in the script include.

    var CopyCaseUtils = Class.create();

    CopyCaseUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    // Function to copy a case
    copyCase: function() {
    var srcSysId = this.getParameter('sysparm_sys_id');
    var fields = JSON.parse(this.getParameter('sysparm_fields') || '{}');
    var result = '';

    if (!srcSysId) {
    gs.error('sys_id is undefined or invalid');
    return result;
    }

    var sourceGR = new GlideRecord('sn_customerservice_case');
    if (!sourceGR.get(srcSysId)) {
    gs.error('Case not found for sys_id: ' + srcSysId);
    return result;
    }

    var targetGR = new GlideRecord('sn_customerservice_case');
    targetGR.initialize();

    // Copy specific fields
    var copyFields = ['short_description', 'description', 'contact', 'account', 'business_service', 'u_child_service', 'service_offering', 'priority', 'email_body'];
    copyFields.forEach(function(field) {
    if (sourceGR.isValidField(field)) {
    targetGR.setValue(field, sourceGR.getValue(field));
    }
    });

    // Work notes indicating the case was copied
    targetGR.work_notes = "Copied from Case " + sourceGR.number;

    // Apply UI-provided field values
    for (var fieldName in fields) {
    if (targetGR.isValidField(fieldName)) {
    targetGR.setValue(fieldName, fields[fieldName]);
    }
    }

    // Insert the new case
    var newSysId = targetGR.insert();
    if (newSysId) {
    // Copy attachments if requested
    if (fields.include_attachments === true || fields.include_attachments === 'true') {
    var attachResult = this._copyAttachments(srcSysId, newSysId);
    gs.info("Attachment copy result: " + attachResult);
    }
    result = newSysId + '';
    } else {
    gs.error('Failed to insert new case.');
    }

    return result;
    },

    // Function to copy attachments using GlideSysAttachment
    _copyAttachments: function(sourceSysId, targetSysId) {
    try {
    var attachment = new GlideSysAttachment();
    var copiedAttachments = attachment.copy('sn_customerservice_case', sourceSysId, 'sn_customerservice_case', targetSysId);
    if (copiedAttachments) {
    gs.info("Successfully copied " + copiedAttachments + " attachments from Case: " + sourceSysId + " to Case: " + targetSysId);
    return "Successfully copied attachments.";
    } else {
    gs.error("No attachments copied from Case: " + sourceSysId);
    return "No attachments copied.";
    }
    } catch (e) {
    gs.error("Error while copying attachments: " + e);
    return "Error copying attachments.";
    }
    },

    // Function to check if the case has attachments
    getCaseCopyAttachDetails: function() {
    var srcSysId = this.getParameter('sysparm_sys_id');
    var gr = new GlideRecord('sn_customerservice_case');

    if (gr.get(srcSysId)) {
    var answer = {};
    answer.hasAttachments = gr.hasAttachments();
    answer.copyAttachProp = gs.getProperty('sn_customerservice_case.copy_attach', 'true') === 'true';
    return JSON.stringify(answer);
    }

    return '';
    },

    type: 'CopyCaseUtils'

    });

  4. UI Action (Workspace Client Script):

    function onClick(g_form) {
    // Create the fields array to hold the form fields for the modal
    var fields = [];

    // Call the Script Include to get the attachment details for the case
    var ga = new GlideAjax('CopyCaseUtils');
    ga.addParam('sysparm_name', 'getCaseCopyAttachDetails');
    ga.addParam('sysparm_sys_id', g_form.getUniqueValue()); // Pass the sys_id of the case being copied

    ga.getXMLAnswer(function(response) {
    response = JSON.parse(response + '');

    if (response && response.hasAttachments) {
    // If the case has attachments, ask if they should be copied
    fields.push({
    type: 'boolean',
    name: 'include_attachments',
    label: 'Include attachments', // Set label directly
    mandatory: false,
    value: response.copyAttachProp === "true" ? true : false,
    referringTable: 'sn_customerservice_case',
    referringRecordId: g_form.getUniqueValue()
    });
    }

    // Show a modal where the user can confirm the copy operation
    g_modal.showFields({
    title: 'Copy Case',
    size: "md",
    fields: fields,
    confirmTitle: 'Copy',
    confirmType: "confirm",
    instruction: 'Create a new case by copying the current case.'
    }).then(function(fieldValues) {
    var updatedFields = {};

    // Process the updated field values
    fieldValues.updatedFields.forEach(function(field) {
    updatedFields[field.name] = field.value;
    });

    // Call the Script Include to perform the case copy
    ga = new GlideAjax('CopyCaseUtils');
    ga.addParam('sysparm_name', 'copyCase');
    ga.addParam('sysparm_sys_id', g_form.getUniqueValue()); // Pass the sys_id of the case
    ga.addParam('sysparm_fields', JSON.stringify(updatedFields)); // Pass the updated fields

    ga.getXMLAnswer(function(response) {
    if (response + '' !== "false") {
    // If the copy was successful, open the new case
    g_aw.openRecord("sn_customerservice_case", response + "");
    } else {
    // If it failed, show an error message
    g_form.addErrorMessage('Failed to copy Case.');
    }
    });
    });
    });
    }

    Please mark my answer as helpful if this solution works for you.