/// <summary> /// Delete this shift /// </summary> /// <param name="shift">Shift</param> public void DeleteShift(Shift shift) { if (!Shifts.Contains(shift)) { return; } // can't be in use foreach (Shift inUseShift in Shifts) { foreach (Team team in Teams) { Rotation rotation = team.Rotation; foreach (TimePeriod period in rotation.GetPeriods()) { if (period.Equals(inUseShift)) { string msg = String.Format(WorkSchedule.GetMessage("shift.in.use"), shift.Name); throw new Exception(msg); } } } } Shifts.Remove(shift); }
/// <summary> /// Build a string representation of this rotation /// </summary> /// <returns>String</returns> public override string ToString() { string named = base.ToString(); string rd = WorkSchedule.GetMessage("rotation.duration"); string rda = WorkSchedule.GetMessage("rotation.days"); string rw = WorkSchedule.GetMessage("rotation.working"); string rper = WorkSchedule.GetMessage("rotation.periods"); string on = WorkSchedule.GetMessage("rotation.on"); string off = WorkSchedule.GetMessage("rotation.off"); string periodsString = ""; foreach (TimePeriod period in GetPeriods()) { if (periodsString.Length > 0) { periodsString += ", "; } string onOff = period.IsWorkingPeriod() ? on : off; periodsString += period.Name + " (" + onOff + ")"; } string text = named + "\n" + rper + ": [" + periodsString + "], " + rd + ": " + GetDuration() + ", " + rda + ": " + GetDuration().Days + ", " + rw + ": " + GetWorkingTime(); return(text); }
/// <summary> /// Print shift instances to the console /// </summary> /// <param name="start">Starting date</param> /// <param name="end">Ending date</param> public void PrintShiftInstances(LocalDate start, LocalDate end) { if (start.CompareTo(end) > 0) { string msg = String.Format(WorkSchedule.GetMessage("end.earlier.than.start"), start, end); throw new Exception(msg); } long days = TimePeriod.DeltaDays(start, end) + 1; LocalDate day = start; for (long i = 0; i < days; i++) { Console.WriteLine("[" + (i + 1) + "] " + GetMessage("Shifts.day") + ": " + day); List <ShiftInstance> instances = GetShiftInstancesForDay(day); if (instances.Count == 0) { Console.WriteLine(" " + GetMessage("Shifts.non.working")); } else { int count = 1; foreach (ShiftInstance instance in instances) { Console.WriteLine(" (" + count + ")" + instance); count++; } } day = day.PlusDays(1); } }
/// <summary> /// Calculate the working time between the specified times of day. The shift /// must not span midnight. /// </summary> /// <param name="from">Starting local time</param> /// <param name="to">Ending local time</param> /// <returns></returns> public Duration CalculateWorkingTime(LocalTime from, LocalTime to) { if (SpansMidnight()) { String msg = String.Format(WorkSchedule.GetMessage("shift.spans.midnight"), Name, from, to); throw new Exception(msg); } return(this.CalculateWorkingTime(from, to, true)); }
/// <summary> /// Build a string representation of a shift instance /// </summary> /// <returns>String</returns> public override string ToString() { string t = WorkSchedule.GetMessage("team"); string s = WorkSchedule.GetMessage("shift"); string ps = WorkSchedule.GetMessage("period.start"); string pe = WorkSchedule.GetMessage("period.end"); string text = " " + t + ": " + Team.Name + ", " + s + ": " + Shift.Name + ", " + ps + ": " + StartDateTime + ", " + pe + ": " + GetEndTime(); return(text); }
/// <summary> /// Create a rotation /// </summary> /// <param name="name">Name</param> /// <param name="description">Description</param> /// <returns>Rotation</returns> public Rotation CreateRotation(string name, string description) { Rotation rotation = new Rotation(name, description); if (Rotations.Contains(rotation)) { string msg = String.Format(WorkSchedule.GetMessage("rotation.already.exists"), name); throw new Exception(msg); } Rotations.Add(rotation); rotation.WorkSchedule = this; return(rotation); }
/// <summary> /// Create a shift /// </summary> /// <param name="name">Name</param> /// <param name="description">Description</param> /// <param name="start">Start of shift</param> /// <param name="duration">Duration of shift</param> /// <returns>Shift</returns> public Shift CreateShift(string name, string description, LocalTime start, Duration duration) { Shift shift = new Shift(name, description, start, duration); if (Shifts.Contains(shift)) { string msg = String.Format(WorkSchedule.GetMessage("shift.already.exists"), name); throw new Exception(msg); } Shifts.Add(shift); shift.WorkSchedule = this; return(shift); }
/// <summary> /// Create a team /// </summary> /// <param name="name">Name</param> /// <param name="description">Description</param> /// <param name="rotation">Shift rotation</param> /// <param name="rotationStart">Start of rotation</param> /// <returns>Team</returns> public Team CreateTeam(string name, string description, Rotation rotation, LocalDate rotationStart) { Team team = new Team(name, description, rotation, rotationStart); if (Teams.Contains(team)) { string msg = String.Format(WorkSchedule.GetMessage("team.already.exists"), name); throw new Exception(msg); } Teams.Add(team); team.WorkSchedule = this; return(team); }
internal NonWorkingPeriod(string name, string description, LocalDateTime startDateTime, Duration duration) : base(name, description) { if (startDateTime == null) { throw new Exception(WorkSchedule.GetMessage("start.not.defined")); } if (duration == null || duration.TotalSeconds == 0) { throw new Exception(WorkSchedule.GetMessage("duration.not.defined")); } StartDateTime = startDateTime; Duration = duration; }
/// <summary> /// Get the day number in the rotation for this local date /// </summary> /// <param name="date">Date in rotation</param> /// <returns>Day number</returns> public int GetDayInRotation(LocalDate date) { // calculate total number of days from start of rotation long deltaDays = TimePeriod.DeltaDays(RotationStart, date); if (deltaDays < 0) { string msg = string.Format(WorkSchedule.GetMessage("end.earlier.than.start"), RotationStart, date); throw new Exception(msg); } int dayInRotation = (int)(deltaDays % Rotation.GetDuration().Days) + 1; return(dayInRotation); }
/// <summary> /// Build a string representation of this shift /// </summary> /// <returns>String</returns> public override string ToString() { string text = base.ToString(); if (Breaks.Count > 0) { text += "\n " + Breaks.Count + " " + WorkSchedule.GetMessage("breaks") + ":"; } foreach (Break breakPeriod in Breaks) { text += "\n " + breakPeriod.ToString(); } return(text); }
/// <summary> /// Build a string value for this period /// </summary> /// <returns>String</returns> public override string ToString() { string text = ""; string start = WorkSchedule.GetMessage("period.start"); string end = WorkSchedule.GetMessage("period.end"); try { text = base.ToString() + ", " + start + ": " + StartTime + " (" + Duration + ")" + ", " + end + ": " + GetEnd(); } catch (Exception) { } return(text); }
/// <summary> /// Create a non-working period of time /// </summary> /// <param name="name">Name</param> /// <param name="description">Description</param> /// <param name="startDateTime">Starting date and time of day</param> /// <param name="duration">Durtation of period</param> /// <returns>NonWorkingPeriod</returns> public NonWorkingPeriod CreateNonWorkingPeriod(string name, string description, LocalDateTime startDateTime, Duration duration) { NonWorkingPeriod period = new NonWorkingPeriod(name, description, startDateTime, duration); if (NonWorkingPeriods.Contains(period)) { string msg = String.Format(WorkSchedule.GetMessage("nonworking.period.already.exists"), name); throw new Exception(msg); } period.WorkSchedule = this; NonWorkingPeriods.Add(period); NonWorkingPeriods.Sort(); return(period); }
/// <summary> /// Build a string value for this team /// </summary> /// <returns>String</returns> public override string ToString() { string rpct = WorkSchedule.GetMessage("rotation.percentage"); string rs = WorkSchedule.GetMessage("rotation.start"); string avg = WorkSchedule.GetMessage("team.hours"); string text = ""; try { text = base.ToString() + ", " + rs + ": " + RotationStart + ", " + Rotation + ", " + rpct + ": " + GetPercentageWorked().ToString("0.00") + "%" + ", " + avg + ": " + GetHoursWorkedPerWeek(); } catch (Exception) { } return(text); }
/// <summary> /// Constructor /// </summary> /// <param name="name">Name</param> /// <param name="description">Desription</param> /// <param name="startTime">Starting time</param> /// <param name="duration">Duration</param> protected TimePeriod(string name, string description, LocalTime startTime, Duration duration) : base(name, description) { if (startTime == null) { throw new Exception(WorkSchedule.GetMessage("start.not.defined")); } if (duration == null || duration.TotalSeconds == 0) { throw new Exception(WorkSchedule.GetMessage("duration.not.defined")); } if (duration.TotalSeconds > SECONDS_PER_DAY) { throw new Exception(WorkSchedule.GetMessage("duration.not.allowed")); } this.StartTime = startTime; this.Duration = duration; }
/// <summary> /// Constructor /// </summary> /// <param name="name">Name</param> /// <param name="description">Description</param> protected Named(string name, string description) { Name = name ?? throw new Exception(WorkSchedule.GetMessage("name.not.defined")); Description = description; }
/// <summary> /// Calculate the schedule working time between the specified dates and times /// </summary> /// <param name="from">Starting date and time</param> /// <param name="to">Ending date and time</param> /// <returns>Duration</returns> public Duration CalculateWorkingTime(LocalDateTime from, LocalDateTime to) { if (from.CompareTo(to) > 0) { string msg = string.Format(WorkSchedule.GetMessage("end.earlier.than.start"), to, from); throw new Exception(msg); } Duration sum = Duration.Zero; LocalDate thisDate = from.Date; LocalTime thisTime = from.TimeOfDay; LocalDate toDate = to.Date; LocalTime toTime = to.TimeOfDay; int dayCount = Rotation.GetDayCount(); // get the working shift from yesterday Shift lastShift = null; LocalDate yesterday = thisDate.PlusDays(-1); ShiftInstance yesterdayInstance = GetShiftInstanceForDay(yesterday); if (yesterdayInstance != null) { lastShift = yesterdayInstance.Shift; } // step through each day until done while (thisDate.CompareTo(toDate) < 1) { if (lastShift != null && lastShift.SpansMidnight()) { // check for days in the middle of the time period bool lastDay = thisDate.CompareTo(toDate) == 0 ? true : false; if (!lastDay || (lastDay && !toTime.Equals(LocalTime.Midnight))) { // add time after midnight in this day int afterMidnightSecond = TimePeriod.SecondOfDay(lastShift.GetEnd()); int fromSecond = TimePeriod.SecondOfDay(thisTime); if (afterMidnightSecond > fromSecond) { Duration seconds = Duration.FromSeconds(afterMidnightSecond - fromSecond); sum = sum.Plus(seconds); } } } // today's shift ShiftInstance instance = GetShiftInstanceForDay(thisDate); Duration duration; if (instance != null) { lastShift = instance.Shift; // check for last date if (thisDate.CompareTo(toDate) == 0) { duration = lastShift.CalculateWorkingTime(thisTime, toTime, true); } else { duration = lastShift.CalculateWorkingTime(thisTime, LocalTime.MaxValue, true); } sum = sum.Plus(duration); } else { lastShift = null; } int n = 1; if (GetDayInRotation(thisDate) == dayCount) { // move ahead by the rotation count if possible LocalDate rotationEndDate = thisDate.PlusDays(dayCount); if (rotationEndDate.CompareTo(toDate) < 0) { n = dayCount; sum = sum.Plus(Rotation.GetWorkingTime()); } } // move ahead n days starting at midnight thisDate = thisDate.PlusDays(n); thisTime = LocalTime.Midnight; } // end day loop return(sum); }