Name

sn_grc_appr.ApprovalUtil

Description

No description available

Script

var ApprovalUtil = Class.create();
ApprovalUtil.prototype = {
  APPROVER_TYPE: {
      SPECIFIC: "specific",
      DYNAMIC: "dynamic",
      SCRIPTED: "scripted",
      FROM_SOURCE: "approver_from_source"
  },

  initialize: function() {},

  /**
   *    This method returns array of objects, each object has information related to approval level
   *    Object is as follows:
   *    {
   *	    users: list of individual approvers,
   *	    groups: list of group approvers,
   *	    approvalQuery: string which can be used as rule in Ask for Approval action (ex: ApprovesAllU[xyz,abc]OrRejectsAnyU[xyz,abc])
   *	    name: name of the approval level
   *	    level: integer which indicates level of approval
   *    }
   */

  evaluateApprovers: function(approvingRecordTable, approvingRecordSysId) {

      var config = this._evaluateApprovalConfigurations(approvingRecordTable, approvingRecordSysId);
      if (!gs.nil(config))
          return this._evaluateApprovalLevels(approvingRecordTable, approvingRecordSysId, config);
      return [];
  },

  _evaluateApprovalConfigurations: function(approvingRecordTable, approvingRecordSysId) {

      var configGR = new GlideRecord("sn_grc_appr_approval_configuration");
      configGR.addQuery("applies_to", approvingRecordTable);
      configGR.addActiveQuery();
      configGR.orderByDesc("priority");
      configGR.query();

      while (configGR.next()) {

          var approvingTableGR = new GlideRecord(approvingRecordTable);
          approvingTableGR.addQuery("sys_id", approvingRecordSysId);

          if (!gs.nil(configGR.getValue("filter_condition")))
              approvingTableGR.addEncodedQuery(configGR.getValue("filter_condition"));
          approvingTableGR.query();

          if (approvingTableGR.hasNext()) {
              return configGR.getUniqueValue();
          }
      }
  },

  _evaluateApprovalLevels: function(approvingRecordTable, approvingRecordSysId, config) {

      var approversPerLevel = [];
      var approvalLevelGR = new GlideRecord("sn_grc_appr_approval_level");
      approvalLevelGR.addQuery("approval_configuration", config);
      approvalLevelGR.orderBy("level");
      approvalLevelGR.query();

      while (approvalLevelGR.next()) {
          var approvalObject = {
              users: [],
              groups: [],
              approveQuery: ""
          };

          var approvalRulesGR = new GlideRecord("sn_grc_appr_approval_rule");
          approvalRulesGR.addQuery("approval_level", approvalLevelGR.getUniqueValue());
          approvalRulesGR.addActiveQuery();
          approvalRulesGR.query();

          while (approvalRulesGR.next()) {
              this._evaluateApprovalRule(approvalRulesGR, approvingRecordTable, approvingRecordSysId, approvalObject);
          }

          var finalApprovalObject = this._processApprovers(approvalObject, approvalLevelGR);

          if (finalApprovalObject.users.length > 0 || finalApprovalObject.groups.length > 0) {
              approversPerLevel.push(finalApprovalObject);
          } else
              break;
      }
      return approversPerLevel;
  },

  _evaluateApprovalRule: function(approvalRulesGR, approvingRecordTable, approvingRecordSysId, approvalObject) {

      var ruleSourceTable = approvalRulesGR.getValue("source");
      var ruleSourceGR = new GlideRecord(ruleSourceTable);

      if (ruleSourceTable == approvingRecordTable)
          ruleSourceGR.addQuery("sys_id", approvingRecordSysId);
      else
          ruleSourceGR.addQuery(approvalRulesGR.getValue("query_using_field"), approvingRecordSysId);

      if (!gs.nil(approvalRulesGR.getValue("additional_condition")))
          ruleSourceGR.addEncodedQuery(approvalRulesGR.getValue("additional_condition"));

      ruleSourceGR.query();

      if (ruleSourceGR.hasNext()) {

          var approvers = this._evaluateApproversBasedOnApproverType(approvalRulesGR, ruleSourceGR);

          if (approvers.users.length > 0 || approvers.groups.length > 0) {

              var approveQuery = 'Approves';
              var approvalRequiredFrom = approvalRulesGR.getValue("approval_required_from");

              if (approvalRequiredFrom == "all")
                  approveQuery += 'All';
              else if (approvalRequiredFrom == "anyone")
                  approveQuery += 'Any';

              var arrayUtil = new global.ArrayUtil();

              if (approvers.users.length > 0) {

                  approvers.users = arrayUtil.unique(approvers.users);
                  var usersQuery = "U[" + approvers.users + "]";
                  approveQuery += usersQuery;

                  arrayUtil.concat(approvalObject.users, approvers.users);
              }

              if (approvers.groups.length > 0) {

                  approvers.groups = arrayUtil.unique(approvers.groups);
                  var groupQuery = "G[" + approvers.groups + "]";
                  approveQuery += groupQuery;

                  arrayUtil.concat(approvalObject.groups, approvers.groups);
              }

              approvalObject.approveQuery += !gs.nil(approvalObject.approveQuery) ? '&' : '';
              approvalObject.approveQuery += approveQuery;
          }
      }
  },

  _processApprovers: function(approvalObject, approvalLevelGR) {

      var finalApprovalObject = {
          users: [],
          groups: [],
          approvalQuery: "",
          level: approvalLevelGR.getValue("level"),
          name: approvalLevelGR.getValue("name")
      };

      if (!gs.nil(approvalObject.approveQuery)) {
          var rejectQuery = 'OrRejectsAny';
          var arrayUtil = new global.ArrayUtil();

          if (approvalObject.users.length > 0) {
              finalApprovalObject.users = arrayUtil.unique(approvalObject.users);
              rejectQuery += 'U[' + finalApprovalObject.users.join(',') + ']';
          }

          if (approvalObject.groups.length > 0) {
              finalApprovalObject.groups = arrayUtil.unique(approvalObject.groups);
              rejectQuery += 'G[' + finalApprovalObject.groups.join(',') + ']';
          }
          finalApprovalObject.approvalQuery = approvalObject.approveQuery + rejectQuery;
      }

      return finalApprovalObject;
  },

  _getApproversFromSource: function(approvalRulesGR, ruleSourceGR, users, groups) {

      while (ruleSourceGR.next()) {
          var userField = approvalRulesGR.getValue("user_field");
          var groupField = approvalRulesGR.getValue("group_field");
          this._getApproversFromFields(ruleSourceGR, approvalRulesGR, users, groups, userField, groupField);
      }
  },

  _getDynamicApprovers: function(approvalRulesGR, ruleSourceGR, users, groups) {

      var approverTableGR;
      var userField;
      var groupField;
      var approverTable = approvalRulesGR.getValue("approvers_from");

      if (approvalRulesGR.advanced) {

          while (ruleSourceGR.next()) {
              approverTableGR = new GlideRecord(approverTable);

              if (!gs.nil(approvalRulesGR.getValue("filter_by")))
                  approverTableGR.addEncodedQuery(approvalRulesGR.getValue("filter_by"));

              var inputs = {
                  current: approverTableGR,
                  parent: ruleSourceGR
              };
              var outputs = ["current"];
              var outputValues = this._evaluateScript(approvalRulesGR, "dynamic_condition", inputs, outputs);

              if (outputValues && Object.keys(outputValues).length) {
                  if (!gs.nil(outputValues.current))
                      approverTableGR = outputValues.current;
              }

              approverTableGR.query();

              this._getApproversFromApproverTable(approverTable, approverTableGR, approvalRulesGR, users, groups);
          }
      } else {
          approverTableGR = new GlideRecord(approverTable);

          if (!gs.nil(approvalRulesGR.getValue("filter_by")))
              approverTableGR.addEncodedQuery(approvalRulesGR.getValue("filter_by"));
          approverTableGR.query();

          this._getApproversFromApproverTable(approverTable, approverTableGR, approvalRulesGR, users, groups);
      }
  },

  _getApproversFromApproverTable: function(approverTable, approverTableGR, approvalRulesGR, users, groups) {

      var userField = approvalRulesGR.getValue("user_field");
      var groupField = approvalRulesGR.getValue("group_field");

      if (gs.nil(userField) && gs.nil(groupField)) {
          if (approverTable == "sys_user") {
              while (approverTableGR.next()) {
                  users.push(approverTableGR.getUniqueValue());
              }
          } else if (approverTable == "sys_user_group") {
              while (approverTableGR.next()) {
                  groups.push(approverTableGR.getUniqueValue());
              }
          }
      } else {

          while (approverTableGR.next()) {
              this._getApproversFromFields(approverTableGR, approvalRulesGR, users, groups, userField, groupField);
          }
      }
  },

  _getSpecificApprovers: function(approvalRulesGR, users, groups) {

      if (!gs.nil(approvalRulesGR.getValue("users"))) {
          var arrayUtil = new global.ArrayUtil();

          arrayUtil.concat(users, approvalRulesGR.getValue("users").split(","));
      }

      if (!gs.nil(approvalRulesGR.getValue("group"))) {
          groups.push(approvalRulesGR.getValue("group"));
      }
  },

  _getScriptedApprovers: function(approvalRulesGR, ruleSourceGR, users, groups) {

      while (ruleSourceGR.next()) {
          var inputs = {
              parent: ruleSourceGR,
              users: [],
              groups: []
          };
          var outputs = ["users", "groups"];
          var outputValues = this._evaluateScript(approvalRulesGR, "script", inputs, outputs);

          if (outputValues && Object.keys(outputValues).length) {
              var userApprovers = outputValues["users"];
              for (var i = 0; i < userApprovers.length; i++) {

                  if (userApprovers[i] != "")
                      users.push(userApprovers[i]);
              }

              var groupApprovers = outputValues.groups;

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

                  if (groupApprovers[i] != "")
                      groups.push(groupApprovers[i]);
              }
          }
      }
  },

  _getApproversFromFields: function(approverTableGR, approvalRulesGR, users, groups, userField, groupField) {

      if (!gs.nil(userField)) {
          var userApprovers = approverTableGR.getElement(userField).toString();
          var usersArray = userApprovers.split(',');

          for (var i = 0; i < usersArray.length; i++) {
              if (!gs.nil(usersArray[i]) && this._ifUserExists(usersArray[i])) {
                  users.push(usersArray[i]);
              }
          }
      }

      if (!gs.nil(groupField)) {
          var groupApprovers = approverTableGR.getElement(groupField).toString();
          var groupApprArr = groupApprovers.split(',');

          for (var j = 0; j < groupApprArr.length; j++) {
              if (!gs.nil(groupApprArr[j]) && this._ifGroupExists(groupApprArr[j])) {
                  groups.push(groupApprArr[j]);
              }
          }
      }
  },

  _ifUserExists: function(userSysID) {

      var userGr = new GlideRecord('sys_user');

      return (userGr.get(userSysID) && userGr.getDisplayValue('active') === 'true');
  },

  _ifGroupExists: function(groupSysID) {

      var groupGr = new GlideRecord('sys_user_group');

      return (groupGr.get(groupSysID) && groupGr.getDisplayValue('active') === 'true');
  },

  _evaluateApproversBasedOnApproverType: function(approvalRulesGR, ruleSourceGR) {

      var users = [];
      var groups = [];
      var approverType = approvalRulesGR.getValue("approver_type");

      switch (approverType) {
          case this.APPROVER_TYPE.SPECIFIC:
              this._getSpecificApprovers(approvalRulesGR, users, groups);
              break;

          case this.APPROVER_TYPE.DYNAMIC:
              this._getDynamicApprovers(approvalRulesGR, ruleSourceGR, users, groups);
              break;

          case this.APPROVER_TYPE.FROM_SOURCE:
              this._getApproversFromSource(approvalRulesGR, ruleSourceGR, users, groups);
              break;

          case this.APPROVER_TYPE.SCRIPTED:
              this._getScriptedApprovers(approvalRulesGR, ruleSourceGR, users, groups);
              break;
      }

      return {
          users: users,
          groups: groups
      };
  },

  _evaluateScript: function(record, scriptField, inputs, outputVariables) {

      var scriptEvaluator = new GlideScopedEvaluator();
      var outputValues = {};

      if (inputs && Object.keys(inputs).length) {
          for (var v in inputs)
              scriptEvaluator.putVariable(v, inputs[v]);
      }

      try {
          scriptEvaluator.evaluateScript(record, scriptField);
          for (var i = 0; i < outputVariables.length; i++) {
              outputValues[outputVariables[i]] = scriptEvaluator.getVariable(outputVariables[i]);
          }
          return outputValues;
      } catch (error) {
          gs.error(error);
          return outputValues;
      }
  },

  type: 'ApprovalUtil'
};

Sys ID

7b7ec52153f23010da91ddeeff7b1233

Offical Documentation

Official Docs: