Name

global.IncidentUtilsSNC

Description

This function contains utility functions related to Incident . This function should not be modified by the customer. Public functions ajaxFunction_getIncidentQueryParams ajaxFunction_makeIncidentCopy ajaxFunction_getKnowledgeGapMapping isCopyIncidentFlagValid makeRelatedTableCopy copyIncidentRelatedLists copyIncidentAttachments getCsvValue getProblemFromIncident

Script

var IncidentUtilsSNC = Class.create();
IncidentUtilsSNC.prototype = {
  INCIDENT: 'incident',
  ROLE_ITIL: 'itil',
  ROLE_SN_INCIDENT_WRITE: 'sn_incident_write',
  PLUGIN_GRANULAR_ITSM_ROLES: 'com.snc.itsm.roles.incident_management',
  PLUGIN_INCIDENT_SANDIEGO: "com.snc.best_practice.incident.sandiego",
  FIELD_CALLER_ID: 'caller_id',
  FIELD_CLOSE_CODE: 'close_code',
  FIELD_CLOSE_NOTES: 'close_notes',
  ATTR_DOMAIN: 'sys_domain',
  ATTR_PARENT_INCIDENT: 'parent_incident',
  ATTR_WORK_NOTES: "work_notes",
  ATTR_NUMBER: "number",
  COPY_IF_ACTIVE_ATTRS: ['parent_incident', 'problem_id', 'rfc'],
  ALWAYS_IGNORE_ATTRS: ['active', 'additional_assignee_list', 'child_incidents', 'close_code', 'close_notes', 'closed_at', 'closed_by', 'created', 'created_by', 'hold_reason', 'knowledge', 'made_sla', 'notify', 'number', 'opened_at', 'opened_by', 'reassignment_count', 'reopen_count', 'resolved_at', 'resolved_by', 'sys_id', 'sys_domain', 'sys_mod_count', 'time_worked', 'updated', 'updated_by', 'watch_list', 'work_notes_list'],
  PROP_INCIDENT_COPY_RELATED_LISTS: 'com.snc.incident.copy.related_lists',
  PROP_INCIDENT_COPY_ATTRS: 'com.snc.incident.copy.attributes',
  PROP_INCIDENT_COPY_ENABLED: 'com.snc.incident.copy.enable',
  PROP_CREATE_CHILD_INCIDENT: 'com.snc.incident.create.child.enable',
  PROP_INCIDENT_COPY_ATTACH: 'com.snc.incident.copy.attach',
  PROP_GLIDE_SYS_TZ: 'glide.sys.default.tz',
  PROP_GLIDE_SYS_DATE_FORMAT: 'glide.sys.date_format',
  PROP_GLIDE_SYS_TIME_FORMAT: 'glide.sys.time_format',
  TZ_UTC: 'UTC',
  DEFAULT_DATE_FORMAT: 'yyyy-MM-dd',
  DEFAULT_TIME_FORMAT: 'HH:mm:ss',
  SYS_USER_GRMEMBER: 'sys_user_grmember',
  INCIDENT_DEFAULT_ATTR_VALUE: 'assignment_group,business_service,category,caused_by,cmdb_ci,company,description,impact,location,parent_incident,problem_id,rfc,short_description,subcategory,urgency,priority,service_offering',
  RELATED_TABLES_MAP: {
      'task_cmdb_ci_service': {
          property: 'com.snc.incident.copy.rl.task_cmdb_ci_services.attributes',
          parentAttr: 'task',
          defaultValue: 'cmdb_ci_service',
          key: 'cmdb_ci_service'
      },
      'task_ci': {
          property: 'com.snc.incident.copy.rl.task_ci.attributes',
          parentAttr: 'task',
          defaultValue: 'ci_item',
          key: 'ci_item'
      },
      'task_service_offering': {
          property: 'com.snc.incident.copy.rl.task_service_offering.attributes',
          parentAttr: 'task',
          defaultValue: 'service_offering',
          key: 'service_offering'
      },
      'task_cmdb_ci_business_app': {
          property: 'com.snc.incident.copy.rl.task_cmdb_ci_business_app.attributes',
          parentAttr: 'task',
          defaultValue: 'business_application',
          key: 'business_application'
      }
  },
  ACTION_TYPE: {
      COPY_INCIDENT: "copy_incident",
      CREATE_CHILD_INCIDENT: "create_child_incident"
  },
  	
  RESOLUTION_CODES: {
  	SOLVED_WORKAROUND: "Solved (Work Around)",
  	SOLVED_REMOTELY_WORKAROUND: "Solved Remotely (Work Around)",
  	WORKAROUND_PROVIDED: "Workaround provided"
  },

  initialize: function() {
      this.arrayUtil = new ArrayUtil();
  },

  canCopyIncident: function(gr) {
      if (gs.hasRole(this.ROLE_ITIL))
          return true;
      if (GlidePluginManager.isActive(this.PLUGIN_GRANULAR_ITSM_ROLES) && gs.hasRole(this.ROLE_SN_INCIDENT_WRITE))
          return true;
      return gr.getValue(this.FIELD_CALLER_ID) == gs.getUserID();
  },

  copyIncidentAttachments: function(srcSysId, targetSysId, userSelection) {
      var isCopyEnabled = gs.nil(userSelection) ? gs.getProperty(this.PROP_INCIDENT_COPY_ATTACH, 'true') == 'true' : userSelection + '' === 'true';
      if (isCopyEnabled) {
          var gr = new GlideRecord(this.INCIDENT);
          if (gr.get(srcSysId) && gr.canRead())
              return this._copyAttachments(gr, targetSysId);
          else
              this.log.logWarning('copyIncidentAttachments: Provided INCIDENT does not exist or the user is not authorized to perform this action- ' + srcSysId);
      }
  },

  copyIncidentRelatedLists: function(srcIncSysID, newIncSysID) {
      var relatedTables = this._getCsvPropertyValue(this.PROP_INCIDENT_COPY_RELATED_LISTS, '');
      for (var i = 0; i < relatedTables.length; ++i) {
          var table = relatedTables[i];
          var ans = this._makeRelatedTableCopy(srcIncSysID, newIncSysID, table);
          if (!this._isSet(ans)) {
              this.log.logWarning('copyIncidentRelatedLists: Could not copy related table ' + table);
              return false;
          }
      }
      return true;
  },

  makeRelatedTableCopy: function( /*String*/ srcParentSysId,
      /*String*/
      targetParentSysId,
      /*String*/
      table,
      /*String*/
      key,
      /*String*/
      parentAttr,
      /*Array*/
      copyAttrs) {
      var ans = [];
      copyAttrs = this.arrayUtil.diff(copyAttrs, this.ALWAYS_IGNORE_ATTRS, [parentAttr]);
      var srcGr = new GlideRecord(table);
      if (srcGr.isValid()) {
          var existingRecords = [];
          srcGr.addQuery(parentAttr, srcParentSysId);
          srcGr.query();

          if (key)
              existingRecords = this._getTargetRelatedRecordKeys(table, key, parentAttr, targetParentSysId);

          while (srcGr.next()) {
              if ((key && this.arrayUtil.contains(existingRecords, srcGr.getValue(key))) || !srcGr.canRead())
                  continue;

              var newSysId = this._makeRelatedRecordCopy(srcGr, copyAttrs, parentAttr, targetParentSysId);
              if (newSysId)
                  ans.push(newSysId);
              else
                  this.log.logWarning('makeRelatedTableCopy: Could not copy related table ' + table);
          }

          return ans;
      } else
          this.log.logWarning('makeRelatedTableCopy: Invalid table ' + table);
  },

  getRedirectUrlForIncidentForm: function(actionVerb, sysId) {
      return this._getRedirectUrlForForm(actionVerb, sysId, this.INCIDENT);
  },

  getCsvValue: function(val) {
      val = val.trim().split(',');
      for (var i = 0; i < val.length;) {
          val[i] = val[i].trim();
          if (!val[i]) {
              val.splice(i, 1);
          } else {
              i++;
          }
      }
      return val;
  },
  
  majorIncidentFilterCheck: function(gr, condition) {
  	var match = GlideFilter.checkRecord(gr, condition);
  	return match;
  },

  _isMajorIncident: function(current) {
      if (!pm.isActive("com.snc.incident.mim"))
          return false;
      return current.major_incident_state == "accepted";
  },

  canResolveIncident: function(current) {
      if (current.incident_state == IncidentState.CLOSED || current.incident_state == IncidentState.RESOLVED || current.incident_state == IncidentState.CANCELED)
          return false;
      if (gs.hasRole("itil_admin,itil,sn_incident_write"))
          return true;
      if (current.caller_id == gs.getUserID())
          return !this._isMajorIncident(current);
      return false;
  },

  canCloseIncident: function(current) {
      if (current.incident_state != IncidentState.RESOLVED)
          return false;
      if (gs.hasRole("itil_admin"))
          return true;
      if (this._isMajorIncident(current))
          return (current.caller_id == gs.getUserID() && gs.getUser().hasRoles()) || gs.hasRole("major_incident_manager");
      else if (current.caller_id == gs.getUserID())
          return true;
      return false;
  },

  canReopenIncident: function(current) {
      return current.incident_state == IncidentState.RESOLVED && !gs.getUser().hasRoles() && !this._isMajorIncident(current);
  },

  isCopyIncidentFlagValid: function() {
      var isCopyIncidentPropEnabled = gs.getProperty(this.PROP_INCIDENT_COPY_ENABLED, 'false');

      return isCopyIncidentPropEnabled == 'true';
  },

  isCreateChildIncidentFlagValid: function() {
      var isCreateChildIncidentEnabled = gs.getProperty(this.PROP_CREATE_CHILD_INCIDENT, 'false');

      return isCreateChildIncidentEnabled == 'true';
  },

  _isCreateChildIncidentAction: function(uiActionType) {
      return uiActionType == this.ACTION_TYPE.CREATE_CHILD_INCIDENT;
  },

  _getAttributeList: function() {
      var fieldList = this._getCsvPropertyValue(this.PROP_INCIDENT_COPY_ATTRS, this.INCIDENT_DEFAULT_ATTR_VALUE);
      return this.arrayUtil.diff(fieldList, this.ALWAYS_IGNORE_ATTRS);
  },

  _isCopyIncidentAction: function(action) {
      return action == this.ACTION_TYPE.COPY_INCIDENT;
  },

  _copyAttachments: function(srcGr, targetSysId) {
      var res = [];
      if (srcGr.hasAttachments()) {
          var table = srcGr.getTableName();
          res = j2js(GlideSysAttachment.copy(table, srcGr.getUniqueValue(), table, targetSysId));
      }
      return res;
  },

  _makeRelatedTableCopy: function(srcParentSysId, targetParentSysId, table) {
      var map = this.RELATED_TABLES_MAP[table];
      if (!map) {
          this.log.logWarning('_makeRelatedTableCopy: Unsupported related table ' + table);
          return;
      }
      var key = map.key;
      var parentAttr = map.parentAttr;
      var copyAttrs = this._getCsvPropertyValue(map.property, map.defaultValue);
      return this.makeRelatedTableCopy(srcParentSysId, targetParentSysId, table, key, parentAttr, copyAttrs);
  },

  _makeRelatedRecordCopy: function(srcGr, copyAttrs, parentAttr, targetParentSysId) {
      var gr = this._makeRecordCopy(srcGr, copyAttrs);
      gr.setValue(parentAttr, targetParentSysId);
      if (gr.canCreate())
          return gr.insert();
  },

  _makeRecordCopy: function(srcGr, copyAttrs) {
      var table = srcGr.getTableName();
      var gr = new GlideRecord(table);
      gr.initialize();
      for (var i = 0; i < copyAttrs.length; ++i) {
          var field = copyAttrs[i];
          if (srcGr.isValidField(field))
              gr.setValue(field, srcGr.getValue(field));
          else
              this.log.logWarning("_makeRecordCopy: Invalid field '" + field + "' provided for table '" + table + "'.");
      }
      return gr;
  },

  _getTargetRelatedRecordKeys: function(table, key, parentAttr, targetParentSysId) {
      var ans = [];
      var gr = new GlideRecord(table);
      gr.addQuery(parentAttr, targetParentSysId);
      gr.query();
      while (gr.next()) {
          ans.push(gr.getValue(key));
      }
      return ans;
  },

  _isSet: function(obj) {
      // Unlike browsers, Rhino condition evaluation
      // returns false when the passed obj is array
      // and has length 0. We want the browser behavior.
      return obj || JSUtil.type_of(obj) === 'object';
  },

  _getRecordValuesAsEncodedQuery: function(record, attributesList, uiActionType) {
      var table = record.getTableName();
      var gr = new GlideRecord(table);
      var activeAttrsToCopy = [];
      // If action is of type "Copy Incident", loop through COPY_IF_ACTIVE_ATTRS list,
      // and skip copying inactive fields.
      if (this._isCopyIncidentAction(uiActionType)) {
          for (var index = 0; index < this.COPY_IF_ACTIVE_ATTRS.length; index++) {
              var attr = this.COPY_IF_ACTIVE_ATTRS[index];
              var activeIndex = attributesList.indexOf(attr);
              if (activeIndex != -1) {
                  attributesList.splice(activeIndex, 1);
                  if (record[attr].active == 1)
                      activeAttrsToCopy.push(attr);
              }
          }
      }

      for (var i = 0; i < attributesList.length; ++i) {
          var name = attributesList[i];
          if (record.isValidField(name)) {
              if (record.getValue(name)) {
                  if (!gs.nil(record.getElement(name)) && !gs.nil(record.getElement(name).getED())) {
                      var ed = record.getElement(name).getED();
                      // We have to use the display value if it's a date based field for form filter
                      if (ed.getInternalType() == "glide_date_time" || ed.isEncrypted())
                          gr.addQuery(name, record.getDisplayValue(name));
                      else
                          gr.addQuery(name, record.getValue(name));
                  } else
                      gr.addQuery(name, record.getValue(name));
              }
          } else
              this.log.logWarning("Invalid field '" + name + "' provided for table '" + table + "'.");
      }

      if (this._isCopyIncidentAction(uiActionType)) {
          for (var j = 0; j < activeAttrsToCopy.length; j++) {
              gr.addQuery(activeAttrsToCopy[j], record.getValue(activeAttrsToCopy[j]));
          }
          gr.addQuery(this.ATTR_WORK_NOTES, gs.getMessage('Created from a similar incident {0}', record.getValue(this.ATTR_NUMBER)));
      }

      if (this._isCreateChildIncidentAction(uiActionType)) {
          gr.addQuery(this.ATTR_PARENT_INCIDENT, record.getUniqueValue());
          gr.addQuery(this.ATTR_DOMAIN, record.getValue(this.ATTR_DOMAIN));
      }

      return gr.getEncodedQuery();
  },

  _getRedirectUrlForForm: function(actionVerb, sysId, table) {
      var urlOnStack = '';
      var suffix = '_and_stay';
      if (!JSUtil.nil(actionVerb) && ((actionVerb.indexOf(suffix, actionVerb.length - suffix.length) !== -1))) {
          var gu = new GlideURL(table + '.do');
          gu.set('sys_id', sysId);
          var createdIncidentUrl = gu.toString();
          urlOnStack = createdIncidentUrl;
      } else {
          if (!gs.getSession().getStack().isEmpty())
              urlOnStack = gs.getSession().getStack().pop();
          if (JSUtil.nil(urlOnStack))
              urlOnStack = 'welcome.do';
      }
      return urlOnStack;
  },

  _getCsvPropertyValue: function(ppty, defaultVal) {
      var val = gs.getProperty(ppty, defaultVal);
      return this.getCsvValue(val);
  },

  getGlideStackURL: function(stackName) {
      var stack = gs.getSession().getStack(stackName);
      return {
          url: stack.back()
      };
  },

  setGlideStackURL: function(url, stackName) {
      var stack = gs.getSession().getStack(stackName);
      var stackUrl = stack.push(url);
      return {
          url: stackUrl
      };
  },

  getTopGlideStackURL: function(stackName) {
      var stack = gs.getSession().getStack(stackName);
      return {
          url: stack.top()
      };
  },
  canCreateRecord: function(tableName) {
      return GlideTableDescriptor.get(tableName).canCreate();
  },
  isChatEnabled: function() {
      return GlideCollaborationCompatibility.isChatEnabled() && GlideCollaborationCompatibility.isFrameSetEnabled();
  },

  /*method which needs to be in TCM, but for lack of addDomainQuery is placed here. Move back when PRB1261386 is fixed*/
  getPlanInstanceGr: function(planInstanceTable, sourceRecordGr) {
      var planInstanceCheckGr = new GlideRecord(planInstanceTable);
      planInstanceCheckGr.addQuery('source', sourceRecordGr.getUniqueValue());
      planInstanceCheckGr.addNotNullQuery('comm_plan_definition');
      planInstanceCheckGr.addDomainQuery(sourceRecordGr);
      planInstanceCheckGr.query();
      return planInstanceCheckGr;
  },

  /*method which needs to be in TCM, but for lack of addDomainQuery is placed here. Move back when PRB1261386 is fixed*/
  getPlanDefinitionGr: function(sourceRecordGr, planDefsAlreadyAttached) {
      var planDefGr = new GlideRecord('comm_plan_definition');
      planDefGr.addActiveQuery();
      planDefGr.addQuery('table', sourceRecordGr.getRecordClassName() + '');
      planDefGr.addQuery('condition_based', true);
      planDefGr.addQuery('sys_id', 'NOT IN', planDefsAlreadyAttached.join(','));
      planDefGr.addDomainQuery(sourceRecordGr);
      planDefGr.orderBy('order');
      planDefGr.query();
      return planDefGr;
  },

  /*method which needs to be in TCM, but for lack of addDomainQuery is placed here. Move back when PRB1261386 is fixed*/
  getTaskDefinitionGr: function(planInstanceGr) {
      var planTaskDefGr = new GlideRecord('comm_task_definition');
      planTaskDefGr.addActiveQuery();
      planTaskDefGr.addQuery('comm_plan_definition', planInstanceGr.comm_plan_definition);
      planTaskDefGr.addDomainQuery(planInstanceGr);
      planTaskDefGr.orderBy('order');
      planTaskDefGr.query();
      return planTaskDefGr;
  },

  /*method which needs to be in TCM, but for lack of addDomainQuery is placed here. Move back when PRB1261386 is fixed*/
  getChannelDefintionGr: function(channelDefTable, planTaskDef, planTaskGr, channel) {
      var channelDefGr = new GlideRecord(channelDefTable);
      if (!channelDefGr.isValid())
          return false;

      channelDefGr.addQuery('comm_task_definition', planTaskDef);
      channelDefGr.addDomainQuery(planTaskGr);
      channelDefGr.query();
      return channelDefGr;
  },

  /*method which needs to be in TCM, but for lack of addDomainQuery is placed here. Move back when PRB1261386 is fixed*/
  getContactDefinitionGr: function(planGr) {
      var contactDefGr = new GlideRecord('comm_contact_definition');
      contactDefGr.addQuery('comm_plan_definition', planGr.comm_plan_definition);
      contactDefGr.addDomainQuery(planGr);
      contactDefGr.query();
      return contactDefGr;
  },

  formatTimeForINCTimeline: function(gdt) {
      var sdt = new GlideScheduleDateTime(gdt);
      sdt.setTimeZone(gs.getProperty(this.PROP_GLIDE_SYS_TZ, this.TZ_UTC));
      gdt.setTZ(sdt.getTimeZone());
      return gdt.getLocalDate().getByFormat(gs.getProperty(this.PROP_GLIDE_SYS_DATE_FORMAT, this.DEFAULT_DATE_FORMAT)) + " " + gdt.getLocalTime().getByFormat(gs.getProperty(this.PROP_GLIDE_SYS_TIME_FORMAT, this.DEFAULT_TIME_FORMAT)) + "(" + sdt.getTimeZoneID() + ")";
  },

  getUserById: function(userId) {
      var g_user = GlideUser.getUser(userId);
      if (g_user)
          return g_user.getFullName();

      return gs.getMessage("Unknown");
  },

  getProblemFromIncident: function(current) {
      if (!current.isValidRecord())
          return undefined;

      var prob = new GlideRecord("problem");
  	prob.initialize();
  	if (prob.isValidField("first_reported_by_task"))
  		prob.first_reported_by_task = current.getUniqueValue();
  	prob.work_notes.setJournalEntry(gs.getMessage('Problem created from Incident {0}', current.number));
  	var incidentWorkaround = this.getWorkaround(current);
  	if (JSUtil.notNil(incidentWorkaround))
  		prob.workaround = incidentWorkaround;
  	
      var defaultCreateFromIncidentPropVal = 'description,short_description,cmdb_ci,impact,urgency,priority,company,sys_domain,business_service,service_offering';
      var createFromIncidentPropVal = gs.getProperty('com.snc.problem.create_from_incident.attributes', defaultCreateFromIncidentPropVal);
      var fieldsToBeCopiedFromIncident = this.getCsvValue(createFromIncidentPropVal);

      for (var i = 0; i < fieldsToBeCopiedFromIncident.length; i++) {
  		if (fieldsToBeCopiedFromIncident[i] === 'number')
  			continue;
  		else if (fieldsToBeCopiedFromIncident[i] === 'category') {
              var elCategory = prob.getElement("category");
              var choicesCategory = elCategory.getChoices();
              if (choicesCategory && choicesCategory.indexOf(current.category) >= 0)
                  prob.category = current.category;

          } else if (fieldsToBeCopiedFromIncident[i] === 'subcategory') {
              var elSubcategory = prob.getElement("subcategory");
              var choicesSubcategory = elSubcategory.getChoices(current.category);
              if (choicesSubcategory && choicesSubcategory.indexOf(current.subcategory) >= 0)
                  prob.subcategory = current.subcategory;

          } else if (prob.isValidField(fieldsToBeCopiedFromIncident[i])) {
              prob[fieldsToBeCopiedFromIncident[i]] = current[fieldsToBeCopiedFromIncident[i]];

          } else {
              gs.addErrorMessage(gs.getMessage("{0} is not a valid field in Problem", fieldsToBeCopiedFromIncident[i]));
              return undefined;
          }
      }
      return prob;
  },

  getUserByIdObj: function(userId) {
      var gUser = GlideUser.getUserByID(userId);
      return gUser;
  },

  canCreateKnowledgeGap: function(incidentGr) {
      return incidentGr.incident_state != IncidentState.CLOSED;
  },

  canAssignToMe: function(current) {
      if (!current.active && !current.isNewRecord())
          return false;
      if (!current.assigned_to.canWrite())
          return false;
      if (current.assigned_to == gs.getUserID())
          return false;
      return current.assignment_group.nil() || gs.getUser().isMemberOf(current.assignment_group.toString());
  },

  getMemberGroups: function(userSysID, setlimit) {
      var memberGroups = [];
      var grMembers = new GlideRecord(this.SYS_USER_GRMEMBER);
      grMembers.addQuery('group.active', 'true');
      grMembers.addQuery('user', userSysID);
      if (setlimit)
          grMembers.setLimit(setlimit);
      grMembers.query();
      while (grMembers.next()) {
          memberGroups.push(grMembers.group.sys_id);
      }
      return memberGroups;
  },
  	
  getWorkaround: function(incidentGr) {
  	var closeCode = incidentGr.getValue(this.FIELD_CLOSE_CODE);
  	var closeNotes = incidentGr.getValue(this.FIELD_CLOSE_NOTES);
  	if (JSUtil.nil(closeCode) || JSUtil.nil(closeNotes))
  		return;
  	if (GlidePluginManager.isActive(this.PLUGIN_INCIDENT_SANDIEGO)) {
  		if (closeCode === this.RESOLUTION_CODES.WORKAROUND_PROVIDED)
  			return closeNotes;
  	}
  	else {
  		if (closeCode === this.RESOLUTION_CODES.SOLVED_WORKAROUND || closeCode === this.RESOLUTION_CODES.SOLVED_REMOTELY_WORKAROUND)
  			return closeNotes;
  	}
  },
  
  canShowRelatedListUIAction: function(current, parent, uiAction){
  	var isValidated = false;
  	switch(uiAction){
  		case "add":
  			if ((new GlideRecord(current.getTableName())).canWrite() && new BulkAddIncidents().canShowAddButton(parent, current) && (gs.hasRole("itil") || (GlidePluginManager.isActive("com.snc.itsm.roles.incident_management") && gs.hasRole("sn_incident_write"))))
  				isValidated =  true;
  			break;
  			
  		case "new":
  			if((new GlideRecord(current.getTableName())).canCreate() && (gs.hasRole("itil") || (GlidePluginManager.isActive("com.snc.itsm.roles.incident_management") && gs.hasRole("sn_incident_write"))))
  				isValidated = true;
  			break;
  		default:
  			break;
  	}
  	return isValidated;
  },

  type: 'IncidentUtilsSNC'
};

Sys ID

a1b5e796531232000600e26b88dc3472

Offical Documentation

Official Docs: