logo

NJP

Easily Move Customer Updates Between Update Sets

ServiceNow Guru · Jul 26, 2024 · article

As ServiceNow developers, we often encounter scenarios where we need to migrate configurations from one update set to another. Traditionally, this involves manually editing each customer update record to change its update set, which can be tedious and time-consuming, especially when dealing with a large number of updates.

This article demonstrates how to streamline this process by creating a UI Action that allows you to move multiple customer updates between update sets with a single click.

Problem Statement

When you make configurations in your instance, there are times when you need to move these updates to a different update set. The conventional method requires opening each customer update record individually and changing the update set field to the desired update set. This method becomes impractical when dealing with numerous updates.

Solution

To overcome this challenge, you can create a UI Action that facilitates the movement of multiple customer updates to another update set in one go. This approach not only saves time but also reduces the risk of manual errors.

To begin, navigate to System Definition > UI Actions and create a new UI Action:

UI Action

Name: Move Updates to Current US

Table: sys_update_xml

Action Name: move_updates_to_current_us

Show insert: true

Show update: true

Client: true

List v2 Compatible: true

List Choice: true

Onclick: showConfirmDialog()

Script:

function showConfirmDialog() {

var entries = g_list.getChecked();
if (!entries || entries.length == 0)
    return;

// this function runs when the modal close
var callback = function () {

    // To send parameters to the server script we should use GlideAjax
    var ga = new GlideAjax('MoveUpdatesToCurrentUS');
    ga.addParam('sysparm_name', 'moveEntries');
    ga.addParam('sysparm_entry_ids', entries);

    // GlideAjax callback to refresh the related list
    var afterMove = function () {
        GlideList2.get(g_form.getTableName() + '.sys_update_xml.update_set').setFilterAndRefresh('');
    };

    ga.getXMLAnswer(afterMove.bind(this));
    return true;
};

var dialogClass = window.GlideModal ? GlideModal : GlideDialogWindow;
var dialog = new dialogClass('glide_confirm_standard');
dialog.setTitle(new GwtMessage().getMessage('Confirmation'));
dialog.setPreference('warning', true);
dialog.setPreference('title', new GwtMessage().getMessage('move_update_set_entries'));
dialog.setPreference('onPromptComplete', callback.bind(this));
dialog.render();

}

Two points I would like to highlight in this script.

– As we need to pass the selected records as a parameter to the server script, we need to use GlideAjax.

– For the callback function I needed to update only the related list. Initially I could only update the entire record but a quick search here on the portal led me to an article explaining exactly what I needed.

For the modal message to be displayed correctly, we need to create a record in the sys_ui_message table with the text we want. Navigate to System UI > Messages and create a new message:

Now we need to create the Script Include that will perform all the necessary validations and actions. Navigate to System Definition> Script Includes and create a new script:

Script Include

Name: MoveUpdatesToCurrentUS

Accessible from: All application scopes

Client callable: true

Active: true

Description: Ajax helper class for helping the [Move Updates to Current US] UI action

Script:

var MoveUpdatesToCurrentUS = Class.create();

MoveUpdatesToCurrentUS.prototype = Object.extendsObject(AbstractAjaxProcessor, {

moveEntries: function () {

    var arrMoved = [];
    var objMoved = {};
    var arrNotMoved = [];
    var objNotMoved = {};
    var currUS_ID = '';
    var customUpdateLink = '';
    var customUpdateType = '';
    var baseURL = gs.getProperty('glide.servlet.uri');

    //create a link to the syslog to return the logs created by this SI on last 15 minutes 
    var sysLogQuery = 'sys_created_onONLast 15 minutes@javascript:gs.beginningOfLast15Minutes()@javascript:gs.endOfLast15Minutes()^messageLIKEMoveUpdatesToCurrentUS';
    sysLogQuery = encodeURIComponent(sysLogQuery); //https://www.w3schools.com/jsref/jsref_encodeuricomponent.asp
    var sysLogURL = baseURL + 'syslog_list.do?sysparm_query=' + sysLogQuery;

    // get the user current US
    var currUS = gs.getPreference('sys_update_set');
    var grUS = new GlideRecord('sys_update_set');       

    if (grUS.get(currUS)) {
        currUS_ID = grUS.getUniqueValue();
    } else {
        gs.info('[MoveUpdatesToCurrentUS] Error: Unable to get Current US.');
        gs.addErrorMessage('There was an error. Please review the <a href="http://'%20+%20sysLogURL%20+%20'">system logs</a> for more details.');
        return false;
    }

    // get the variable sent by the UI Action
    var entries = this.getParameter('sysparm_entry_ids');

    //get all selected custom updates
    var customUpGr = new GlideRecord('sys_update_xml');
    customUpGr.addEncodedQuery('sys_idIN' + entries);
    customUpGr.query();

    while (customUpGr.next()) {

        //check if the user can write in the table
        if (customUpGr.canWrite()) {

            //create a link to the current update and get its type
            customUpdateLink = baseURL + 'sys_update_xml.do?sys_id=' + customUpGr.getValue('sys_id');
            customUpdateType = customUpGr.getValue('type');

            // check if it trying to move do a diferent US
            if (customUpGr.getValue('update_set') == currUS_ID) {

                objNotMoved = {
                    sys_id: customUpGr.getUniqueValue(),
                    reasonHTML: 'Custom US <a href="http://'%20+%20customUpdateLink%20+%20'">' + customUpdateType + '</a> is already in your currently US.',
                    reasonText: 'Custom US ' + customUpdateType + ' - ' + customUpGr.getValue('sys_id') + ' - is already in your currently US.'
                };

                arrNotMoved.push(objNotMoved);

            } else {

                // move the customer update to de current US
                try {

                    customUpGr.setValue('update_set', currUS);
                    customUpGr.update();

                    objMoved = {
                        sys_id: customUpGr.getUniqueValue(),
                        reasonHTML: 'Custom US <a href="http://'%20+%20customUpdateLink%20+%20'">' + customUpdateType + '</a> was moved to your currently US.',
                        reasonText: 'Custom US ' + customUpdateType + ' - ' + customUpGr.getValue('sys_id') + ' - was moved to your currently US.'
                    };

                    arrMoved.push(objMoved);

                } catch (e) {

                    objNotMoved = {
                        sys_id: customUpGr.getUniqueValue(),
                        reasonHTML: 'Unable to move the Custom US <a href="http://'%20+%20customUpdateLink%20+%20'">' + customUpdateType + '</a> due: ' + e,
                        reasonText: 'Unable to move the Custom US ' + customUpdateType + ' - ' + customUpGr.getValue('sys_id') + ' - due: ' + e
                    };

                    arrNotMoved.push(objNotMoved);

                }

            }               

        } else {

            objNotMoved = {
                sys_id: customUpGr.getUniqueValue(),
                reasonHTML: 'Unable to move the Custom US <a href="http://'%20+%20customUpdateLink%20+%20'">' + customUpdateType + '</a> due to ACL restrictions.',
                reasonText: 'Unable to move the Custom US ' + customUpdateType + ' - ' + customUpGr.getValue('sys_id') + ' - due to ACL restrictions.'          
            };

            arrNotMoved.push(objNotMoved);

        }           

    }

    // create 2 messages: one to the syslog and one to show to user
    var sysLogMessage = '[MoveUpdatesToCurrentUS]' + '\r\r';

    if (arrMoved.length > 0) {

        var successScreenMessage = 'Move Updates to Current US Action' + '<br><br>';

        sysLogMessage += 'Custom Updates moved:\r';
        successScreenMessage += 'Custom Updates moved:<br>';

        for (var i = 0; i < arrMoved.length; i++) {
            sysLogMessage += arrMoved[i].reasonText + '\r';
            successScreenMessage += arrMoved[i].reasonHTML + '<br>';
        }

        gs.addInfoMessage(successScreenMessage);

    }

    if (arrNotMoved.length > 0) {

        var failureScreenMessage = 'Move Updates to Current US Action' + '<br><br>';

        sysLogMessage += '\r\rCustom Updates NOT moved:\r';
        failureScreenMessage += 'Custom Updates NOT moved:<br>';

        for (var x = 0; x < arrNotMoved.length; x++) {
            sysLogMessage += arrNotMoved[x].reasonText + '\r';
            failureScreenMessage += arrNotMoved[x].reasonHTML + '<br>';
        }

        gs.addErrorMessage(failureScreenMessage);

    }       

    gs.info(sysLogMessage);

    gs.addInfoMessage('Customer Update(s) transfer has been completed. Please review the <a href="http://'%20+%20sysLogURL%20+%20'">system logs</a> for more details.');

    return true;

},

type: 'MoveUpdatesToCurrentUS'

});

Using

  • Open the update set from which you want to move few customer updates
  • Go to the Customer Updates Related List
  • Select all the updates you want to move
  • Click on [Move Updates to Current US] in the actions dropdown menu

  • If everything works fine all selected customer updates have been moved to your Current US and you will see a message – simple as that.

  • If any problems occur during the transfer, you will be notified.

  • Everything will be recorded in syslog

Benefits

  • Efficiency: Moves multiple updates simultaneously, significantly reducing the time required.
  • Accuracy: Minimizes the risk of errors associated with manual updates.
  • Usability: Provides a straightforward and user-friendly method for managing update sets.

By implementing this UI Action, you can enhance your productivity and ensure a smoother workflow when managing update sets in ServiceNow. This method is particularly beneficial in complex development environments where rapid and accurate configuration management is essential.

The post Easily Move Customer Updates Between Update Sets appeared first on ServiceNow Guru.

View original source

https://servicenowguru.com/system-definition/easily-move-customer-updates-between-update-sets/