Name

sn_uib_dyn_rel_rec.RelatedRecordsUtil

Description

Utility APIs to converting the related records to now-data-set EVAM templates. This data conversion is required for Related records to be displayed within the Related Records shared page.

Script

var RelatedRecordsUtil = Class.create();
RelatedRecordsUtil.prototype = {
  initialize: function() {},

  getConfigFieldsTemplate: function(relatedRecordGr, viewConfigGr) {
      var props = [],
          item = {};
      var fields = viewConfigGr.field_list.split(",");
      fields.push('sys_id');
      fields.push('table');
      for (field in fields) {
          var prop = {};
          if (fields[field] !== "table") {
              prop.name = fields[field] + "";
              prop.value = relatedRecordGr.getDisplayValue(fields[field]) + "";
              props.push(prop);
          } else {
              props.push({
                  "name": fields[field] + "",
                  "value": relatedRecordGr.getTableName() + ""
              });
          }
      }
      item.template = viewConfigGr.ux_template + "";
      item.props = props;
      item.actions = this._getConfigItemActions(viewConfigGr.sys_id);
      return item;
  },

  getMatchingViewConfig: function(table, sys_id) {
      var matchingViewConfigGr;
      var relatedRecordGr = new GlideRecord(table);
      relatedRecordGr.get(sys_id);

      var viewConfigGr = new GlideRecord("sys_ux_composite_data_template_predicate");
      viewConfigGr.addActiveQuery();
      viewConfigGr.addQuery("table", table);
      viewConfigGr.orderBy("order");
      viewConfigGr.query();
      while (viewConfigGr.next()) {
          if (GlideFilter.checkRecord(relatedRecordGr, viewConfigGr.condition)) {
              matchingViewConfigGr = viewConfigGr;
  			break;
  		}
      }
      return matchingViewConfigGr;
  },

  getAllActionsForViewConfig: function(viewConfigGr) {
      return this._getConfigItemActions(viewConfigGr.sys_id);
  },

  _getConfigItemActions: function(viewConfigSysID) {
      var itemActions = [];
      var actions = this._getActionAssignment(viewConfigSysID);
      for (var i = 0; i < actions.length; i++) {
          itemActions.push(this._getDeclarativeActionMapping(actions[i]));
      }
      return itemActions;
  },

  _getActionAssignment: function(viewConfigSysID) {
      var actions = [];
      var actAssignGr = new GlideRecord("sys_ux_predicate_m2m_action_assignment");
      actAssignGr.addQuery("predicate", viewConfigSysID);
      actAssignGr.query();
      while (actAssignGr.next()) {
          var declActGr = this._getDeclarativeAction(actAssignGr.declarative_action_assignment);
          actions.push(declActGr);
      }
      return actions;
  },

  _getDeclarativeAction: function(actionId) {
      var actionGr = new GlideRecord("sys_declarative_action_assignment");
      actionGr.get(actionId);
      return actionGr;
  },

  _getDeclarativeActionMapping: function(actionGr) {
      var itemAction = {};
      itemAction.assignmentId = actionGr.sys_id + '';
      itemAction.name = actionGr.action_name + '';
      itemAction.label = actionGr.label + '';
      itemAction.actionType = actionGr.declarative_action_type + '';
      itemAction.icon = actionGr.icon + '';
      itemAction.buttonType = actionGr.button_type + '';
      itemAction.serverScript = actionGr.server_script + '';
      itemAction.confirmationRequired = Boolean(actionGr.confirmation_required);
      itemAction.confirmationMessage = actionGr.confirmation_message + '';

      var actionPayload = this._getDeclarativeActionPayloadMapping(actionGr.client_action);
      itemAction.actionPayload = actionPayload.action_payload;
      itemAction.actionDispatch = actionPayload.actionDispatch;
      itemAction.actionPayloadMap = actionPayload.actionPayloadMap;
      return itemAction;
  },

  _getDeclarativeActionPayloadMapping: function(actionPayloadId) {
      var actionPayload = {};
      var actionPayloadGr = new GlideRecord("sys_declarative_action_payload_definition");
      actionPayloadGr.get(actionPayloadId);
      actionPayload.actionDispatch = actionPayloadGr.action_key + '';
      actionPayload.action_payload = actionPayloadGr.payload_template + '';
      actionPayload.actionPayloadMap = this._getPayloadFieldMapping(actionPayloadId);
      return actionPayload;
  },

  _getPayloadFieldMapping: function(actionPayloadId) {
      var payloadMap = [];
      var payloadFieldGr = new GlideRecord("sys_declarative_action_payload_field");
      payloadFieldGr.addQuery("model_id", actionPayloadId);
      payloadFieldGr.query();
      while (payloadFieldGr.next()) {
          var payload = {};
          payload.name = payloadFieldGr.element + '';
          payload.value = payloadFieldGr.default_value + '';
          payloadMap.push(payload);
      }
      return payloadMap;
  },

  //returns JSON {defintion_id : {definition metadata}}, or { message : ""} if error occcurs
  fetchRelatedRecordDefinitions: function (table, sys_id) {
      if (gs.nil(table))
          return {
              "message": gs.getMessage("Table required for Related Record Contexts")
          };
      //fetch source record
      var source_record = new GlideRecord(table);
      source_record.get(sys_id);

      var contexts = [];
      //if has parents, collect their contexts
      var base = new GlideTableHierarchy(table).getBase();
      if (base != table) {
          var parent_related_contexts = new GlideRecord('sn_related_record_context');
          parent_related_contexts.addQuery("applies_to_table", new GlideTableHierarchy(base).getTables());
          parent_related_contexts.addActiveQuery();
          parent_related_contexts.addQuery("inherited", "true");
          parent_related_contexts.query();

          //run source record against Context conditions
          while (parent_related_contexts.next()) {
              if (gs.nil(parent_related_contexts.conditions) ||
                  GlideFilter.checkRecord(source_record, parent_related_contexts.conditions))
                  contexts.push(parent_related_contexts.sys_id + "");
          }
      }
      //retrieve self contexts
      var self_related_contexts = new GlideRecord('sn_related_record_context');
      self_related_contexts.addQuery("applies_to_table", table);
      self_related_contexts.addActiveQuery();
      self_related_contexts.query();

      while (self_related_contexts.next()) {
          if (gs.nil(self_related_contexts.conditions) ||
              GlideFilter.checkRecord(source_record, self_related_contexts.conditions))
              contexts.push(self_related_contexts.sys_id + "");
      }

      if (contexts.length === 0) {
          return {
              "message": gs.getMessage("No Related Record Context defined for this table")
          };
      }

      var defs = {};

      //fetch Relationships
      var related_records = new GlideRecord('sn_m2m_context_related_record_defn');
      related_records.addQuery("related_record_context", "IN", contexts.join());
      related_records.addActiveQuery();
      related_records.query();
      while (related_records.next()) {
          //initalize the definition script
          var related_def = related_records.related_record_definition;
          var current = new GlideRecord(related_def.queries_from);
          var rel_context = related_records.related_record_context;

          var evaluator = new GlideScopedEvaluator();
          evaluator.putVariable("current", current);
          evaluator.putVariable("primary", new GlideRecord());
          evaluator.putVariable("secondary", new GlideRecord());

          if (!gs.nil(related_def.primary_table) &&
              !gs.nil(rel_context.primary_field)) {
              var primary = new GlideRecord(related_def.primary_table);
              primary.get(source_record.getElement(rel_context.primary_field));
              if (!primary.isValidRecord()) {
                  continue;
              }
              evaluator.putVariable("primary", primary);
          }
          if (!gs.nil(related_def.secondary_table) &&
              !gs.nil(rel_context.secondary_field)) {
              var secondary = new GlideRecord(related_def.secondary_table);
              secondary.get(source_record.getElement(rel_context.secondary_field));
              if (!secondary.isValidRecord()) {
                  continue;
              }
              evaluator.putVariable("secondary", secondary);
          }
          //evaluate the Defintion Script
          try {
              evaluator.evaluateScript(related_def.getRefRecord(), 'script');
          } catch (err) {
              gs.addErrorMessage(gs.getMessage("GlideScopedEvaluation of Related Record Definition of Fetch Related Record Context Definitions errored"));
              gs.error(err);
              continue;
          }
          //check if table level access
          if (!current.canRead()) {
              var canReadRelatedRecordsGR = new GlideRecord(related_def.queries_from);
              canReadRelatedRecordsGR.addEncodedQuery(evaluator.getVariable("current").getEncodedQuery());
              canReadRelatedRecordsGR.setLimit(1);
              canReadRelatedRecordsGR.query();
              //check if record access
              if ((!(canReadRelatedRecordsGR.next() && canReadRelatedRecordsGR.canRead())))
                  continue;
          }

          if (evaluator.getVariable("current").getEncodedQuery() !== "sys_idNotValidnull") {
              //if same defintion under one context, take the least ordered defintion's metadata
              if (related_def.sys_id in defs) {
                  if((rel_context.order + 0) <= defs[related_def.sys_id].context_order && (related_records.order + 0) < defs[related_def.sys_id].order) {
                      defs[related_def.sys_id]["order"] = related_records.order + 0;
                      defs[related_def.sys_id]["context_order"] = rel_context.order + 0;
                  }
              } else {
                  defs[related_def.sys_id] = {
                      "label": gs.getMessage("{0}",String(related_def.display_label)),
                      "table": related_def.queries_from + '',
                      "id": related_def.display_label + "_" + related_def.sys_id,
                      "filter": evaluator.getVariable("current").getEncodedQuery() + '',
                      "canCreate": current.canCreate(),
                      "order": related_records.order + 0,
                      "context_order": rel_context.order + 0
                  };
              }
          }
      }
      return defs;
  },

  //given tables and sysIds, return sorted arrays of Defintions
  getRelatedRecordDefinitions: function (table, sysId, optional_table, optional_sys_id) {
      var primary_defs = this.fetchRelatedRecordDefinitions(table, sysId);
      var optional_defs = {};
      if (!gs.nil(optional_table) && !gs.nil(optional_sys_id)) {
          optional_defs = this.fetchRelatedRecordDefinitions(optional_table, optional_sys_id);
      }
      var sort_by_order = function (lhs, rhs) {
          if (lhs.context_order - rhs.context_order === 0)
              return lhs.order - rhs.order;
          return lhs.context_order - rhs.context_order;
      };

      //only primary passed in
      var sorted_defs = [];
      if (!primary_defs.message && (gs.nil(optional_defs) || optional_defs.message)) {
          Object.keys(primary_defs).forEach(function (item) {
              sorted_defs.push(primary_defs[item]);
          });
      }
      //only the optional has defs
      if (!gs.nil(optional_defs) && primary_defs.message && !optional_defs.message) {
          Object.keys(optional_defs).forEach(function (item) {
              sorted_defs.push(optional_defs[item]);
          });
      }

      //both have defs
      if (!primary_defs.message && !optional_defs.message) {
          //if same definition, combine the filter and take the least ordered
          Object.keys(primary_defs).forEach(function (item) {
              if (item in optional_defs) {
                  //if optional[item] is least ordered
  				if(optional_defs[item].context_order < primary_defs[item].context_order || 
  				  (optional_defs[item].context_order == primary_defs[item].context_order && 
  				  optional_defs[item].order < primary_defs[item].order)) {	
                      primary_defs[item].context_order = optional_defs[item].context_order;
                      primary_defs[item].order = optional_defs[item].order;
                  }
                  //combine filters with 'OR' condition
                  primary_defs[item].filter = primary_defs[item].filter + "^OR" + optional_defs[item].filter;
              }
              sorted_defs.push(primary_defs[item]);
          });
          //add  remaining items in optional defs
          Object.keys(optional_defs).forEach(function (item) {
              if (!(item in primary_defs)) {
                  sorted_defs.push(optional_defs[item]);
              }
          });
      }
      //return sorted defintions
      sorted_defs.sort(sort_by_order);
      return sorted_defs;
  },

  type: 'RelatedRecordsUtil'
};

Sys ID

620591738703201074f38467a7cb0b4e

Offical Documentation

Official Docs: