Name
sn_sow_on_call.OnCallRotationSowSNC
Description
ServiceNow On-Call Rotation for SOW implementation
Script
var OnCallRotationSowSNC = Class.create();
OnCallRotationSowSNC.LOG_PROPERTY = 'com.snc.on_call_rotation.log.level';
OnCallRotationSowSNC.prototype = {
initialize: function() {
this._log = new global.GSLog(OnCallRotationSowSNC.LOG_PROPERTY, this.type);
global.OnCallRotation.prototype.prepareOnCallGroupsDataGroup = OnCallRotationSowSNC.methods.prepareOnCallGroupsDataGroup.bind(this);
global.OnCallRotation.prototype.prepareOnCallGroupsDataRota = OnCallRotationSowSNC.methods.prepareOnCallGroupsDataRota.bind(this);
global.OnCallRotation.prototype.prepareOnCallGroupsDataRoster = OnCallRotationSowSNC.methods.prepareOnCallGroupsDataRoster.bind(this);
global.OnCallRotation.prototype.prepareOnCallGroupsDataMember = OnCallRotationSowSNC.methods.prepareOnCallGroupsDataMember.bind(this);
global.OnCallRotation.prototype.prepareOnCallGroupsDataUser = OnCallRotationSowSNC.methods.prepareOnCallGroupsDataUser.bind(this);
global.OnCallRotation.prototype._getGroupsWithRotasByName = OnCallRotationSowSNC.methods._getGroupsWithRotasByName.bind(this);
this._onCallRotation = new global.OnCallRotation();
},
_getUsers: function(userSysIds) {
return this._onCallRotation._getUsers(userSysIds);
},
processIndividualOCData: function (groupsData, gdt) {
return this._onCallRotation.processIndividualOCData(groupsData, gdt);
},
simulateEscalationToAllRotas: function (indicator) {
return this._onCallRotation.simulateEscalationToAllRotas(indicator);
},
getOnCallGroupData: function(dateTime, offset, groupsLimit, textSearch, excludeGroupSysIds, showOnlyActiveGroups) {
dateTime = dateTime || '';
textSearch = textSearch || '';
offset = offset || 0;
excludeGroupSysIds = excludeGroupSysIds || '';
if (this._log.atLevel(global.GSLog.DEBUG))
this._log.debug('[getOnCallGroupData] dateTime: ' + dateTime);
this._recommendedGroups = (excludeGroupSysIds || '').split(',');
return this._onCallRotation.getOnCallGroupData(dateTime, offset, groupsLimit, textSearch, excludeGroupSysIds, showOnlyActiveGroups);
},
getOnCallGroupDataByGroupSysId: function(dateTime, groupSysIds) {
dateTime = dateTime || '';
groupSysIds = groupSysIds || '';
if (this._log.atLevel(global.GSLog.DEBUG))
this._log.debug('[getOnCallGroupDataByGroupSysId] dateTime: ' + dateTime + ' groupSysIds: ' + groupSysIds);
this._recommendedGroups = (groupSysIds || '').split(',');
return this._onCallRotation.getOnCallGroupDataByGroupSysId(dateTime, groupSysIds);
},
/**
* This returns the next request time in UTC factoring:
* 1. End of current and Start next shift
* 2. End of current and Start next cover record
* 3. End of current and Start next Time Off record
* 4. End of current and Start next Extra Time record
*/
_getNextRequestDateTimeUTC: function(rotaGr, gdt) {
if (!rotaGr)
return null;
gdt = gdt || new GlideDateTime();
var span = this.getSpanByGdt(rotaGr.getValue('schedule', gdt));
if (!span)
return null;
return span.getEnd() + '';
},
_getRosterCount: function(rotaGr) {
var rosterCount = 0;
if (!rotaGr)
return rosterCount;
var groupSysId = rotaGr.getValue('group');
var rotaSysId = rotaGr.getUniqueValue();
var ga = new GlideAggregate('cmn_rota_roster');
ga.addAggregate('COUNT');
ga.addQuery('rota', rotaSysId);
ga.addQuery('active', true);
ga.query();
rosterCount = parseInt(ga.next() ? ga.getAggregate('COUNT') : 0);
if (this._log.atLevel(global.GSLog.DEBUG))
this._log.debug('[_getRosterCount] rosterCount: ' + rosterCount);
return rosterCount;
},
/**
* This returns rota details message used by UIB/WEP oncall macroponent
* example is: 2 members on-call from 8:00 AM yesterday to 5:00 PM today
*/
_getRotaDetailsMsg: function(dateTime) {
var msg = '';
if (!dateTime || !dateTime.start || !dateTime.end)
return msg;
var start = dateTime.start;
var end = dateTime.end;
msg = gs.getMessage('From {0} to {1}', [start, end]);
if (this._log.atLevel(global.GSLog.DEBUG))
this._log.debug('[_getRotaDetailsMsg] msg: ' + msg);
return msg;
},
getDaysDifference: function(startDateTime, endDateTime) {
var start = new GlideDate();
start.setValue(startDateTime.getLocalDate());
var end = new GlideDate();
end.setValue(endDateTime.getLocalDate());
var diff = GlideDate.subtract(start, end);
return diff.getRoundedDayPart();
},
_getRotaHumanizedDetailsMsg: function(dateTime) {
var msg = '';
if (!dateTime || !dateTime.start || !dateTime.end)
return msg;
var start = dateTime.start;
var end = dateTime.end;
var gdt = new GlideDateTime();
gdt.setDisplayValue(start);
var startGdt = new GlideDateTime(gdt);
gdt.setDisplayValue(end);
var endGdt = new GlideDateTime(gdt);
endGdt.addSeconds(-1);
var dayDiff = 0;
msg = gs.getMessage('From {0} to {1}', [startGdt.getDisplayValue(), endGdt.getDisplayValue()]);
var nowGdt = new GlideDateTime();
var startEndDaysDiff = this.getDaysDifference(startGdt, endGdt);
var startDayDiff = this.getDaysDifference(nowGdt, startGdt);
var endDayDiff = this.getDaysDifference(nowGdt, endGdt);
if (startEndDaysDiff === 0) {
if (endDayDiff === 0) {
msg = gs.getMessage('From {0} to {1} today', [startGdt.getTime().getDisplayValue(), endGdt.getTime().getDisplayValue()]);
}
else if (endDayDiff === -1) {
msg = gs.getMessage('From {0} to {1} yesterday', [startGdt.getTime().getDisplayValue(), endGdt.getTime().getDisplayValue()]);
}
else if (endDayDiff === 1) {
msg = gs.getMessage('From {0} to {1} tomorrow', [startGdt.getTime().getDisplayValue(), endGdt.getTime().getDisplayValue()]);
}
} else {
if (startDayDiff === 0) {
if (endDayDiff === 1) {
msg = gs.getMessage('From {0} today to {1} tomorrow', [startGdt.getTime().getDisplayValue(), endGdt.getTime().getDisplayValue()]);
} else {
msg = gs.getMessage('From {0} today to {1}', [startGdt.getTime().getDisplayValue(), endGdt.getDisplayValue()]);
}
}
else if (startDayDiff === -1) {
if (endDayDiff === 0) {
msg = gs.getMessage('From {0} yesterday to {1} today', [startGdt.getTime().getDisplayValue(), endGdt.getTime().getDisplayValue()]);
}
else if (endDayDiff === 1) {
msg = gs.getMessage('From {0} yesterday to {1} tomorrow', [startGdt.getTime().getDisplayValue(), endGdt.getTime().getDisplayValue()]);
} else {
msg = gs.getMessage('From {0} yesterday to {1}', [startGdt.getTime().getDisplayValue(), endGdt.getDisplayValue()]);
}
}
else if (startDayDiff === 1) {
msg = gs.getMessage('From {0} tomorrow to {1}', [startGdt.getTime().getDisplayValue(), endGdt.getDisplayValue()]);
}
}
if (this._log.atLevel(global.GSLog.DEBUG))
this._log.debug('[_getRotaHumanizedDetailsMsg] msg: ' + msg);
return msg;
},
_getLocation: function(userSysId) {
if (!userSysId)
return;
var userGr = new GlideRecord('sys_user');
if (!userGr.get(userSysId))
return;
var locationGr = userGr.location.getRefRecord();
if (locationGr && locationGr.canRead())
return {
city: {
display_value: locationGr.getDisplayValue("city")
}
};
},
contains: function (arr, obj) {
var i = arr.length;
while (i--)
if (arr[i] === obj)
return true;
return false;
},
getSpanByGdt: global.OnCallRotationSNC._getSpanByGdt,
getRotaTime: global.OnCallRotationSNC._getRotaTime,
type: 'OnCallRotationSowSNC'
};
OnCallRotationSowSNC.methods = {
prepareOnCallGroupsDataGroup: function(groupGr, group) {
if (!group)
return;
group.isRecommended = this.contains(this._recommendedGroups, group.sys_id);
return group;
},
prepareOnCallGroupsDataRota: function(rotaGr, rota) {
if (!rota)
return null;
var rotaTime = this.getRotaTime(rotaGr.getValue('schedule'));
var rosterCount = this._getRosterCount(rotaGr);
var membersMsg = '';
if (rosterCount < 1)
membersMsg = gs.getMessage('No members currently available');
else if (rosterCount === 1)
membersMsg = gs.getMessage('{0} member on-call', [rosterCount + '']);
else
membersMsg = gs.getMessage('{0} members on-call', [rosterCount + '']);
rota.details = {
"members": membersMsg,
"default": this._getRotaDetailsMsg(rotaTime),
"humanized": this._getRotaHumanizedDetailsMsg(rotaTime)
};
rota.nextRequestDateTimeUTC = this._getNextRequestDateTimeUTC(rotaGr);
return rota;
},
prepareOnCallGroupsDataRoster: function(rosterGr, roster) {
if (!roster)
return;
return roster;
},
prepareOnCallGroupsDataMember: function(memberGr, member) {
if (!member)
return;
return member;
},
prepareOnCallGroupsDataUser: function(glideUser, user) {
if (!user || !user.sys_id)
return;
var location = this._getLocation(user.sys_id + "");
user.city = location && location.city ? location.city.display_value : '';
return user;
},
_getGroupsWithRotasByName: function(textSearch) {
var gr = new GlideRecord('cmn_rota');
var encodedQuery = 'active=true^group.active=true^ORDERBYgroup.name';
if (textSearch)
encodedQuery += '^group.nameLIKE' + textSearch;
gr.addEncodedQuery(encodedQuery);
gr.query();
var groupKeys = {};
while (gr.next()) {
groupKeys[gr.group.getRefRecord().getUniqueValue()] = true;
}
return Object.keys(groupKeys);
}
};
Sys ID
a962c877535630100999ddeeff7b12a2