Name

global.OCRotaMember

Description

Class to represent a cmn_rota_member record for on-call scheduling.

Script

var OCRotaMember = Class.create();
OCRotaMember.prototype = {
  initialize: function() {
  	this.log = new GSLog("com.snc.on_call_rotation.log.level", this.type);
  },

  deactivateUser: function(userId, deactivateDate) {
  	if (JSUtil.nil(deactivateDate))
  		deactivateDate = new GlideDateTime();

  	var gr = new GlideRecord('cmn_rota_member');
  	gr.addActiveQuery();
  	gr.addQuery('member', userId);
  	gr.addNullQuery('to');
  	gr.query();
  	while (gr.next()) {
  		gr.setValue('to', deactivateDate);
  		gr.update();
  	}
  },

  hasOrderChanged: function(current, previous) {
  	var highestOrder = current.order > previous.order ? current.order : previous.order;
  	var lowestOrder = current.order < previous.order ? current.order : previous.order;

  	if (this.log.atLevel(GSLog.DEBUG)) {
  		this.log.debug("[hasOrderChanged] highestOrder: " + highestOrder + " lowestOrder: " + lowestOrder);
  		this.log.debug("[hasOrderChanged] previous: " + previous.getUniqueValue());
  		this.log.debug("[hasOrderChanged] current: " + current.getUniqueValue());
  	}

  	// check if jumping members
  	var membersGr = new GlideRecord("cmn_rota_member");
  	membersGr.addQuery("sys_id", "!=", previous.getUniqueValue());
  	membersGr.addQuery("roster", current.roster + "");
  	membersGr.addQuery("order", ">=", lowestOrder);
  	membersGr.addQuery("order", "<=", highestOrder);
  	membersGr.query();
  	var rows = membersGr.getRowCount();
  	var changed = rows != 0;

  	if (this.log.atLevel(GSLog.DEBUG)) {
  		this.log.debug("[hasOrderChanged] changed: " + changed);
  		while (membersGr.next())
  			this.log.debug("[hasOrderChanged] membersGr.sys_id: " + membersGr.getUniqueValue() + " order: " + membersGr.order);
  	}

  	return changed;
  },

  validateDates: function(from, to) {
  	// ensure from date is before the to date
  	if (JSUtil.nil(from) && JSUtil.nil(to))
  		return true;

  	var fromGd = new GlideDate();
  	fromGd.setValue(from);
  	var toGd = new GlideDate();
  	toGd.setValue(to);
  	return fromGd.compareTo(toGd) <= 0;
  },

  hasChanged: function(current, previous) {
  	var changed = current.member.changes() || current.to.changes() || current.from.changes() || this.hasOrderChanged(current, previous);

  	if (this.log.atLevel(GSLog.DEBUG))
  		this.log.debug("[hasChanged] changed: " + changed);

  	return changed;
  },

  recalculate: function(current) {
  	if (this.log.atLevel(GSLog.DEBUG))
  		this.log.debug("[recalculate] roster: " + current.roster);

  	OnCallRotationRecalc.updateSchedules(current.roster.getRefRecord());
  },
  
  rotaRepeatLimitExceeded: function(gr) {
  	if (!gr)
  		return false;

  	var rosterGR;
  	var tableName = gr.getRecordClassName();
  	if ("cmn_rota_roster" === tableName)
  		rosterGR = gr;
  	else if ("cmn_rota_member" === tableName) {
  		rosterGR = new GlideRecord("cmn_rota_roster");
  		if (!rosterGR.get(gr.getValue("roster")))
  			return false;
  	} else
  		return false;
  	
  	var rotationInterval = parseInt(rosterGR.getValue("rotation_interval_count"), 10);
  	var weeklyInterval = "weekly" === rosterGR.getValue("rotation_interval_type");
  	if (weeklyInterval)
  		rotationInterval *= 7;

  	var memberCount = 0;
  	var ga = new GlideAggregate("cmn_rota_member");
  	ga.addQuery("roster", rosterGR.getUniqueValue());
  	ga.addAggregate("COUNT");
  	ga.query();
  	if (ga.next())
  		memberCount = parseInt(ga.getAggregate("COUNT"), 10);
  	
  	// Add 1 to member Count as we are factoring the insert of a new cmn_rota_member record
  	if ("cmn_rota_member" === tableName)
  		memberCount++;
  	if (memberCount > 0)
  		rotationInterval *= memberCount;

  	var maxRepeatCount = parseInt(gs.getProperty("com.snc.on_call_rotation.max_rotation_repeat_count", 182000), 10);

  	if (rotationInterval <= maxRepeatCount)
  		return false;

  	var dailyIntervalCount = Math.floor(maxRepeatCount / memberCount);
  	
  	if ("cmn_rota_roster" === tableName)
  		if (weeklyInterval)
  			gs.addErrorMessage(gs.getMessage("The repeat count for each member has exceeded the limit of {0} years ({1} weeks/{2} days). For {3} members, the value of 'Rotate every' for the roster should be set to {4} weeks to be within the limit.", [Math.floor(maxRepeatCount / 364) + "", Math.floor(maxRepeatCount / 7) + "", maxRepeatCount + "", memberCount + "", Math.floor(dailyIntervalCount / 7) + ""]));
  		else
  			gs.addErrorMessage(gs.getMessage("The repeat count for each member has exceeded the limit of {0} years ({1} days/{2} weeks). For {3} members, the value of 'Rotate every' for the roster should be set to {4} days to be within the limit.", [Math.floor(maxRepeatCount / 364) + "", Math.floor(maxRepeatCount / 7) + "", maxRepeatCount + "", memberCount + "", dailyIntervalCount + ""]));
  	else
  		if (weeklyInterval)
  			gs.addErrorMessage(gs.getMessage("The repeat count for each member has exceeded the limit of {0} years ({1} weeks/{2} days). To add another member, the value of 'Rotate every' for the roster should be set to {3} weeks, for a total of {4} members to be within the limit.", [Math.floor(maxRepeatCount / 364) + "", Math.floor(maxRepeatCount / 7) + "", maxRepeatCount + "", Math.floor(dailyIntervalCount / 7) + "", memberCount + ""]));
  		else
  			gs.addErrorMessage(gs.getMessage("The repeat count for each member has exceeded the limit of {0} years ({1} weeks/{2} days). To add another member, the value of 'Rotate every' for the roster should be set to {3} days, for a total of {4} members to be within the limit.", [Math.floor(maxRepeatCount / 364) + "", Math.floor(maxRepeatCount / 7) + "", maxRepeatCount + "", dailyIntervalCount + "", memberCount + ""]));
  	
  	return true;
  },

  type: 'OCRotaMember'
};

Sys ID

45858be29f3212000391b89a442e709b

Offical Documentation

Official Docs: