Interested in a ServiceNow event built for developers? Registration for now[dev]26 is officially open!

Catalog Item testing - RITM Printer

andersonk17474
Tera Contributor

I regularly want to test multiple catalog items quickly without having to manually submit a bunch of forms.  I present to you all...<drum roll>... the RITM printer.  Enjoy.  Note: this script was created using AI.

 

// ======================================================
// RITM PRINTER
// Sept 1 2026
//
// Purpose:
// Clone a catalog request from an existing RITM using
// CartJS and return the resulting REQ/RITM.
//
// Usage:
// 1. Specify a source RITM.
// 2. Leave fieldList empty to copy ALL variables.
// 3. Populate fieldList to copy ONLY selected variables.
//
// Notes:
// - Assumes one RITM per request.
// - Structured for easy migration into a Script Include.
// ======================================================

var DEBUG = true;

var sourceRitmNumber = 'RITM0XXXXX'; // Update, ex: RITM0123456

/*
 * Leave empty to copy ALL variables
 */
var fieldList = [];

/*
 * Example CONA Feature field list:
 *
 * var fieldList = [
 *     'v_requestor',
 *     'v_director',
 *     'v_cost_center',
 *     'v_description',
 *     'v_approvers_list',
 *     'v_watchlist',
 *     'v_estimated_save_amt',
 *     'v_roi_estimate',
 *     'v_is_budgeted',
 * ];
 */

run();

/**
 * Debug logger.
 *
 * @Param {String} message
 */
function debug(message) {

    if (DEBUG)
        gs.print('[DEBUG] ' + message);

}


/**
 * Main execution entry point.
 *
 * @returns {void}
 */
function run() {

    var sourceRitm =
        getRitm(sourceRitmNumber);

    if (!sourceRitm)
        return;

    var variables =
        buildVariableMap(
            sourceRitm,
            fieldList
        );

    var result =
        submitRequest(
            sourceRitm.cat_item.toString(),
            variables
        );

    printResults(
        sourceRitm,
        result
    );
}


/**
 * Retrieves source RITM.
 *
 * @Param {String} ritmNumber
 * @returns {GlideRecord|null}
 */
function getRitm(ritmNumber) {

    var ritm =
        new GlideRecord('sc_req_item');

    ritm.addQuery(
        'number',
        ritmNumber
    );

    ritm.query();

    if (!ritm.next()) {

        gs.error(
            'Source RITM not found: ' +
            ritmNumber
        );

        return null;
    }

    return ritm;
}


/**
 * Builds variable payload.
 *
 * @Param {GlideRecord} ritm
 * @Param {Array} fieldList
 * @returns {Object}
 */
function buildVariableMap(
    ritm,
    fieldList
) {

    var variables = {};

    if (
        !fieldList ||
        fieldList.length === 0
    ) {

        debug(
            'Copying ALL variables.'
        );

        var vars =
            ritm.variables.getElements();

        for (
            var i = 0;
            i < vars.length;
            i++
        ) {

            var fieldName =
                vars[i].getName();

            variables[fieldName] =
                ritm.variables[fieldName]
                    .toString();

            debug(
                fieldName +
                ' = ' +
                variables[fieldName]
            );
        }

        return variables;
    }

    debug(
        'Copying SELECTED variables.'
    );

    for (
        var x = 0;
        x < fieldList.length;
        x++
    ) {

        var fieldName =
            fieldList[x];

        if (
            ritm.variables[fieldName] !==
            undefined
        ) {

            variables[fieldName] =
                ritm.variables[fieldName]
                    .toString();

            debug(
                fieldName +
                ' = ' +
                variables[fieldName]
            );

        } else {

            debug(
                'Variable not found: ' +
                fieldName
            );
        }
    }

    return variables;
}


/**
 * Submit request using CartJS.
 *
 * @Param {String} catItemSysId
 * @Param {Object} variables
 * @returns {Object}
 */
function submitRequest(
    catItemSysId,
    variables
) {

    debug(
        'Submitting catalog item: ' +
        catItemSysId
    );

    debug(
        'Variable Payload:\n' +
        JSON.stringify(
            variables,
            null,
            2
        )
    );

  var cartName = 'RITM_PRINTER_' + gs.generateGUID();
  var cart = new sn_sc.CartJS(cartName);

    var cartDetails =
        cart.addToCart({
            sysparm_id: catItemSysId,
            sysparm_quantity: '1',
            variables: variables
        });

    debug(
        'addToCart() Response:\n' +
        JSON.stringify(
            cartDetails,
            null,
            2
        )
    );

    debug(
        'Cart ID: ' +
        cart.getCartID()
    );

    var cartItems =
        cart.getCartItems();

    while (cartItems.next()) {

        debug(
            'Cart Item: ' +
            cartItems.cat_item.getDisplayValue() +
            ' Qty=' +
            cartItems.quantity
        );
    }

    var request = {
      sysparm_id: catItemSysId,
      sysparm_quantity: '1',
      variables: variables
   };

    var cartResult = cart.submitOrder({ requested_for: gs.getUserID() });

    debug(
        'checkoutCart() Response:\n' +
        JSON.stringify(
            cartResult,
            null,
            2
        )
    );

    return {
        cart: cartResult,
        ritm: getGeneratedRitm(
            cartResult.request_id
        )
    };
}


/**
 * Look up generated RITM.
 *
 * @Param {String} requestSysId
 * @returns {Object}
 */
function getGeneratedRitm(
    requestSysId
) {

    var result = {
        number: '',
        sys_id: ''
    };

    if (!requestSysId) {

        debug(
            'No request_id returned from CartJS.'
        );

        return result;
    }

    debug(
        'Searching for request: ' +
        requestSysId
    );

    gs.sleep(5000);

    var ritm =
        new GlideRecord('sc_req_item');

    ritm.addQuery(
        'request',
        requestSysId
    );

    ritm.orderByDesc(
        'sys_created_on'
    );

    ritm.query();

    if (ritm.next()) {

        result.number =
            ritm.number.toString();

        result.sys_id =
            ritm.sys_id.toString();

        debug(
            'Generated RITM Found: ' +
            result.number
        );

    } else {

        debug(
            'No generated RITM found.'
        );
    }

    return result;
}


/**
 * Print execution results.
 *
 * @Param {GlideRecord} sourceRitm
 * @Param {Object} result
 * @returns {void}
 */
function printResults(
    sourceRitm,
    result
) {

    var baseUrl =
        gs.getProperty(
            'glide.servlet.uri'
        );

    debug(
        'Final Result Object:\n' +
        JSON.stringify(
            result,
            null,
            2
        )
    );

    gs.print('');
    gs.print('========================================');
    gs.print('RITM PRINTER COMPLETE');
    gs.print('========================================');

    gs.print(
        'SOURCE RITM : ' +
        sourceRitm.number
    );

    gs.print(
        'SOURCE ITEM : ' +
        sourceRitm.cat_item.getDisplayValue()
    );

    if (
        result.cart &&
        result.cart.request_number
    ) {

        gs.print('');

        gs.print(
            'NEW REQ     : ' +
            result.cart.request_number
        );

        gs.print(
            'REQ URL     : ' +
            baseUrl +
            'sc_request.do?sys_id=' +
            result.cart.request_id
        );

        if (
            result.ritm &&
            result.ritm.number
        ) {

            gs.print('');

            gs.print(
                'NEW RITM    : ' +
                result.ritm.number
            );

            gs.print(
                'RITM URL    : ' +
                baseUrl +
                'sc_req_item.do?sys_id=' +
                result.ritm.sys_id
            );
        }

    } else {

        gs.print(
            '[WARN] CartJS did not return a REQ.'
        );

        gs.print(
            JSON.stringify(
                result,
                null,
                2
            )
        );
    }

    gs.print('========================================');
}

 

0 REPLIES 0