Name
global.AgentScheduleUtil
Description
No description available
Script
var AgentScheduleUtil = Class.create();
AgentScheduleUtil.prototype = {
initialize: function() {
this.iso8601 = true;
this.timezoneMap = null;
this.workScheduleTimeMapCache = null;
},
getUsersTZ : function (users) {
var timezoneMap = {};
var usersNew = [];
if (this.timezoneMap != null) {
for(var i = 0; i < users.length ; i ++ ){
var localuser = users[i];
var retrievedTimezone = this.timezoneMap[localuser];
if (retrievedTimezone) {
timezoneMap[localuser] = retrievedTimezone;
} else {
usersNew.push(localuser);
}
}
} else {
this.timezoneMap = {};
usersNew = users;
}
if (usersNew.length > 0) {
var user = new GlideRecord("sys_user");
user.addEncodedQuery("sys_idIN" + usersNew);
user.setCategory('list');
user.query();
while(user.next()) {
var timeZone = user.getValue("time_zone");
if(JSUtil.nil(timeZone))
{
timeZone = GlideUser.getSysTimeZone();
}
timezoneMap[user.getValue("sys_id")] = timeZone;
this.timezoneMap[user.getValue("sys_id")] = timeZone;
}
}
return timezoneMap;
},
getUserTZ : function (userID){
var timeZoneMap = this.getUsersTZ([userID]);
return timeZoneMap[userID];
},
getScheduleFromUsersProfile : function(users, startDate, endDate) {
var userGR = new GlideRecord("sys_user");
userGR.addEncodedQuery("sys_idIN" + users);
userGR.setCategory('list');
userGR.query();
var userScheduleMap = {};
while(userGR.next()) {
if(!userGR.getValue("schedule")) {
if(new CSMUtil().isDebugOn())
gs.log("getScheduleFromUsersProfile : No schedule defined for " + userGR.getValue("name"));
userScheduleMap[userGR.getValue("sys_id")] = null;
}
else{
var workScheduleObj = {};
var start_date = new GlideDateTime(startDate);
workScheduleObj.from_date = start_date;
var end_date = new GlideDateTime(endDate);
workScheduleObj.to_date = end_date;
workScheduleObj.work_schedule = userGR.getValue("schedule");
userScheduleMap[userGR.getValue("sys_id")] = workScheduleObj;
}
}
return userScheduleMap;
},
getScheduleFromUserProfile : function(user, startDate, endDate) {
var scheduleMap = this.getScheduleFromUsersProfile([user], startDate, endDate);
return scheduleMap[user];
},
_getWorkScheduleQuery : function (startDate, endDate) {
var query = "from_date<=" + startDate + "^to_date>=" + startDate;
query += "^NQfrom_date<=" + endDate + "^to_date>=" + endDate;
query += "^NQfrom_date>=" + startDate + "^to_date<=" + endDate;
return query;
},
//existing function will load user profile
getWorkSchedulesFromDBForUsers : function(users, startDate, endDate) {
return this.getWorkSchedulesFromDBForAgents(users, startDate, endDate, true);
},
getWorkSchedulesFromDBForAgents : function(users, startDate, endDate, loadUserProfileSchedule) {
var shiftGR = new GlideRecord("agent_work_schedule");
var query = this._getWorkScheduleQuery(startDate, endDate);
shiftGR.addEncodedQuery(query);
shiftGR.addEncodedQuery("userIN" + users);
shiftGR.addEncodedQuery("type=0");
shiftGR.setCategory('list');
shiftGR.query();
var userSchedulesMap = {};
var timezoneMap = this.getUsersTZ(users);
while(shiftGR.next()) {
if (JSUtil.nil(shiftGR.getValue("work_schedule"))) {
gs.info("Record in agent_work_schedule table : user " + shiftGR.user + " does not have a value specified for work_schedule." );
continue;
}
var user = shiftGR.getValue("user");
var userTZ = timezoneMap[user];
var time_zone = Packages.java.util.TimeZone.getTimeZone(userTZ);
var workScheduleObj = {};
var start_date = new GlideDateTime();
start_date.setTZ(time_zone);
start_date.setDisplayValue(shiftGR.getValue("from_date"));
if(start_date.getNumericValue() < startDate.getNumericValue())
start_date = startDate;
workScheduleObj.from_date = start_date;
var end_date = new GlideDateTime();
end_date.setTZ(time_zone);
end_date.setDisplayValue(shiftGR.getValue("to_date"));
var old_end_date = new GlideDateTime();
old_end_date.setTZ(time_zone);
old_end_date.setDisplayValue(shiftGR.getValue("to_date"));
end_date.addDaysUTC(1);
if (end_date.getNumericValue() < old_end_date.getNumericValue())
end_date = old_end_date;
if(end_date.getNumericValue() > endDate.getNumericValue())
end_date = endDate;
workScheduleObj.to_date = end_date;
workScheduleObj.work_schedule = shiftGR.getValue("work_schedule");
var schedules = [];
if(userSchedulesMap.hasOwnProperty(user))
schedules = userSchedulesMap[user];
schedules.push(workScheduleObj);
userSchedulesMap[user] = schedules;
}
if(loadUserProfileSchedule){
var noWorkSchedulesUsers = [];
for(var i = 0;i < users.length; i++) {
var user = users[i];
if(!userSchedulesMap[user])
noWorkSchedulesUsers.push(user);
}
if(noWorkSchedulesUsers.length > 0){
var userProfileScheduleMap = this.getScheduleFromUsersProfile(noWorkSchedulesUsers, startDate, endDate);
for(var i = 0;i < noWorkSchedulesUsers.length; i++) {
var schedules = [];
if(userProfileScheduleMap[noWorkSchedulesUsers[i]]!=null)
schedules.push(userProfileScheduleMap[noWorkSchedulesUsers[i]]);
userSchedulesMap[noWorkSchedulesUsers[i]] = schedules;
}
}
this._verifyScheduleExistsForAllDaysAndFill(userSchedulesMap, startDate, endDate, userProfileScheduleMap, users, timezoneMap);
}
return userSchedulesMap;
},
getWorkSchedulesFromDB : function(user, startDate, endDate) {
if(new CSMUtil().isDebugOn())
gs.log("getWorkSchedulesFromDB startDate:" + startDate + " endDate:" + endDate + " user=" + user);
var userSchdedulesMap = this.getWorkSchedulesFromDBForUsers([user], startDate, endDate);
return userSchdedulesMap[user];
},
getDurationFromTimeMap : function(timeMap, startDate, endDate){
if (timeMap.isEmpty()) {
return new GlideDuration(0);
}
var timeSpent = 0;
var startTime = new GlideScheduleDateTime(startDate).getMS();
var endTime = new GlideScheduleDateTime(endDate).getMS();
while (timeMap.hasNext()) {
var span = timeMap.next();
if (endTime < span.getStart().getMS())
break; // all done
if (startTime < span.getStart().getMS())
startTime = span.getStart().getMS(); // Current start time is BEFORE the next span's start time - move it up
if (startTime < span.getEnd().getMS()) {
// We are within this span, update time spent in this span
if (span.getEnd().getMS() <= endTime)
timeSpent += (span.getEnd().getMS() - startTime);
else {
timeSpent += (endTime - startTime);
break;
}
startTime = span.getEnd().getMS();
}
}
return new GlideDuration(timeSpent);
},
getDuration : function (user, startDate, endDate) {
var userDurationMap = this.getDurationForUsers([user], startDate, endDate);
return userDurationMap[user];
},
getDurationForUsers : function (users, startDate, endDate) {
var userDurationMap = {};
var userTimeMap = this.getAvailabilityMapForUsers(users, startDate, endDate);
for(var i=0;i<users.length;i++) {
var user = users[i];
var timeMap = userTimeMap[user];
if(timeMap)
{
var duration = this.getDurationFromTimeMap(timeMap, startDate, endDate);
userDurationMap[user] = duration;
}
else
userDurationMap[user] = null;
}
return userDurationMap;
},
getAvailabilityMapForUsers : function(users, startDate, endDate) {
var userTZMap = this.getUsersTZ(users);
var userWorkSchedules = this.getWorkSchedulesFromDBForUsers(users, startDate, endDate);
var userTimeOffs = this.getTimeOffSpansForUsers(users, startDate, endDate);
var userAvailabilityMap = {};
var scheduleCache = {};
for(var i=0;i<users.length;i++) {
var user = users[i];
var workSchedules = userWorkSchedules[user];
var timeOffSpans = userTimeOffs[user];
var userTZ = userTZMap[user];
if(workSchedules.length == 0) {
if(new CSMUtil().isDebugOn())
gs.log("getDuration no work schedules");
userAvailabilityMap[user] = null; //Caller should should check for the null
}
else {
var timeMap = new GlideScheduleTimeMap();
for(var j = 0; j < workSchedules.length; j++){
var workSchedule = workSchedules[j];
var schedule = new GlideSchedule(workSchedule.work_schedule);
schedule.setTimeZone(userTZ);
var schedTimeMap = schedule.getTimeMap(workSchedule.from_date, workSchedule.to_date);
while(schedTimeMap.hasNext())
timeMap.addInclude(schedTimeMap.next());
}
for(var k = 0; k < timeOffSpans.length; k++){
var timeOffObj = timeOffSpans[k];
if(timeOffObj.show_as == "busy")
timeMap.addExclude(timeOffObj.span);
}
timeMap.buildMap(userTZ);
userAvailabilityMap[user] = timeMap;
}
}
return userAvailabilityMap;
},
getAvailabilityMap : function(user, startDate, endDate) {
var availabilityMap = this.getAvailabilityMapForUsers([user], startDate, endDate);
return availabilityMap[user];
},
getWorkSchedule : function(user, startDate, endDate) {
if(new CSMUtil().isDebugOn())
gs.log("getWOrkSchedule: " + startDate + " " + endDate);
var workScheduleTimeMap = this.getWorkScheduleForUsers([user], startDate, endDate);
return workScheduleTimeMap[user];
},
//new function by dispatch work space will not load user profile schedule
getWorkShiftForUsers : function (users, startDate, endDate) {
return this.getWorkScheduleForAgents(users, startDate, endDate, false);
},
//existing function will load user profile schedule
getWorkScheduleForUsers : function (users, startDate, endDate) {
return this.getWorkScheduleForAgents(users, startDate, endDate, true);
},
getWorkScheduleForAgents : function (users, startDate, endDate, loadUserProfileSchedule) {
var workSchedulesMap = this.getWorkSchedulesFromDBForAgents(users, startDate, endDate, loadUserProfileSchedule);
var workScheduleTimeMap = {};
var timezoneMap = this.getUsersTZ(users);
if (this.workScheduleTimeMapCache == null) {
this.workScheduleTimeMapCache = {};
}
for(var i = 0; i < users.length ; i++) {
var user = users[i];
var workSchedules = workSchedulesMap[user];
if(workSchedules.length == 0) {
if(new CSMUtil().isDebugOn())
gs.log("getWorkScheduleForUsers no work schedules for user " + user);
workScheduleTimeMap[user] = null; //Caller should should check for the null
}
else {
var timeMap = new GlideScheduleTimeMap();
var userTZ = timezoneMap[user];
for(var j = 0; j < workSchedules.length; j++){
var workSchedule = workSchedules[j];
//Attempt to retrieve cached results
var localSchedule = workSchedule.work_schedule;
var localStart = workSchedule.from_date;
var localEnd = workSchedule.to_date;
var localTZ = userTZ;
var key = localSchedule + "_" + localStart + "_" + localEnd + "_" + localTZ;
var localCache = this.workScheduleTimeMapCache[key];
if (localCache) {
gs.info('AgentScheduleUtil: getWorkScheduleForAgents retrieved cached result for ' + key);
for (var t = 0; t < localCache.length; t ++) {
var localSpan = new GlideScheduleDateTimeSpan(localCache[t].start, localCache[t].end);
timeMap.addInclude(localSpan);
}
} else {
var schedule = new GlideSchedule(localSchedule);
schedule.setTimeZone(userTZ);
var schedTimeMap = schedule.getTimeMap(workSchedule.from_date, workSchedule.to_date);
var schedTimeMapList = [];
while (schedTimeMap.hasNext()){
var localschedTimeMap = schedTimeMap.next();
var localschedTimeMapStart = localschedTimeMap.getStart();
var localschedTimeMapEnd = localschedTimeMap.getEnd();
var localObj = {};
localObj.start = localschedTimeMapStart;
localObj.end = localschedTimeMapEnd;
schedTimeMapList.push(localObj);
timeMap.addInclude(localschedTimeMap);
}
this.workScheduleTimeMapCache[key] = schedTimeMapList;
}
}
timeMap.buildMap(userTZ);
workScheduleTimeMap[user] = timeMap;
}
}
return workScheduleTimeMap;
},
getTimeOffAsScheduleSpans : function (user, startDate, endDate) {
var retTimeOffSpans = [];
var schedSpans = this.getTimeOffSpans(user, startDate, endDate);
var userTZ = this.getUserTZ(user);
for(var i=0;i<schedSpans.length;i++){
if(schedSpans[i].show_as == "busy") {
var schedDateTimeSpan = schedSpans[i].span;
retTimeOffSpans.push(schedDateTimeSpan);
}
}
return retTimeOffSpans;
},
getTimeOffSpansForUsers : function (users, startDate, endDate, eventType, configId, displayField) {
var userSpansMap = {};
var scheduleUserMap = {};
var agentEventGR = this.getAgentsPersonalSchedule(users);
var userTZMap = this.getUsersTZ(users);
if(agentEventGR){
var personalSchedules = [];
while(agentEventGR.next()){
var user = agentEventGR.getValue("user");
var personal_schedule = agentEventGR.getValue("personal_schedule");
personalSchedules.push(personal_schedule);
scheduleUserMap[personal_schedule] = user;
userSpansMap[user] = [];
}
// handling display value on calendar
if (gs.nil(displayField)) {
var eventConfigId = configId; // getting display field value from the configId passed to the context
if (gs.nil(configId))
eventConfigId = "c34d27e37fa32200c57212f44efa9162"; // getting display field value from old OOB event config (only applies to customers before Madrid)
var eventConfigGR = new GlideRecord("agent_schedule_task_config");
eventConfigGR.addQuery("sys_id",eventConfigId);
eventConfigGR.addActiveQuery();
eventConfigGR.setCategory('list');
eventConfigGR.query();
if (eventConfigGR.isValidRecord() && eventConfigGR.getRowCount() > 0)
displayField = eventConfigGR.getValue("display_field");
else
displayField = "name"; // if no valid event config found, hardcoding it to "name" field of the event
}
var scheduleEntryGR = this.getPersonalEventsGR(personalSchedules, startDate, endDate, this.iso8601, eventType);
while(scheduleEntryGR.next()){
var schedule = scheduleEntryGR.getValue("schedule");
var user = scheduleUserMap[schedule];
var userTZ = userTZMap[user];
var name = scheduleEntryGR.getDisplayValue("name");
var text = scheduleEntryGR.getDisplayValue(displayField);
var sys_id = scheduleEntryGR.getUniqueValue();
var start_date = new GlideScheduleDateTime(startDate);
var end_date = new GlideScheduleDateTime(endDate);
var schedDateTimeSpan = new GlideScheduleTimeSpan(scheduleEntryGR, userTZ);
var schedSpans = schedDateTimeSpan.getSpans(start_date, end_date);
schedSpans = j2js(schedSpans);
for(var i=0;i<schedSpans.length;i++){
var timeOffObj = {};
timeOffObj.name = name;
timeOffObj.sys_id = sys_id;
timeOffObj.event_id = sys_id + "_" + i;
timeOffObj.text = text;
timeOffObj.timezone = userTZ;
timeOffObj.start_date = schedSpans[i].getStart();
timeOffObj.end_date = schedSpans[i].getEnd();
timeOffObj.origin_start_date = schedSpans[i].getActualStart();
timeOffObj.origin_end_date = schedSpans[i].getActualEnd();
timeOffObj.show_as = scheduleEntryGR.getValue("show_as");
timeOffObj.span = schedSpans[i];
userSpansMap[user].push(timeOffObj);
}
}
}
return userSpansMap;
},
// Only pass the first four params if fetching all active event types
// personalSchedules: personal schdule id concatenated string
// startDate, endDate : GlideDateTime object
// iso8601 : boolean , eventType : event type string, optional
getPersonalEventsGR: function(personalSchedules, startDate, endDate, iso8601, eventType){
var scheduleEntryGR = new GlideRecord("cmn_schedule_span");
if (iso8601) {
// Handle user's schedule with floating timezone, get the start/end date in current logged in user's timezone
var sDate = this._convertToISOFormat(startDate.getDisplayValueInternal());
var eDate = this._convertToISOFormat(endDate.getDisplayValueInternal());
// Handle user's schedule with specified timezone, get the start/end date in UTC timezone
var sDateUTC = this._convertToISOFormat(startDate.getValue());
var eDateUTC = this._convertToISOFormat(endDate.getValue());
var minStartDate = sDate < sDateUTC ? sDate : sDateUTC;
var maxEndDate = eDate > eDateUTC ? eDate : eDateUTC;
var case1Str = "scheduleIN"+personalSchedules+"^repeat_type=^end_date_time>"+minStartDate+"^start_date_time<"+maxEndDate;
var case2Str = "^NQscheduleIN"+personalSchedules+"^repeat_type!=^repeat_until>"+(minStartDate.substr(0,8)-1)+"^start_date_time<"+maxEndDate;
var case3Str = "^NQscheduleIN"+personalSchedules+"^repeat_type!=^repeat_until=0^start_date_time<"+maxEndDate;
scheduleEntryGR.addEncodedQuery(case1Str+case2Str+case3Str);
} else
scheduleEntryGR.addQuery("schedule","IN",personalSchedules);
// handling event type filter
if (typeof eventType != "undefined") { // event type param value passed to the method context; if not passed to the method context - show all events
if (eventType == null || eventType == "null")
scheduleEntryGR.addQuery("type",""); // show events with type "none"
else if (!gs.nil(eventType))
scheduleEntryGR.addQuery("type",eventType); // show events where type != "none"
}
scheduleEntryGR.addActiveQuery();
scheduleEntryGR.setCategory("list");
if(new CSMUtil().isDebugOn())
gs.log("AgentScheduleUtil:::getPersonalEventsGR: scheduleEntryGR.getEncodedQuery() is " + scheduleEntryGR.getEncodedQuery());
scheduleEntryGR.query();
return scheduleEntryGR;
},
// get users' personal events within the time slot
// agentListStr : agent ids concatenated string
// startDate, endDate : unix time stamp as millisecs
getEventSpan: function(agentListStr, startDate, endDate) {
var personalSchedules = [];
var userMap = {};
var userTZMap = this.getUsersTZ(agentListStr);
// get personal event ids by user ids
var agentEventGR = new GlideRecord("agent_events");
agentEventGR.addEncodedQuery("userIN" + agentListStr);
agentEventGR.query();
while(agentEventGR.next()){
var personal_schedule = agentEventGR.getValue("personal_schedule");
personalSchedules.push(personal_schedule);
userMap[personal_schedule] = {"user_id" : agentEventGR.getValue("user")};
}
// convert time from unix timestamp to GlideDateTime
var startDateGdt = new GlideDateTime();
startDateGdt.setNumericValue(startDate);
var endDateGdt = new GlideDateTime();
endDateGdt.setNumericValue(endDate);
return this.getEventScheduleSpans(personalSchedules.join(","), userMap, userTZMap,startDateGdt, endDateGdt);
},
getEventScheduleSpans: function(personalSchedules, userMap, userTZMap, startDateGdt, endDateGdt) {
var scheduleEntryGR = this.getPersonalEventsGR(personalSchedules, startDateGdt, endDateGdt, true);
var res = [];
while(scheduleEntryGR.next()){
var name = scheduleEntryGR.getDisplayValue("name");
var user = userMap[scheduleEntryGR.getValue("schedule")]["user_id"];
var sys_id = scheduleEntryGR.getValue("sys_id");
// fetch the repeated events within the given time slot
var startScheduleDateTime = new GlideScheduleDateTime(startDateGdt);
var endScheduleDateTime = new GlideScheduleDateTime(endDateGdt);
var schedDateTimeSpan = new GlideScheduleTimeSpan(scheduleEntryGR, userTZMap[user]);
var schedSpans = schedDateTimeSpan.getSpans(startScheduleDateTime, endScheduleDateTime);
schedSpans = j2js(schedSpans);
// split the repeated event into multi simple events
for(var i=0;i<schedSpans.length;i++){
res.push({
"id" : sys_id,
"name": name,
"user": user,
"start_time": schedSpans[i].getStart().getGlideDateTime().getValue(),
"end_time": schedSpans[i].getEnd().getGlideDateTime().getValue()
});
}
}
return res;
},
getTimeOffSpans : function (user, startDate, endDate) {
var timeOffSpanMap = this.getTimeOffSpansForUsers([user], startDate, endDate);
return timeOffSpanMap[user];
},
getAgentsPersonalSchedule : function(users){
var agentEventGR = "";
var userScheduleMap = {};
if(users){
agentEventGR = new GlideRecord("agent_events");
agentEventGR.addEncodedQuery("userIN"+users);
agentEventGR.setCategory("list");
agentEventGR.query();
}
return agentEventGR;
},
getAgentPersonalSchedule : function(user){
return this.getAgentsPersonalSchedule([user]);
},
getCurrentUserScheduleName : function(user){
var schedules = this.getUserScheduleNames([user]);
if(schedules.hasOwnProperty(user)){
return schedules[user];
}
},
getUserScheduleNames : function(users){
var gr = new GlideRecord("agent_work_schedule");
var now = new GlideDateTime();
gr.addEncodedQuery("userIN" + users);
gr.addQuery("from_date", "<=", now);
gr.addQuery("to_date", ">=", now);
gr.setCategory("list");
gr.query();
var userSchedules = {};
while (gr.next()){
userSchedules[gr.getValue("user")] = gr.work_schedule.getDisplayValue();
}
return userSchedules;
},
createPersonalSchedule : function(user){
var personalScheduleID = "";
if (user) {
var userGR = new GlideRecord("sys_user");
userGR.addQuery('sys_id', user);
userGR.setCategory('list');
userGR.query();
if (userGR.next()) {
var personalScheduleGR = new GlideRecord('cmn_schedule');
personalScheduleGR.initialize();
personalScheduleGR.setValue('name', userGR.getValue('name') + " Personal Schedule");
if(userGR.getValue('time_zone'))
personalScheduleGR.setValue('time_zone',userGR.getValue('time_zone'));
personalScheduleID = personalScheduleGR.insert();
if(personalScheduleID)
this.createPersonalScheduleConfig(user, personalScheduleID);
}
}
return personalScheduleID;
},
createPersonalScheduleConfig : function (user, personalScheduleID) {
var agentPersonalScheduleConfigID = "";
if (user && personalScheduleID) {
var agentEventGR = new GlideRecord('agent_events');
agentEventGR.initialize();
agentEventGR.setValue('user', user);
agentEventGR.setValue('personal_schedule', personalScheduleID);
agentPersonalScheduleConfigID = agentEventGR.insert();
}
return agentPersonalScheduleConfigID;
},
getloggedinAgentConfig:function(){
var currentUserConfig = "";
var agentConfigRecord = new GlideRecord("agent_schedule_user_pref");
agentConfigRecord.addQuery("user",gs.getUserID());
agentConfigRecord.setCategory('list');
agentConfigRecord.query();
if(agentConfigRecord.next()){
currentUserConfig = agentConfigRecord.getValue("sys_id");
}
return currentUserConfig;
},
isReporteeEvent:function(gr){
var answer = false;
if(JSUtil.notNil(gr)){
var personalSchedule = gr.getValue('schedule');
if(personalSchedule){
var agentEvents = new GlideRecord('agent_events');
agentEvents.addQuery('personal_schedule',personalSchedule);
agentEvents.setLimit(1);
agentEvents.query();
if(agentEvents.next()){
var user = agentEvents.getValue('user');
var manager = gs.getUserID();
var memGR = new GlideRecord('sys_user_grmember');
memGR.addQuery("group.manager", manager);
memGR.addQuery("user",user);
memGR.addActiveQuery();
memGR.setLimit(1);
memGR.query();
if(memGR.hasNext()){
answer = true;
}
}
}
}
return answer;
},
getScheduleEventsForUser : function (user, startDate, endDate) {
var userSpansArr = [];
var personalSchedule = new global.FSMMobileUtil().getUserSchedule();
var userTZMap = this.getUsersTZ(user);
if(personalSchedule){
var startDateTime = new GlideDateTime(startDate);
var endDateTime = new GlideDateTime(endDate);
var scheduleEntryGR = this.getPersonalEventsGR(personalSchedule, startDateTime, endDateTime, this.iso8601);
while(scheduleEntryGR.next()){
var schedule = scheduleEntryGR.getValue("schedule");
var userTZ = userTZMap[user];
var name = scheduleEntryGR.getDisplayValue("name");
var sys_id = scheduleEntryGR.getUniqueValue();
var start_date = new GlideScheduleDateTime(startDate);
var end_date = new GlideScheduleDateTime(endDate);
var schedDateTimeSpan = new GlideScheduleTimeSpan(scheduleEntryGR, userTZ);
var schedSpans = schedDateTimeSpan.getSpans(start_date, end_date);
schedSpans = j2js(schedSpans);
for(var i=0;i<schedSpans.length;i++){
var timeOffObj = {};
timeOffObj.name = name;
timeOffObj.sys_id = sys_id;
timeOffObj.event_id = sys_id + "_" + i;
timeOffObj.timezone = userTZ;
timeOffObj.start_date = schedSpans[i].getStart();
timeOffObj.end_date = schedSpans[i].getEnd();
timeOffObj.event_inst_start_date = schedSpans[i].getActualStart();
timeOffObj.event_inst_end_date = schedSpans[i].getActualEnd();
timeOffObj.cmn_sched_span_start_date = scheduleEntryGR.start_date_time.getDisplayValue();
timeOffObj.cmn_sched_span_end_date = scheduleEntryGR.end_date_time.getDisplayValue();
timeOffObj.show_as = scheduleEntryGR.getValue("show_as");
timeOffObj.span = schedSpans[i];
timeOffObj.type = scheduleEntryGR.getValue("type");
timeOffObj.repeat_type = scheduleEntryGR.getValue("repeat_type");
timeOffObj.repeat_count = scheduleEntryGR.getValue("repeat_count");
timeOffObj.repeat_until = scheduleEntryGR.getValue("repeat_until");
userSpansArr.push(timeOffObj);
}
}
}
return userSpansArr;
},
_convertToISOFormat: function(dateVal) {
var dateTimeArray = dateVal.split(" ");
var dateISO = dateTimeArray[0].split("-").join("");
var timeISO = dateTimeArray[1].split(":").join("");
return dateISO + "T" + timeISO;
},
/*
* Method to check in userSchedulesMap, that for every user, there is schedule for all days given in the date range startDate to endDate and fill in the empty days with the schedule from sys_user table if there is any.
*. Logic for every user:
* Step 1: Prepare the filtered dates for which there is no schedule for the user.
* Step 2: Get the userProfile schedule if any for the user
* Step 3: Prepare scheduleObj for missing days and fill in the userSchedulesMap for the user.
*/
_verifyScheduleExistsForAllDaysAndFill: function(userSchedulesMap, startDate, endDate, userProfileScheduleMap, users, userTimezoneMap){
var dateSet = [];
var tempDate = new GlideDateTime(startDate);
var tempEndDate = new GlideDateTime(endDate);
while(tempDate<tempEndDate){ //Prepare a set of individual dates for which schedules ar requested.
dateSet.push(tempDate.getDate().toString());
tempDate.addSeconds(1*24*60*60);
}
for(var agent in userSchedulesMap){
var agentTZ = userTimezoneMap[agent];
var agent_time_zone = Packages.java.util.TimeZone.getTimeZone(agentTZ);
var agentSchedules = userSchedulesMap[agent];
var filteredDateSet = dateSet.filter(function(currDateStr){ //Filter and get dates not covered by schedules.
return !agentSchedules.some(function(scheduleObj){
var gdt = new GlideDateTime();
gdt.setTZ(agent_time_zone);
gdt.setDisplayValue(currDateStr);
var dateIsCovered = (
(scheduleObj.from_date.getDate() <= gdt.getDate()) &&
(scheduleObj.to_date.getDate() >= gdt.getDate())
);
return dateIsCovered;
});
});
var lookupProfileSchedule = (
!userProfileScheduleMap ||
!(agent in userProfileScheduleMap)
);
//Get agent's default schedule from user profile.
if(lookupProfileSchedule)
userProfileScheduleMap = this.getScheduleFromUsersProfile(users, startDate, endDate);
if(userProfileScheduleMap[agent]){
//prepare the scheduleObjs for the missing days and relpenish the userSchedulesMap
filteredDateSet.forEach(function(currDate){
var scheduleObj = {};
var gd = new GlideDate();
gd.setDisplayValue(currDate);
var from_date = new GlideDateTime();
from_date.setTZ(agent_time_zone);
from_date.setDisplayValue(gd.getDisplayValue());
scheduleObj.from_date = new GlideDateTime(from_date);
var to_date = new GlideDateTime();
to_date.setTZ(agent_time_zone);
gd.addDays(1);
to_date.setDisplayValue(gd.getDisplayValue());
scheduleObj.to_date = new GlideDateTime(to_date);
scheduleObj.work_schedule = userProfileScheduleMap[agent]["work_schedule"];
if(userSchedulesMap[agent] != null)
userSchedulesMap[agent].push(scheduleObj);
else
userSchedulesMap[agent] = [scheduleObj];
});
agentSchedules = userSchedulesMap[agent];
}
}
},
/*
* Method to get the work schedules for all the users passed in users array.
*. Logic:
* Step 1: getWorkScheduleForUsers
* Step 2: For each user prepare shiftBlocksArr containing the schedObj JSONs from the Java scheduleData.
*/
_getAgentScheduleBlocks: function(users, startDate, endDate){
var usersScheduleData = this.getWorkScheduleForUsers(users, startDate, endDate);
var userShiftBlocksMap = {};
var curTimeZone = GlideSession.get().getTimeZoneName();
var timezoneMap = this.getUsersTZ(users);
users.forEach(function(user){
var scheduleData = usersScheduleData[user];
var shiftBlocksArr = [];
while (!JSUtil.nil(scheduleData) && scheduleData.hasNext()) {
var schedObj = {};
var timeSpan = scheduleData.next();
var timezone = timezoneMap[user];
schedObj.start_date_usertz = new GlideDateTime(timeSpan.getStart().convertTimeZone(curTimeZone, timezone)); //Setting Date in String in user's timezone in JSON attribute
schedObj.end_date_usertz = new GlideDateTime(timeSpan.getEnd().convertTimeZone(curTimeZone, timezone));
schedObj.user = user;
schedObj.start_date = timeSpan.getStart().getGlideDateTime();
schedObj.end_date = timeSpan.getEnd().getGlideDateTime();
schedObj.start_time = timeSpan.getStart().getGlideDateTime();
schedObj.end_time = timeSpan.getEnd().getGlideDateTime();
if (schedObj.end_date_usertz > schedObj.start_date_usertz)
shiftBlocksArr.push(schedObj);
}
if(shiftBlocksArr.length>0)
userShiftBlocksMap[user] = shiftBlocksArr;
});
return userShiftBlocksMap;
},
/*
* Method to prepare daily work start and for given shiftBlocks.
* Step 1: Sort the shiftBlocks by start date.
* Step 2: Reduce the multiple shift blocks for each day into GroupBy start_date_usertz.
*/
_prepareDailyWorkStartEnd: function(shiftBlocks){
if(shiftBlocks.length>0){
shiftBlocks.sort(function(schedObjA, schedObjB){
var startDtA_Num = schedObjA.start_date.getNumericValue();
var startDtB_Num = schedObjB.start_date.getNumericValue();
if(startDtA_Num == startDtB_Num){
var endDtA_Num = schedObjA.end_date.getNumericValue();
var endDtB_Num = schedObjB.end_date.getNumericValue();
}
return (startDtA_Num!=startDtB_Num ? startDtA_Num-startDtB_Num : endDtA_Num-endDtB_Num);
});
var result = shiftBlocks.reduce(function(res,obj){
if(!(obj.start_date_usertz.getLocalDate() in res)){
var schedObj = obj;
res[obj.start_date_usertz.getLocalDate()]= schedObj;
} else{
var schedObj = obj;
res[obj.start_date_usertz.getLocalDate()]['end_date'] = schedObj.end_date;
res[obj.start_date_usertz.getLocalDate()]['end_time'] = schedObj.end_time;
res[obj.start_date_usertz.getLocalDate()]['end_date_usertz'] = schedObj.end_date_usertz;
}
return res;
},{});
}
return result;
},
_insertDownloadScheduleForUsers: function(userSysIdsArr, startDate, endDate){
var userScheduleBlocksMap = this._getAgentScheduleBlocks(userSysIdsArr, startDate, endDate);
for (var user in userScheduleBlocksMap){
var scheduleBlocksDateMap = this._prepareDailyWorkStartEnd(userScheduleBlocksMap[user]);
for (var dateKey in scheduleBlocksDateMap){
var rowJSON = scheduleBlocksDateMap[dateKey];
this._insertInDownloadSchedule(rowJSON);
}
}
},
_insertInDownloadSchedule: function(rowJSON){
var gr = new GlideRecord("agent_daily_schedule");
gr.setValue('user',rowJSON.user);
gr.setValue('start',rowJSON.start_date);
gr.setValue('end',rowJSON.end_date);
gr.setWorkflow(false);
gr.insert();
},
purgePastAndFutureAgentScheduleBlocks: function(roles, oldRecordsCreationTime){
var gr= new GlideRecord("agent_daily_schedule");
gr.addEncodedQuery("user.roles=" + roles + "^sys_created_on<" + oldRecordsCreationTime + "^ORuser.active=false");
gr.setWorkflow(false);
gr.deleteMultiple();
},
insertAgentScheduleBlocks: function(numberOfDaysData, roles){
var startDate = new GlideDateTime();
startDate.setDisplayValue(startDate.getDate() + "+00:00:00");
var endDate = new GlideDateTime();
endDate.addSeconds(numberOfDaysData*24*60*60);
endDate.setDisplayValue(endDate.getDate() + "+00:00:00");
// Query wm_agent role users which have the scheduled_download user preference enabled
var userPreferenceName = "glide.sg.offline.scheduled_download.enabled";
var primaryTableField = 'sys_id';
var joinTable = 'sys_user_preference';
var joinTableField = 'user';
var joinTableQuery = 'name=' + userPreferenceName + '^value=true';
var userGr = new GlideRecord("sys_user");
userGr.addActiveQuery();
userGr.addEncodedQuery('active=1^roles=' + roles + '^SUBQUERY' + primaryTableField + ',' + joinTableField + ',' + joinTable + '^' + joinTableQuery + '^ENDSUBQUERY');
userGr.setCategory('list');
userGr.query();
var userGrArr = [];
var userGrArrSizeLimit = 1000;
while(userGr.next()){
var agentSysId = userGr.getValue("sys_id");
userGrArr.push(agentSysId);
if(userGrArr.length==userGrArrSizeLimit){
this._insertDownloadScheduleForUsers(userGrArr,startDate,endDate);
userGrArr = [];
}
}
if(userGrArr.length>0) //insert last batch of users if there are some users left
this._insertDownloadScheduleForUsers(userGrArr,startDate,endDate);
},
type: 'AgentScheduleUtil'
};
Sys ID
e67a5510c37312001c845cb981d3aee5