Incorrect Development Approval Group Populated Due to "STARTSWITH" Query in Script Include

1_DipikaD
Kilo Sage

Hi All,

 

A CI is created through a catalog item. After creation, the CI form includes a tab to specify the CI owner, support group, development group, and development approval group. The development approval group is automatically populated based on the selected development group. This works correctly for most CIs, but for one particular CI, the development approval group is being set incorrectly.

 

Upon investigation, I found that a Script Include is responsible for this behavior—specifically, a section of the code(highlighted below) that uses the "STARTSWITH" operator in a query. Since the group names are very similar, I suspect the "STARTSWITH" condition is matching the wrong group. To ensure the correct development approval group is selected, I believe this operator should be changed to an exact match instead. Even not aware how to check if there are any other CIs are impacted on this, till now it looks good for other CIs. I have attached Script Include and scripts in workflow activity where it is called and pics for your reference .

 

Thank You

 

Script Include : -   

var Nom_App_Onboarding_Form_Util = Class.create();
Nom_App_Onboarding_Form_Util.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    getAppInst: function() {
        var country = '';
        var gr = new GlideRecord('u_cmdb_ci_app_instance');
        //      gr.addQuery('u_environment=97a9d2934f37160011a93c728110c7c2^ORu_environment=51d7f5c0db0c87000870fd431d961991');
        gr.addQuery('sys_id', this.getParameter('sysparm_instName'));
        gr.query();
        if (gr.next()) {
            var instName = gr.name;
            var data = {};
           
           
            data.u_app = gr.u_parent.toString();
            if (gr.u_parent.sys_class_name != 'u_cmdb_ci_app_instance') {
                data.u_app = gr.u_application.toString();
            }
            //adding values for dr doc path and last updated under JIRA GLITSME-9338
            data.u_itdr_doc_path = gr.u_itdr_doc_path.toString();
            data.u_itdr_doc_last_updated =  gr.u_itdr_doc_last_updated.toString();
            //end for changes under JIRA GLITSME-9338
            data.u_bcm_estimated_recovery_point = gr.u_bcm_estimated_recovery_point.toString();
            data.u_bcm_estimated_recovery_time = gr.u_bcm_estimated_recovery_time.toString();
            data.u_region = gr.location.toString();
            data.u_division = gr.u_division.toString();
            //data.u_it_division= gr.u_division.u_it_division.toString();
            // As per JIRA 6144
            data.u_it_division = 'false';
            if (gr.u_division.u_it_division || gr.u_subdivision.u_it_division) {
                data.u_it_division = 'true';
            }
            data.u_subdivision = gr.u_subdivision.toString();
            data.u_description = gr.short_description.toString();
            data.u_bcm_tier = gr.u_bcm_tier.toString();
            data.u_envrnmt = gr.u_environment.toString();
            data.u_app_owner = this.getRolesandResp(gr, '8fd027af370e9200cd2b5a9543990e96', false);
            data.u_dev_owner = this.getRolesandResp(gr, '42416f6f370e9200cd2b5a9543990e51', false);
            data.u_supp_owner = this.getRolesandResp(gr, '9f01236f370e9200cd2b5a9543990e0d', false);
            data.u_bus_owner = this.getRolesandResp(gr, 'd52cb67c4ff00300c5ce44f18110c754', false);
            data.u_supp_grp = '';
            data.u_dev_grp = '';
            data.u_supp_bing_grp = '';
            data.u_supp_app_grp = '';
            data.u_dev_app_grp = '';
            data.u_app_owner_grp = '';
            data.u_hft_algo_flag = gr.u_hft_algo_flag.toString();
            //              if(gr.u_division.u_it_division){
            data.u_supp_bing_grp = gr.u_support_bing_group.toString();
            data.u_supp_grp = this.getRolesandResp(gr, '96a16f6f370e9200cd2b5a9543990ec7', true);
            data.u_dev_grp = this.getRolesandResp(gr, '65c3abf537125600cd2b5a9543990e30', true);
            data.u_supp_app_grp = this.getRolesandResp(gr, 'a0ee3d5637292a00cd2b5a9543990e33', true);
            data.u_dev_app_grp = this.getRolesandResp(gr, '9aaef59637292a00cd2b5a9543990eb8', true);
            data.u_app_owner_grp = this.getRolesandResp(gr, 'da9a5d493739cb00cd2b5a9543990eaa', true);
            data.u_a2p_supp =  this.getRolesandResp(gr, '0f2297a9db21ab4cf5aa15784b9619a8', true);
            data.u_a2p_dev =  this.getRolesandResp(gr, 'aec3c5d9dbe9274cf5aa15784b96199c', true);
            gs.info('tanvir::  before ower check:'+gr.name);
//          if(data.u_app_owner==gs.getUserID()){
//              
//          data.isNotTrueOwner= this.getTrueOwner(gr);
//          }else{
//              
//              data.isNotTrueOwner=true;
//          }
            //              }
   
            var choic = new GlideRecord('sys_choice');
            choic.addEncodedQuery('element=u_country_opt^inactive=false^dependent_value=' + gr.location.u_region.name);
            choic.query();
            while (choic.next()) {
                if (instName.indexOf(choic.label) > -1) {
                    country = choic.value;
                }
            }
            data.u_country = country.toString();
           
            return JSON.stringify(data);
        }
    },
    getMyUserGroups: function(user_name) {

        if (JSUtil.nil(user_name))
            user_name = gs.getUserName();

        var grps = '';
        var sep = '';

        var gmem = new GlideRecord('sys_user_grmember');
        gmem.addQuery('user.user_name', user_name + '');
        gmem.query();

        while (gmem.next()) {
            grps += sep + gmem.group + '';
            sep = ',';
        }

        return grps + '';
    },
    getTrueOwner: function(inst){
        var answer = false;
        var arrayUtil = new ArrayUtil();
                var rolesArr = [];
                var ids = [];
                var visitedCi = [];
                var env = inst.getDisplayValue('u_environment');
                var env_group = inst.u_division.u_environment_management;
                var groups = this.getMyUserGroups();
        var functions = 'Support Group,Support Owner';

                var queryS = 'u_function.u_functionIN' + functions;
                queryS += '^u_user=' + gs.getUserID(); //check if user is the owner
                queryS += '^ORu_group.sys_idIN' + groups; //check if user is the member of owner group
               
                var rnr = new GlideRecord('u_roles_and_responsibilities');
               rnr.addQuery('u_ci', inst.sys_id+'');
                rnr.addEncodedQuery(queryS);
                rnr.query();

                //if a role/responsibility exists
                if (rnr.next()) {

                    answer = true;
                   
                } else {
                    functions = 'Development Group,Development Owner';

                    queryS = 'u_function.u_functionIN' + functions;
                    queryS += '^u_user=' + gs.getUserID(); //check if user is the owner
                    queryS += '^ORu_group.sys_idIN' + groups; //check if user is the member of owner group

                    var rnr1 = new GlideRecord('u_roles_and_responsibilities');
                    rnr1.addQuery('u_ci', inst.sys_id);
                    rnr1.addEncodedQuery(queryS);
                    rnr1.query();

                    if (rnr1.next()) {

                        //if environment is PROD and Lifecycle BUILD, return true
                        if ((env == 'PROD' || env == 'DR') && app_instance.u_lifecycle_state == 'BUILD')
                            answer = true;
                           

                        //for all non-prod, return true
                        else if (env != 'PROD' && env != 'DR')
                            answer = true;
                           
                    }
                }
        return answer;
    },
    getRolesandResp: function(inst, funct, isGroup) {
        var gr = new GlideRecord('u_roles_and_responsibilities');
        gr.addQuery('u_ci', inst.sys_id);
        gr.addQuery('u_function', funct);
        gr.query();
        if (gr.next()) {
            if (isGroup) {
                return gr.u_group.toString();
            }
            return gr.u_user.toString();
        } else if (inst.u_parent) {
            return this.getRolesandResp(inst.u_parent, funct, isGroup);
        }
        return '';
    },

    isApplicationExist: function() {
        var answer = false;
        var gr = new GlideRecord('cmdb_ci_business_app');
        gr.addQuery('sys_class_name', 'cmdb_ci_business_app');
        gr.addQuery('name', this.getParameter('sysparm_app_name'));
        gr.query();
        if (gr.next()) {
            answer = true;
        }
        return answer;
    },

    getUsersDefaultSuppGrp: function() {
        var answer = '';
        var gr = new GlideRecord('sys_user');
        gr.addQuery('active', true);
        gr.addQuery('sys_id', this.getParameter('sysparm_user'));
        gr.query();
        if (gr.next()) {
            answer = gr.u_default_support_group;
        }
        return answer;
    },

    // function for getting division value(A2RM - BCM Tier Update)
    getDepartment: function() {
        var answer = '';
        var gr = new GlideRecord('cmn_department');
        gr.addQuery('sys_id', this.getParameter('sysparm_subdiv'));
        gr.query();
        if (gr.next()) {
            answer = gr.parent;
        }
        return answer;
    },
    getApprovalGrp: function(){
        var gr = new GlideRecord('sys_user_group');
    gr.addQuery('active', 'true');
    gr.addQuery('type', 'c38b983f74e11100f03b1545dd5c638f');
    gr.addQuery('name', 'STARTSWITH', this.getParameter('sysparm_grname'));
    gr.query();
    if (gr.next()) {
        return gr.sys_id;
    }

       
    },
    getAppInstEnv : function(){      
        var answer;
        var gr = new GlideRecord('u_cmdb_ci_app_instance');
        gr.addQuery('sys_id', this.getParameter('sysparm_inst'));
        gr.query();
        if (gr.next()) {
            if(gr.u_environment == '97a9d2934f37160011a93c728110c7c2' || gr.u_environment=='51d7f5c0db0c87000870fd431d961991'){
               answer = true;
             }else{
                answer = false;
             }
        }
        return answer;
       
    },

    type: 'Nom_App_Onboarding_Form_Util'
});
 
 
RunScript activity :-
 var utils = new Nom_App_Onboarding_Util();
workflow.scratchpad.u_application = utils.createApp(current);
 
RunScript activity :-
var utils = new Nom_App_Onboarding_Util();  
workflow.scratchpad.u_appInst = utils.createAllAppInst(current, workflow);
 
Approval Co-ordinator:-
var apprGrps = new Nom_App_Onboarding_Util().getLevel2Approval(current.variables, workflow.scratchpad.app_inst_input);

var answer = [apprGrps];

 


 

 
 
5 REPLIES 5

Robert H
Mega Sage

Hello @1_DipikaD ,

 

You are absolutely correct. The 'STARTSWITH' operator should be avoided since the query could potentially return multiple results in random order, while you need an exact match here.

 

So please either replace it with the '=' operator...

...or, even better, just use the sys_id of the group that I guess is already present in your "current.variables" object (assuming that your Catalog Item uses a reference variable to select the approval group), so you would not have to deal with the group names at all.

 

Regards,

Robert

Hi @Robert H ,

Thanks for your response.

I have already tried that Replacing 'STARTSWITH' with '=' . When I tested it did not auto populate the development approval group. The field appeared with no value.

The getApprovalGrp function is using 'STARTSWITH' with addquery
How can we construct the approval group name first then pass it in the query. Also tried the below script but the result is same , it did not show any value on that field.

getApprovalGrp: function(){
        var groupPrefix = this.getParameter('sysparm_grname');
        var fullGroupName = groupPrefix + '_Approval_Group';
        var gr = new GlideRecord('sys_user_group');
    gr.addQuery('active', 'true');
    gr.addQuery('type', 'c38b983f74e11100f03b1545dd5c638f');
    gr.addQuery('name', fullGroupName);
    gr.query();
    if (gr.next()) {
        return gr.sys_id;
    }

Hello @1_DipikaD ,

 

Your screen shots are not showing the full group names.

But I guess the name of the corresponding approval group for the "CTS:APS-GLAD_Mario" development group is "CTS:APS-GLAD-Mario-Approval_Group"?

So in other words, your naming convention is to just add "-Approval_Group" to the name?

 

If so then there is a typo in your script because it currently adds "_Approval_Group" (with an underscore instead of a hyphen as the first character).

 

Regards,

Robert

Hi @Robert H ,

Thanks for finding my mistake. I changed _ to - and it's working now. 

One last thing want to ask that can we optimize the code with better quality if possible. Is this code is okay to implement ? Is there any possibility  that it could impact adversely ? And how can I check if similar thing is happening with  any other CIs  ?

 

Thanks once again.