public void ClonePropertiesTo(SlaTrigger clone) { foreach (System.Reflection.PropertyInfo sourcePropertyInfo in this.GetType().GetProperties()) { if (sourcePropertyInfo.CanWrite && sourcePropertyInfo.Name.ToLower() != "basecollection" && sourcePropertyInfo.PropertyType != typeof(DateTime) && sourcePropertyInfo.PropertyType != typeof(DateTime?)) { System.Reflection.PropertyInfo destPropertyInfo = clone.GetType().GetProperty(sourcePropertyInfo.Name); destPropertyInfo.SetValue( clone, sourcePropertyInfo.GetValue(this, null), null); } } //DateTime properties are special it needs to be the UTC value. The DateTime (and DateTime?) properties always have a UTC version foreach (System.Reflection.PropertyInfo sourcePropertyInfo in this.GetType().GetProperties()) { if (sourcePropertyInfo.CanRead && sourcePropertyInfo.Name.Substring(sourcePropertyInfo.Name.Length - 3).ToLower() == "utc" && (sourcePropertyInfo.PropertyType == typeof(DateTime) || sourcePropertyInfo.PropertyType == typeof(DateTime?))) { System.Reflection.PropertyInfo destPropertyInfo = clone.GetType().GetProperty(sourcePropertyInfo.Name.Substring(0, sourcePropertyInfo.Name.Length - 3)); destPropertyInfo.SetValue( clone, sourcePropertyInfo.GetValue(this, null), null); } } }
public static TimeSpan CalculatePausedTime(LoginUser loginUser, int organizationId, int triggerId, DateTime pausedOn, DateTime resumedOn, Logs logs = null) { SlaTrigger slaTrigger = SlaTriggers.GetSlaTrigger(loginUser, triggerId); Organization organization = Organizations.GetOrganization(loginUser, organizationId); SlaTickets.BusinessHours businessHours = new SlaTickets.BusinessHours() { DayStartUtc = organization.BusinessDayStartUtc, DayEndUtc = organization.BusinessDayEndUtc, BusinessDays = organization.BusinessDays }; //Check if we should use SLA's business hours instead of Account's if (!slaTrigger.UseBusinessHours && slaTrigger.DayStartUtc.HasValue && slaTrigger.DayEndUtc.HasValue) { businessHours.DayStartUtc = slaTrigger.DayStartUtc.Value; businessHours.DayEndUtc = slaTrigger.DayEndUtc.Value; businessHours.BusinessDays = slaTrigger.Weekdays; } List <DateTime> daysToPause = SlaTriggers.GetSpecificDaysToPause(slaTrigger.SlaTriggerID); bool pauseOnHoliday = slaTrigger.PauseOnHoliday; CalendarEvents holidays = new CalendarEvents(loginUser); if (pauseOnHoliday) { holidays.LoadHolidays(organization.OrganizationID); } return(CalculatePausedTime(loginUser, organization, slaTrigger, pausedOn, resumedOn, businessHours, daysToPause, holidays, logs)); }
public static TimeSpan CalculatePausedTime(int ticketId, Organization organization, BusinessHours businessHours, SlaTrigger slaTrigger, List <DateTime> daysToPause, CalendarEvents holidays, LoginUser loginUser, Dictionary <int, double> businessPausedTimes, Logs logs = null, bool overwritePrevious = false, DateTime?startOn = null) { TimeSpan totalPausedTime = new TimeSpan(); SlaPausedTimes slaPausedTimes = new SlaPausedTimes(loginUser); slaPausedTimes.LoadByTicketId(ticketId, startOn); foreach (SlaPausedTime slaPausedTime in slaPausedTimes) { bool hasBeenCalculated = slaPausedTime.BusinessPausedTime != null; if (!hasBeenCalculated || (hasBeenCalculated && overwritePrevious)) { TimeSpan rangePausedTime = SlaPausedTimes.CalculatePausedTime(loginUser, organization, slaTrigger, slaPausedTime.PausedOnUtc, (DateTime)slaPausedTime.ResumedOnUtc, businessHours, daysToPause, holidays, logs); totalPausedTime = totalPausedTime.Add(rangePausedTime); //return the results to stored them in the db. businessPausedTimes.Add(slaPausedTime.Id, rangePausedTime.TotalSeconds); } else if (hasBeenCalculated && !overwritePrevious) { TimeSpan previouslyCalculatedPausedTime = TimeSpan.FromSeconds((int)slaPausedTime.BusinessPausedTime); totalPausedTime = totalPausedTime.Add(previouslyCalculatedPausedTime); } } return(totalPausedTime); }
public static DateTime?CalculateSLA(DateTime DateCreated, BusinessHours businessHours, SlaTrigger slaTrigger, int minutes, TimeSpan pausedTimeSpan, List <DateTime> daysToPause, CalendarEvents holidays) { bool slaUseBusinessHours = slaTrigger.UseBusinessHours; DateTime?slaDayStart = businessHours.DayStartUtc; DateTime?slaDayEnd = businessHours.DayEndUtc; int slaBusinessDays = businessHours.BusinessDays; DateTime?ExpireDate = new DateTime(); int adjustedMinutes = 0; if ((slaUseBusinessHours && (slaDayStart == null || slaDayEnd == null || slaBusinessDays < 1)) || minutes < 1) { ExpireDate = null; } else { if ((slaUseBusinessHours && slaBusinessDays == 0) || (!slaUseBusinessHours && DateTime.Compare(slaDayStart.Value, slaDayEnd.Value) == 0 && slaBusinessDays == 127) || slaTrigger.NoBusinessHours) //127 means all days are selected. { ExpireDate = DateCreated.AddMinutes(minutes); } else { int startOfDayMinutes = slaDayStart.Value.Minute + (slaDayStart.Value.Hour * 60); int endOfDayMinutes = slaDayEnd.Value.Minute + (slaDayEnd.Value.Hour * 60); int currentMinuteInTheProcess = DateCreated.Minute + (DateCreated.Hour * 60); int minutesInOneDay = (24 * 60); //When converted the input to UTC the end time might be less than the start time. E.g. central 8 to 22, is stored as utc 14 to 4 if (businessHours.DayEndUtc.Hour < businessHours.DayStartUtc.Hour && businessHours.DayEndUtc.Day > businessHours.DayStartUtc.Day) { adjustedMinutes = slaDayStart.Value.Minute + slaDayStart.Value.Hour * 60; slaDayStart = slaDayStart.Value.AddMinutes(-adjustedMinutes); slaDayEnd = slaDayEnd.Value.AddMinutes(-adjustedMinutes); DateCreated = DateCreated.AddMinutes(-adjustedMinutes); startOfDayMinutes = slaDayStart.Value.Minute + (slaDayStart.Value.Hour * 60); endOfDayMinutes = slaDayEnd.Value.Minute + (slaDayEnd.Value.Hour * 60); currentMinuteInTheProcess = (DateCreated.Minute + (DateCreated.Hour * 60)); } //Make sure endOfDayMinutes is greater than startOfDayMinutes if (startOfDayMinutes >= endOfDayMinutes) { //Add 1 day worth of minutes endOfDayMinutes = endOfDayMinutes + minutesInOneDay; } int minutesInBusinessDay = endOfDayMinutes - startOfDayMinutes; //Make sure the start time falls within business hours if (currentMinuteInTheProcess > endOfDayMinutes) { //Reset the time to start of bussiness day AND add 1 day DateCreated = DateCreated.Date.AddDays(1).Add(slaDayStart.Value.TimeOfDay); } else if (currentMinuteInTheProcess < startOfDayMinutes) { DateCreated = DateCreated.Date.Add(slaDayStart.Value.TimeOfDay); } //Repeat until we find the first business day, non-pause day, non-holiday while (!IsValidDay(DateCreated, slaBusinessDays, daysToPause, holidays)) { DateCreated = DateCreated.AddDays(1); //If this happened then we need to set it with the start of day hour DateCreated = new DateTime(DateCreated.Year, DateCreated.Month, DateCreated.Day, slaDayStart.Value.Hour, slaDayStart.Value.Minute, 0); } //DateCreated now contains a valid date to start SLA with business days currentMinuteInTheProcess = DateCreated.Minute + (DateCreated.Hour * 60); int slaDays = (minutes / 60) / 24; int slaHours = (minutes - (slaDays * 24 * 60)) / 60; int slaMinutes = minutes - (slaDays * 24 * 60) - (slaHours * 60); ExpireDate = DateCreated; //1) process days while (slaDays > 0) { ExpireDate = ExpireDate.Value.AddDays(1); if (IsValidDay(ExpireDate.Value, slaBusinessDays, daysToPause, holidays)) { slaDays--; } } //2) process hours while (slaHours > 0) { ExpireDate = ExpireDate.Value.AddHours(1); if (ExpireDate.Value.Hour > slaDayEnd.Value.Hour || (ExpireDate.Value.Hour == slaDayEnd.Value.Hour && ExpireDate.Value.Minute > slaDayEnd.Value.Minute)) { ExpireDate = GetNextBusinessDay(ExpireDate.Value, slaBusinessDays); int minuteOffset = ExpireDate.Value.Minute - slaDayEnd.Value.Minute; ExpireDate = new DateTime(ExpireDate.Value.Year, ExpireDate.Value.Month, ExpireDate.Value.Day, slaDayStart.Value.Hour, slaDayStart.Value.Minute, 0); ExpireDate = ExpireDate.Value.AddMinutes(minuteOffset); } if (IsValidDay(ExpireDate.Value, slaBusinessDays, daysToPause, holidays)) { slaHours--; } else { ExpireDate = GetNextBusinessDay(ExpireDate.Value, slaBusinessDays); ExpireDate = ExpireDate.Value.AddHours(-1); } } //3) process minutes while (slaMinutes > 0) { ExpireDate = ExpireDate.Value.AddMinutes(1); if (ExpireDate.Value.Hour == slaDayEnd.Value.Hour && ExpireDate.Value.Minute > slaDayEnd.Value.Minute) { ExpireDate = GetNextBusinessDay(ExpireDate.Value, slaBusinessDays); ExpireDate = new DateTime(ExpireDate.Value.Year, ExpireDate.Value.Month, ExpireDate.Value.Day, slaDayStart.Value.Hour, slaDayStart.Value.Minute, 0); } if (IsValidDay(ExpireDate.Value, slaBusinessDays, daysToPause, holidays)) { slaMinutes--; } else { ExpireDate = GetNextBusinessDay(ExpireDate.Value, slaBusinessDays); ExpireDate = ExpireDate.Value.AddMinutes(-1); } } } ExpireDate = AddPausedTime((DateTime)ExpireDate, pausedTimeSpan, slaBusinessDays, slaDayStart, slaDayEnd, slaUseBusinessHours); if (businessHours.DayEndUtc.Hour < businessHours.DayStartUtc.Hour && businessHours.DayEndUtc.Day > businessHours.DayStartUtc.Day) { ExpireDate = ExpireDate.Value.AddMinutes(adjustedMinutes); } //last check to make sure it didn't fall into a Holiday, if so move onto the next valid day while (!IsValidDay(ExpireDate.Value, slaBusinessDays, daysToPause, holidays)) { ExpireDate = GetNextBusinessDay(ExpireDate.Value, slaBusinessDays); } } return(ExpireDate); }
public SlaLevel Clone(string cloneName = null) { int cloneSlaLevelId = 0; LoginUser loginUser = Collection.LoginUser; SlaLevels slaLevels = new SlaLevels(loginUser); SlaLevel clone = slaLevels.AddNewSlaLevel(); clone.OrganizationID = OrganizationID; if (string.IsNullOrEmpty(cloneName)) { clone.Name = Name + " (Clone)"; } else { clone.Name = cloneName; } clone.Collection.Save(); cloneSlaLevelId = clone.SlaLevelID; string actionLog = string.Format("{0} cloned SLA Level {1} into {2}.", loginUser.GetUserFullName(), this.Name, clone.Name); ActionLogs.AddActionLog(loginUser, ActionLogType.Insert, ReferenceType.Sla, cloneSlaLevelId, actionLog); //Clone SLA's triggers SlaTriggers clonedSlaTriggers = new SlaTriggers(loginUser); SlaTriggers originalSlaTriggers = new SlaTriggers(loginUser); try { originalSlaTriggers.LoadBySlaLevel(OrganizationID, SlaLevelID); foreach (SlaTrigger slaTrigger in originalSlaTriggers.OrderBy(o => o.SlaTriggerID).ToList()) { SlaTrigger clonedSlaTrigger = clonedSlaTriggers.AddNewSlaTrigger(); slaTrigger.ClonePropertiesTo(clonedSlaTrigger); clonedSlaTrigger.SlaLevelID = cloneSlaLevelId; } clonedSlaTriggers.BulkSave(); } catch (Exception ex) { actionLog = string.Format("Failed to clone sla {0} Triggers into {1}.", this.SlaLevelID, clone.SlaLevelID); ActionLogs.AddActionLog(loginUser, ActionLogType.Insert, ReferenceType.Sla, cloneSlaLevelId, actionLog); ExceptionLogs.LogException(loginUser, ex, "Cloning Sla Triggers", "SlaLevels.Clone - Triggers"); } //Clone SLA's Pause on specific days try { clonedSlaTriggers = new SlaTriggers(loginUser); clonedSlaTriggers.LoadBySlaLevel(OrganizationID, cloneSlaLevelId); foreach (SlaTrigger slaTrigger in originalSlaTriggers) { SlaPausedDays clonedSlaPausedDays = new SlaPausedDays(loginUser); SlaPausedDays originalSlaPausedDays = new SlaPausedDays(loginUser); originalSlaPausedDays.LoadByTriggerID(slaTrigger.SlaTriggerID); int newTriggerId = clonedSlaTriggers.Where(p => p.TicketTypeID == slaTrigger.TicketTypeID && p.TicketSeverityID == slaTrigger.TicketSeverityID && p.SlaLevelID == cloneSlaLevelId).First().SlaTriggerID; foreach (SlaPausedDay slaPausedDay in originalSlaPausedDays.OrderBy(o => o.DateToPause).ToList()) { SlaPausedDay clonedSlaPausedDay = clonedSlaPausedDays.AddNewSlaPausedDay(); clonedSlaPausedDay.SlaTriggerId = newTriggerId; clonedSlaPausedDay.DateToPause = slaPausedDay.DateToPauseUtc; } clonedSlaPausedDays.BulkSave(); } } catch (Exception ex) { actionLog = string.Format("Failed to clone sla {0} DaysToPause into {1}.", this.SlaLevelID, clone.SlaLevelID); ActionLogs.AddActionLog(loginUser, ActionLogType.Insert, ReferenceType.Sla, cloneSlaLevelId, actionLog); ExceptionLogs.LogException(loginUser, ex, "Cloning Sla Pause On Days", "SlaLevels.Clone - Pause On Days"); } return(clone); }
public static TimeSpan CalculatePausedTime(LoginUser loginUser, Organization organization, SlaTrigger slaTrigger, DateTime pausedOn, DateTime resumedOn, SlaTickets.BusinessHours businessHours, List <DateTime> daysToPause, CalendarEvents holidays, Logs logs = null) { TimeSpan pausedTime = new TimeSpan(); int adjustedMinutes = 0; bool slaUseBusinessHours = slaTrigger.UseBusinessHours; int slaBusinessDays = businessHours.BusinessDays; DateTime?slaDayStart = businessHours.DayStartUtc; DateTime?slaDayEnd = businessHours.DayEndUtc; int startOfDayMinutes = slaDayStart.Value.Minute + (slaDayStart.Value.Hour * 60); int endOfDayMinutes = slaDayEnd.Value.Minute + (slaDayEnd.Value.Hour * 60); int minutesInOneDay = (24 * 60); //When converted the input to UTC the end time might be less than the start time. E.g. central 8 to 22, is stored as utc 14 to 4 if (businessHours.DayEndUtc.Hour < businessHours.DayStartUtc.Hour && businessHours.DayEndUtc.Day > businessHours.DayStartUtc.Day) { adjustedMinutes = slaDayStart.Value.Minute + slaDayStart.Value.Hour * 60; slaDayStart = slaDayStart.Value.AddMinutes(-adjustedMinutes); slaDayEnd = slaDayEnd.Value.AddMinutes(-adjustedMinutes); pausedOn = pausedOn.AddMinutes(-adjustedMinutes); resumedOn = resumedOn.AddMinutes(-adjustedMinutes); startOfDayMinutes = slaDayStart.Value.Minute + (slaDayStart.Value.Hour * 60); endOfDayMinutes = slaDayEnd.Value.Minute + (slaDayEnd.Value.Hour * 60); } if (pausedOn.Date == resumedOn.Date && (slaUseBusinessHours || (!slaUseBusinessHours && !slaTrigger.NoBusinessHours)) && //the last condition means it is using sla custom hours ( (!SlaTickets.IsValidDay(pausedOn, slaBusinessDays, daysToPause, holidays) && !SlaTickets.IsValidDay(resumedOn, slaBusinessDays, daysToPause, holidays)) || (pausedOn.TimeOfDay.TotalSeconds < slaDayStart.Value.TimeOfDay.TotalSeconds && resumedOn.TimeOfDay.TotalSeconds < slaDayStart.Value.TimeOfDay.TotalSeconds) || (pausedOn.TimeOfDay.TotalSeconds > slaDayEnd.Value.TimeOfDay.TotalSeconds && resumedOn.TimeOfDay.TotalSeconds > slaDayEnd.Value.TimeOfDay.TotalSeconds) ) ) { if (logs != null) { logs.WriteEvent("Paused and Resumed on the same non-valid day and time (non-business day, holiday, day to pause, outside business hours), so no time to add."); } } else if (pausedOn.Date == resumedOn.Date && (slaUseBusinessHours || (!slaUseBusinessHours && !slaTrigger.NoBusinessHours)) && //the last condition means it is using sla custom hours ( (SlaTickets.IsValidDay(pausedOn, slaBusinessDays, daysToPause, holidays) && SlaTickets.IsValidDay(resumedOn, slaBusinessDays, daysToPause, holidays)) && (pausedOn.TimeOfDay.TotalSeconds > slaDayStart.Value.TimeOfDay.TotalSeconds && pausedOn.TimeOfDay.TotalSeconds < slaDayEnd.Value.TimeOfDay.TotalSeconds) && (resumedOn.TimeOfDay.TotalSeconds > slaDayStart.Value.TimeOfDay.TotalSeconds && resumedOn.TimeOfDay.TotalSeconds < slaDayEnd.Value.TimeOfDay.TotalSeconds) ) ) { pausedTime = resumedOn - pausedOn; if (logs != null) { logs.WriteEvent("Paused and Resumed on the same valid day and time (business day, non-holiday, not day to pause, inside business hours), simple resumedon - pausedon."); } } else { if ((slaUseBusinessHours && slaBusinessDays == 0) || (!slaUseBusinessHours && DateTime.Compare(slaDayStart.Value, slaDayEnd.Value) == 0 && slaBusinessDays == 127) || //127 means all days are selected. slaTrigger.NoBusinessHours) { pausedTime = resumedOn - pausedOn; logs.WriteEvent("24/7, simple resumedon - pausedon."); } else { //Make sure endOfDayMinutes is greater than startOfDayMinutes if (startOfDayMinutes >= endOfDayMinutes) { //Add 1 day worth of minutes endOfDayMinutes = endOfDayMinutes + minutesInOneDay; } int minutesInBusinessDay = endOfDayMinutes - startOfDayMinutes; //Make sure the pausedon and resumedon are business days while (!SlaTickets.IsValidDay(pausedOn, slaBusinessDays, daysToPause, holidays)) { pausedOn = SlaTickets.GetNextBusinessDay(pausedOn, slaBusinessDays); } while (!SlaTickets.IsValidDay(resumedOn, slaBusinessDays, daysToPause, holidays)) { resumedOn = SlaTickets.GetNextBusinessDay(resumedOn, slaBusinessDays); } //If the pause spans to more than one (and same) days then loop, set a tempResumedOn to end of business days and moving the pausedOn to next business day start of day while (DateTime.Compare(pausedOn, resumedOn) < 0) { DateTime tempResumedOn = new DateTime(); if (DateTime.Compare(pausedOn.Date, resumedOn.Date) < 0) { tempResumedOn = new DateTime(pausedOn.Year, pausedOn.Month, pausedOn.Day, slaDayEnd.Value.Hour, slaDayEnd.Value.Minute, 0); } else if (DateTime.Compare(pausedOn.Date, resumedOn.Date) == 0) { tempResumedOn = resumedOn; } //...do the calculation int secondsPaused = 0; while (pausedOn.Date < tempResumedOn.Date) { int pausedOnSecond = (pausedOn.Minute + (pausedOn.Hour * 60)) * 60; if (pausedOnSecond < (startOfDayMinutes * 60) || pausedOnSecond > (endOfDayMinutes * 60)) { pausedOnSecond = startOfDayMinutes * 60; } secondsPaused = (endOfDayMinutes * 60) - pausedOnSecond; pausedTime = pausedTime.Add(TimeSpan.FromSeconds(secondsPaused)); pausedOn = SlaTickets.GetNextBusinessDay(pausedOn, slaBusinessDays); pausedOn = new DateTime(pausedOn.Year, pausedOn.Month, pausedOn.Day, slaDayStart.Value.Hour, slaDayStart.Value.Minute, 0); } //same day if (pausedOn.Date == tempResumedOn.Date && pausedOn.TimeOfDay < tempResumedOn.TimeOfDay) { int resumedOnMinute = tempResumedOn.Minute + (tempResumedOn.Hour * 60); int resumedOnSecond = resumedOnSecond = (resumedOnMinute * 60) + tempResumedOn.Second; if (resumedOnMinute < startOfDayMinutes) { resumedOnMinute = startOfDayMinutes; resumedOnSecond = resumedOnSecond = (resumedOnMinute * 60) + tempResumedOn.Second; } if (resumedOnMinute > endOfDayMinutes) { resumedOnMinute = endOfDayMinutes; resumedOnSecond = resumedOnSecond = (resumedOnMinute * 60) + tempResumedOn.Second; } if (resumedOnSecond < (startOfDayMinutes * 60)) { resumedOnSecond = (startOfDayMinutes * 60); } if (resumedOnSecond > (endOfDayMinutes * 60)) { resumedOnSecond = (endOfDayMinutes * 60); } secondsPaused = resumedOnSecond - ((((pausedOn.Hour * 60) + pausedOn.Minute) * 60) + pausedOn.Second); pausedTime = pausedTime.Add(TimeSpan.FromSeconds(secondsPaused)); } //get the next valid day to start pausedOn = SlaTickets.GetNextBusinessDay(pausedOn, slaBusinessDays); pausedOn = new DateTime(pausedOn.Year, pausedOn.Month, pausedOn.Day, slaDayStart.Value.Hour, slaDayStart.Value.Minute, 0); while (!SlaTickets.IsValidDay(pausedOn, slaBusinessDays, daysToPause, holidays)) { pausedOn = SlaTickets.GetNextBusinessDay(pausedOn, slaBusinessDays); pausedOn = new DateTime(pausedOn.Year, pausedOn.Month, pausedOn.Day, slaDayStart.Value.Hour, slaDayStart.Value.Minute, 0); } } } } return(pausedTime); }