Monday, 30 May 2016

Service Catalog: Record Producer Variables in your Change Ticket

At a recent project, we had a requirement to show the variables of a record producer 
on the change record that was created by the record producer. This can be done easily 
by adding the variable editor to the form.
However… the UI Policies and client scripts defined on the record producer cannot run 
on the produced record like you can do with Request Item variables.
The Challenge
The requirement of the client was to make the information of the 
variables available on the change record. Having the fields listed out in a change 
specific field was the next option the Client had for this requirement. 

The variables however needed to be listed in the same order as they appear on
 the record producer form. 

The functionality of a label and multiple check boxes is used regularly, this should be 
visualized the same way in the record producer.
Another reason why the variable pool option did not make it was because the variable 
pool can only be used to get the label,value and type of a variable related to the change 
record. We needed more information from the variable, for example the order field.

The Solution

Out of the box, Service-Now has the functionality that if the Variable that is used in 
the record producer has the same name as the target field, the value is automatic 
scopied to the newly created record. For all other options, the record producer has 
a script field in where the mapping between variables and fields can be scripted. The 
client was looking at a number of record producers (pre-approved change requests)
 that was going to exceed 200 cases. Due to this large number, we had to come up 
with a maintainable solution.
We created a script (script include) that loops through the related variables of a record 
producer and prints them in the right order in the description field of the target 
(change) record.



The variables of the types ‘container_start, container_end, container split’ are ignored.
The script include is called from the script field in the record producer, like this:
New u_RPUtils,process(‘string of the sys_id of the record producer’);
The Script

var u_RPUtils = Class.create();

u_RPUtils.prototype = {
    initialize: function() {
    },

    // function called from record producer, should have the producer object available.
    process: function(recProdSysID){
        var recProd = '';
        if(typeof recProdSysID != 'undefined'){
            var stringState = '-2';
            recProd = u_GlobalUtils.getRec('sc_cat_item_producer',recProdSysID);
            current.short_description = recProd.short_description;
            //map field from the variable set. the reference qualifiers from the change process are mapped to im_service in stead of the u_im_service variable
            current.u_im_service = producer.im_service;
            current.state = parseInt(stringState);
            current.type = 'Pre-Approved';
            current.requested_by = gs.getUserID();
            }
    },
    setValuesForQuestions: function (current){
        //variables that are already mapped are added to a system property, we dont want to see these questions in the description of the change
        var varNameStr = gs.getProperty('lsmc.pacr.mapped_variable_names');
        var varNameArray =[];
        if(varNameStr !=""){
            var aa = varNameStr.toString().split(',');
            for(var i=0; i<aa.length; i++){
                varNameArray.push(aa[i].toString().trim());
            }
        }
        var string3 = "";
        var producerVars = new GlideRecord('question_answer');
        producerVars.addQuery('table_sys_id', current.sys_id);
        producerVars.addQuery('question.type', '!=', 19); // Container Start
        producerVars.addQuery('question.type', '!=', 20); // Container End
        producerVars.addQuery('question.type', '!=', 24); // Container Split
        producerVars.orderBy('question.order');
        producerVars.query();

        while(producerVars.next()){
            var type = producerVars.question.type;
            var label = producerVars.question.question_text.toString();
            var name = producerVars.question.name.toString();
            var question = current.variables[producerVars.question.name.toString()];
            var value = question.getGlideObject().getQuestion().getDisplayValue() + '';
            //11==label
            if(new ArrayUtil().indexOf(varNameArray, name) == -1){
                if(type == 11){ 
                    string3 += "\n\n" + label + " : ";
                    var xxx = [];
                    while(producerVars.next()){
                        label = producerVars.question.question_text.toString();
                        name = producerVars.question.name.toString();
                        question = current.variables[producerVars.question.name.toString()];
                        value = question.getGlideObject().getQuestion().getDisplayValue() + '';
                        type = producerVars.question.type;
                        // 7==checkbox
                        if(type == 7){
                                if(value == 'true'){
                                xxx.push(label);
                                }
                        }
                        else{
                            string3 += xxx.toString();
                            if(name == 'pacr_businesss_requirement'){
                                string3 =  "" +  value + "\n" + string3;
                            }
                            else{
                                // next is evaluated, if you don't use it here, the glide record will not be processed.
                                string3 += "\n" + label + " : " +  value;
                            }
                            // clear the array
                          xxx = [];
                            break;
                        }
                    }
                    // when the last question is a checkbox, we need to add it to the string here, it will never get in the previous else state..
                    if(xxx.length >0){
                    string3 += xxx.toString();
                    }
                }
                else if(name == 'pacr_businesss_requirement'){
                    string3 = "" +  value + "\n" + string3;
                }
                else{
                    string3 += "\n" + label + " : " +  value;
                }
            }
        }
        current.description += "Questions and Answers from the request:\n" + string3;
        },
    type: 'u_RPUtils'
};
If you would like to know more about this specific subject or you need help with your 
Service Catalog, 
please contact me at abhi.jain39@outlook.com
-AJNow

3 comments:

  1. I am really enjoying reading your well written articles. It looks like you spend a lot of effort and time on your blog. I have bookmarked it and I am looking forward to reading new articles. Keep up the good work..

    ServiceNow training in Hyderabad

    ReplyDelete
  2. Nice and good article. It is very useful and understand easily. Thanks for sharing your valuable information.

    ServiceNow Training in Hyderabad
    ServiceNow Training in Ameerpet
    ServiceNow Training
    ServiceNow Online Training

    ReplyDelete