Script Includes - Question Choices in variable type Select Box are not copied

kandulek
Tera Contributor

Hi All,

 

We have a UI action that copies the Catalog Item. This part of the referenced Script Includes is responsible to copy variable and its question choices. All Variables are copied, but not always its Question Choices. For variable type Multiple Choice, its Question Choices are copied successfully. When variable type is Select Box, only variable is copied but Question Choices are empty. Could somebody guide me which part might have caused the issue, and how to fix this?

  copyCatalogItem: function() {
            // Check for related records in item_option_new table
            var oCITEMItOpNeLookupGR = new GlideRecord("item_option_new");
            oCITEMItOpNeLookupGR.addQuery("cat_item", current.getUniqueValue()); // Query for records referencing the original sc_cat_item
            oCITEMItOpNeLookupGR.query();
            while (oCITEMItOpNeLookupGR.next()) {
                // Copy each related record
                var oRelatedItemOptNewGR = new GlideRecord("item_option_new");
                oRelatedItemOptNewGR.initialize();
                for (field in oCITEMItOpNeLookupGR) {
                    if (oCITEMItOpNeLookupGR.isValidField(field) && !field.startsWith("sys_")) {
                        oRelatedItemOptNewGR[field] = oCITEMItOpNeLookupGR[field];
                    }
                }
                oRelatedItemOptNewGR.cat_item = sCatItemId; // Update the sc_cat_item reference to point to the newly created record
                oRelatedItemOptNewGR.insert();
            }

            // Check for related records in question_choice table
            var oCITEMQuestionChoiceLookupGR = new GlideRecord("question_choice");
            oCITEMQuestionChoiceLookupGR.addQuery("question", oCITEMItOpNeLookupGR.getUniqueValue());
            oCITEMQuestionChoiceLookupGR.query();
            while (oCITEMQuestionChoiceLookupGR.next()) {
                // Copy each related record
                var oRelatedQuestionChoiceGR = new GlideRecord("question_choice");
                oRelatedQuestionChoiceGR.initialize();
                for (field in oCITEMQuestionChoiceLookupGR) {
                    if (oCITEMQuestionChoiceLookupGR.isValidField(field) && !field.startsWith("sys_")) {
                        oRelatedQuestionChoiceGR[field] = oCITEMQuestionChoiceLookupGR[field];
                    }
                }
                oRelatedQuestionChoiceGR.question = oRelatedItemOptNewGR.sys_id;
                oRelatedQuestionChoiceGR.insert();
            }
}

 

1 ACCEPTED SOLUTION

KeerthiP
Mega Guru

Can you check if this works. I have done few changes

 

copyCatalogItem: function() {
    // Check for related records in item_option_new table
    var oCITEMItOpNeLookupGR = new GlideRecord("item_option_new");
    oCITEMItOpNeLookupGR.addQuery("cat_item", current.getUniqueValue()); // Query for records referencing the original sc_cat_item
    oCITEMItOpNeLookupGR.query();
    var itemOptionNewMap = {}; // Map to store old and new item_option_new records

while (oCITEMItOpNeLookupGR.next()) {
        // Copy each related record
        var oRelatedItemOptNewGR = new GlideRecord("item_option_new");
        oRelatedItemOptNewGR.initialize();
        for (var field in oCITEMItOpNeLookupGR) {
            if (oCITEMItOpNeLookupGR.isValidField(field) && !field.startsWith("sys_")) {
                oRelatedItemOptNewGR[field] = oCITEMItOpNeLookupGR[field];
            }
        }
        oRelatedItemOptNewGR.cat_item = sCatItemId; // Update the sc_cat_item reference to point to the newly created record
        var newSysId = oRelatedItemOptNewGR.insert();
        itemOptionNewMap[oCITEMItOpNeLookupGR.sys_id] = newSysId; // Store old and new sys_id mapping
    }

// Check for related records in question_choice table
    var oCITEMQuestionChoiceLookupGR = new GlideRecord("question_choice");
    oCITEMQuestionChoiceLookupGR.addQuery("question", "IN", Object.keys(itemOptionNewMap));
    oCITEMQuestionChoiceLookupGR.query();

while (oCITEMQuestionChoiceLookupGR.next()) {
        // Copy each related record
        var oRelatedQuestionChoiceGR = new GlideRecord("question_choice");
        oRelatedQuestionChoiceGR.initialize();
        for (var field in oCITEMQuestionChoiceLookupGR) {
            if (oCITEMQuestionChoiceLookupGR.isValidField(field) && !field.startsWith("sys_")) {
                oRelatedQuestionChoiceGR[field] = oCITEMQuestionChoiceLookupGR[field];
            }
        }
        oRelatedQuestionChoiceGR.question = itemOptionNewMap[oCITEMQuestionChoiceLookupGR.question]; // Update the question reference to point to the newly created item_option_new record
        oRelatedQuestionChoiceGR.insert();
    }
}

View solution in original post

4 REPLIES 4

KeerthiP
Mega Guru

Can you check if this works. I have done few changes

 

copyCatalogItem: function() {
    // Check for related records in item_option_new table
    var oCITEMItOpNeLookupGR = new GlideRecord("item_option_new");
    oCITEMItOpNeLookupGR.addQuery("cat_item", current.getUniqueValue()); // Query for records referencing the original sc_cat_item
    oCITEMItOpNeLookupGR.query();
    var itemOptionNewMap = {}; // Map to store old and new item_option_new records

while (oCITEMItOpNeLookupGR.next()) {
        // Copy each related record
        var oRelatedItemOptNewGR = new GlideRecord("item_option_new");
        oRelatedItemOptNewGR.initialize();
        for (var field in oCITEMItOpNeLookupGR) {
            if (oCITEMItOpNeLookupGR.isValidField(field) && !field.startsWith("sys_")) {
                oRelatedItemOptNewGR[field] = oCITEMItOpNeLookupGR[field];
            }
        }
        oRelatedItemOptNewGR.cat_item = sCatItemId; // Update the sc_cat_item reference to point to the newly created record
        var newSysId = oRelatedItemOptNewGR.insert();
        itemOptionNewMap[oCITEMItOpNeLookupGR.sys_id] = newSysId; // Store old and new sys_id mapping
    }

// Check for related records in question_choice table
    var oCITEMQuestionChoiceLookupGR = new GlideRecord("question_choice");
    oCITEMQuestionChoiceLookupGR.addQuery("question", "IN", Object.keys(itemOptionNewMap));
    oCITEMQuestionChoiceLookupGR.query();

while (oCITEMQuestionChoiceLookupGR.next()) {
        // Copy each related record
        var oRelatedQuestionChoiceGR = new GlideRecord("question_choice");
        oRelatedQuestionChoiceGR.initialize();
        for (var field in oCITEMQuestionChoiceLookupGR) {
            if (oCITEMQuestionChoiceLookupGR.isValidField(field) && !field.startsWith("sys_")) {
                oRelatedQuestionChoiceGR[field] = oCITEMQuestionChoiceLookupGR[field];
            }
        }
        oRelatedQuestionChoiceGR.question = itemOptionNewMap[oCITEMQuestionChoiceLookupGR.question]; // Update the question reference to point to the newly created item_option_new record
        oRelatedQuestionChoiceGR.insert();
    }
}

Kieran Anson
Kilo Patron

Problems like this, I like to make a re-usable function to condense the code.

 

function copyRelatedRecords(parentSysId, parentField, queryTable, newParentSysId) {

    if (!gs.tableExists(queryTable))
        return;

    //optional map of old to new
    var recordMap = {};

    var relatedRecordGR = new GlideRecord(queryTable);
    relatedRecordGR.addQuery(parentField, parentSysId);
    relatedRecordGR.query();

    while (relatedRecordGR.next()) {
        var originalSysId = relatedRecordGR.getUniqueValue();

        relatedRecordGR.setValue(parentField, newParentSysId);

        var insertedRecord = relatedRecordGR.insert();

        recordMap[originalSysId] = insertedRecord;
    }

    return recordMap;
}

 

This works across items, as long as there is a direct relationship. You can then use the following to copy the item

 

//this being the source cat item
var currentCatalogSysId = '';
//this being the variable representing the new catalog item
var newCatalogItemGR = '';

var copiedQuestions = copyRelatedRecords(currentCatalogSysId, 'cat_item', 'item_option_new', newCatalogItemGR);

Object.keys(copiedQuestions).forEach(function(entry) {
    copyRelatedRecords(entry, 'question', 'question_choice', copiedQuestions[entry]);
})

 

I tested this in a background script with the following, and copied the questions and it's related content

var existingItem = 'f0caa23e97c2019021983d1e6253af9a';
var gr = new GlideRecord('sc_cat_item');
gr.get(existingItem);
var newId = gr.insert();

if(!newId){
  throw gs.error("Unable to copy item");
}

var copiedQuestions = copyRelatedRecords(existingItem, 'cat_item', 'item_option_new', newId);

gs.info(JSON.stringify(copiedQuestions)) //hashmap of old/new sys_ids

Object.keys(copiedQuestions).forEach(function(entry) {
    copyRelatedRecords(entry, 'question', 'question_choice', copiedQuestions[entry]);
})

gs.info(newId); //return the new SysId

 

Ankur Bawiskar
Tera Patron
Tera Patron

@kandulek 

what's your business requirement to copy entire catalog item?

If my response helped please mark it correct and close the thread so that it benefits future readers.

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

kandulek
Tera Contributor

Many thanks All for your comments and support on this!