Name

sn_sow_on_call.OnCallUtilsSowSNC

Description

No description available

Script

var OnCallUtilsSowSNC = Class.create();
OnCallUtilsSowSNC.prototype = {
  initialize: function() {
  	this.recommendedGroups = {};
  	this.MAX_CMDB_ITEMS_ALLOWED = 1;
  	this.MAX_RECOMMENDED_GROUPS_ALLOWED = 3;
  	this.TABLES = {
  		INCIDENT: "incident",
  		CMDB_CI: "cmdb_ci",
  		CMDB_CI_SERVICE: "cmdb_ci_service",
  		TASK_CI: "task_ci",
  		TASK_CMDB_CI_SERVICE: "task_cmdb_ci_service",
  		SHIFT: "cmn_rota",
  		SHIFT_MEMBER: "cmn_rota_member"
  	};
  	this.ORDERS = {
  		"business_service": 10,
  		"cmdb_ci": 20,
  		"impacted_services": 30,
  		"affected_ci_services": 60,
  		"assignment_group": 70
  	};
  	
  	this.CALCULATE_NEXT_SHIFT_FOR_DAYS = 30;
  },
  
  TCM_COLLAB_FEB_VERSION: 202202,

  isTeamsPluginActive: function() {
      var tcmCollabVersion = gs.getProperty("sn_tcm_collab_hook.version");
      return (GlidePluginManager.isActive('com.snc.ms_teams') && GlidePluginManager.isActive('com.snc.tcm_collab_hook')) && !gs.nil(tcmCollabVersion) && tcmCollabVersion >= this.TCM_COLLAB_FEB_VERSION;
  },

  isSupportedScreen: function(tableName, sysId) {
  	var supportedTablesStr = gs.getProperty('com.snc.sow_on_call.supported_tables');
  	if (!supportedTablesStr || !sysId)
  		return false;

  	var supportedTables = supportedTablesStr.split(',');
  	if (supportedTables.indexOf(tableName) === -1)
  		return false;
  	
  	var recordGr = new GlideRecord(tableName);
  	if (!recordGr.get(sysId))
  		return false;
  	
  	return true;
  },
  
  _isOnCallDefinedForTheGroup: function(groupSysId) {
  	var cmnRotaGr = new GlideRecord(this.TABLES.SHIFT);
  	cmnRotaGr.addQuery('group', groupSysId);
  	cmnRotaGr.addActiveQuery();
  	cmnRotaGr.query();

  	return cmnRotaGr.hasNext();
  },
  
  /*
   return the following format
   {
  	 <sys_id of the recommended group id>: {
  		 message: "Recommended from field name",
  		 order: <specify the order>
  	 }
   }
  */
  getRecommendedGroups: function(table, sysId, fieldWatchList) {
  	if(!table || !sysId) {
  		return {};
  	}
  	
  	var gr = new GlideRecord(table);
  	if (!gr.get(sysId))
  		return this.recommendedGroups;
  	
  	fieldWatchList = this._getObjectFromArray(fieldWatchList);
  	var self = this;
  	var recommendedGroupsCount = 0;
  		
  	if (table == this.TABLES.INCIDENT) {
  		var primaryService = fieldWatchList.business_service;
  		if (primaryService) {
  			var primaryServiceSupportGroup = this._getSupportGroups(this.TABLES.CMDB_CI_SERVICE, primaryService);
  			if (primaryServiceSupportGroup) {
  				this._updateRecommendedGroups(primaryServiceSupportGroup, gs.getMessage("Recommended based on primary service"), this.ORDERS["business_service"]);
  				recommendedGroupsCount++;
  			}
  		}

  		var primaryCI = fieldWatchList.cmdb_ci;
  		if (primaryCI) {
  			var primaryCISupportGroup = this._getSupportGroups(this.TABLES.CMDB_CI, primaryCI);
  			if (primaryCISupportGroup) {
  				this._updateRecommendedGroups(primaryCISupportGroup, gs.getMessage("Recommended based on primary CI"), this.ORDERS["cmdb_ci"]);
  				recommendedGroupsCount++;
  			}
  		}

  		if (recommendedGroupsCount < this.MAX_RECOMMENDED_GROUPS_ALLOWED) {
  			var impactedServicesSupportGroups = this._getImpactedServicesSupportGroups(gr);
  			impactedServicesSupportGroups.forEach(function(supportGroup) {
  				if (recommendedGroupsCount < self.MAX_RECOMMENDED_GROUPS_ALLOWED) {
  					self._updateRecommendedGroups(supportGroup, gs.getMessage("Recommended based on impacted services"), self.ORDERS["impacted_services"]);
  					recommendedGroupsCount++;
  				} else return;
  			});
  		}

  		if (recommendedGroupsCount < this.MAX_RECOMMENDED_GROUPS_ALLOWED) {
  			var affectedCISupportGroups = this._getAffectedCIsSupportGroups(gr);
  			affectedCISupportGroups.forEach(function(supportGroup) {
  				if (recommendedGroupsCount < self.MAX_RECOMMENDED_GROUPS_ALLOWED) {
  					self._updateRecommendedGroups(supportGroup, gs.getMessage("Recommended based on affected CIs"), self.ORDERS["affected_ci_services"]);
  					recommendedGroupsCount++;
  				} else return;
  			});
  		}

  		var assignmentGroup = fieldWatchList.assignment_group;
  		if (assignmentGroup && recommendedGroupsCount < this.MAX_RECOMMENDED_GROUPS_ALLOWED)
  			this._updateRecommendedGroups(assignmentGroup, gs.getMessage("Recommended based on assignment group"), this.ORDERS["assignment_group"]);
  	}
  	
  	return this.recommendedGroups;
  },
  
  getNextShiftDateTime: function(groupId) {
  	var startDate = new GlideDateTime();
  	var endDate = new GlideDateTime();
  	endDate.addDaysLocalTime(this.CALCULATE_NEXT_SHIFT_FOR_DAYS);

  	var formatter = new global.OCDHTMLXCalendarFormatter();

  	var spans = new global.OCRotationV2(null, formatter)
  		.setStartDate(startDate.getDate())
  		.setEndDate(endDate.getDate())
  		.setGroupIds(groupId)
  		.getSpans();

  	spans = spans.filter(function(span) {
  		return span.type != 'rota' && span.type != 'timeoff';
  	});

  	var earliestStartDate;

  	spans.forEach(function(span) {
  		var spanStartDate = new GlideDateTime();
  		spanStartDate.setDisplayValueInternal(span.start_date + "");

  		if (startDate.getNumericValue() < spanStartDate.getNumericValue() && (!earliestStartDate || spanStartDate.getNumericValue() < earliestStartDate.getNumericValue()))
  			earliestStartDate = spanStartDate;
  	});
  	
  	if (earliestStartDate) {
  		earliestStartDate.addDaysLocalTime(-1);
  		return earliestStartDate.getDisplayValueInternal();
  	}
  	
  	throw new Error("No on-call member available for the next 30 days");
  },

  handleChannelRedirect: function(table, sysId, userSysId) {
      var chatUtils = new sn_tcm_collab_hook.MSTeamsChatUtil();
      var sourceGr = new GlideRecord(table);
      if (!sourceGr.get(sysId)) {
          return '';
      }

      var userIds = [userSysId, gs.getUserID()];
  	
      var clientType = gs.getUser().getPreference('sn_tcm_collab_hook_teams_preferred_client') || 'web_client';
      var autoImport = chatUtils.importChatUtil.isAutoImportEnabled(sourceGr);
      var appDetails = new sn_tcm_collab_hook.MSTeamsChatUtil().getAppDetails();
      var useIHActionsForSingleTenant = new sn_tcm_collab_hook.MSTeamsChatUtil().useIHActionsForSingleTenant();

      if (!("multiTenant" in appDetails) && !useIHActionsForSingleTenant)
          return '';

  	
      if (appDetails.multiTenant || useIHActionsForSingleTenant) {
  		try {
  			var chatInfo = new sn_tcm_collab_hook.MSTeamsChatUtil().createChatFromChatModal(sourceGr, userIds, null, null, clientType, autoImport);
  			var requesterUserGr = this._getRecordById("sys_user", userSysId);
  			new sn_tcm_collab_hook.MSTeamsAjaxUtils().addCommentForGroupChat(GlideStringUtil.escapeHTML(gs.getUserDisplayName()), GlideStringUtil.escapeHTML(requesterUserGr.getDisplayValue('name')), '[]', table, sysId, 'work_notes', chatInfo);
  			
  			return chatInfo.url;
  		}

  		catch (e) {
  			var error = {};
  			error.errorMsg = e.message;
  			return error;
  		}
          
      }
  
  	throw new Error();
  },
  
  _getRecordById: function(table, id) {
  	var gr = new GlideRecord(table);
  	if (gr.get(id))
  		return gr;
  },
  
  _getObjectFromArray: function(fieldsMapArr) {
  	if (!fieldsMapArr && fieldsMapArr.length == 0) {
  		return {};
  	}
  	
  	var output = {};
  	fieldsMapArr.forEach(function(fieldMap) {
  		output[fieldMap.field] = fieldMap.value;
  	});
  	
  	return output;
  },
  
  _getCommonlyUsedGroups: function(table, column, count, encodedQuery) {
  	var ga = new GlideAggregate(table);
  	ga.addAggregate('COUNT', column);
  	ga.orderByAggregate('COUNT', column);
  	if (encodedQuery)
  		ga.addEncodedQuery(encodedQuery);
  	ga.query();
  	
  	var supportGroups = [];
  	
  	while (ga.next() &&  count > 0) {
  		var supportGroupSysId = ga.getValue(column);
  		if (!this.recommendedGroups[supportGroupSysId] && this._isOnCallDefinedForTheGroup(supportGroupSysId)) {
  			supportGroups.push(supportGroupSysId);
  			count--;
  		}
  	}
  	
  	return supportGroups;
  },
  
  _getAffectedCIsSupportGroups:  function(recordGr) {
  	var encodedQuery = "task=" + recordGr.getUniqueValue();
  	return this._getCommonlyUsedGroups(this.TABLES.TASK_CI, "ci_item.support_group", this.MAX_CMDB_ITEMS_ALLOWED, encodedQuery);
  },
  
  _getImpactedServicesSupportGroups: function(recordGr) {
  	var encodedQuery = "task=" + recordGr.getUniqueValue();
  	return this._getCommonlyUsedGroups(this.TABLES.TASK_CMDB_CI_SERVICE, "cmdb_ci_service.support_group", this.MAX_CMDB_ITEMS_ALLOWED, encodedQuery);
  },
  
  _getSupportGroups: function(table, sysId) {
  	var cmdbGr = this._getRecordById(table, sysId);
  	if (cmdbGr.isValidRecord() && cmdbGr.support_group) {
  		return cmdbGr.support_group + "";
  	}
  	return "";
  },
  
  _updateRecommendedGroups: function(groupSysId, message, order) {
  	if (this.recommendedGroups[groupSysId] || !this._isOnCallDefinedForTheGroup(groupSysId))
  		return;
  	this.recommendedGroups[groupSysId] = {
  		message: message,
  		order: order
  	};
  },

  type: 'OnCallUtilsSowSNC'
};

Sys ID

8b26aebc53723010610bddeeff7b128b

Offical Documentation

Official Docs: