internal static IEnumerable <CalculationOccurrence> CalculateOccurrences(CalculationTrigger trigger, DateTime startDate, DateTime?endDate) { if (trigger == null) { throw new ArgumentNullException("trigger"); } List <CalculationTrigger> triggers = new List <CalculationTrigger>() { trigger }; return(CalculateOccurrences(triggers, startDate, endDate)); }
internal static IEnumerable <DateTime> CalculateOccurrenceDates(CalculationTrigger trigger, DateTime startDate, DateTime?endDate) { //var occurrences = GetOccurrencesWithRecurrenceEvaluation(new Collection<CalculationTrigger> { trigger }, startDate, endDate); var occurrences = CalculateOccurrences(new List <CalculationTrigger> { trigger }, startDate, endDate); if (occurrences == null) { return(new List <DateTime>()); } else { return(occurrences.Select(it => it.ScheduledDate).ToList()); } }
private static CalculationOccurrence CreateCalendarEventOccurrence(DateTime date, CalculationTrigger trigger) { CalculationOccurrence occurrence = new CalculationOccurrence(); occurrence.Trigger = trigger; occurrence.Status = OccurrenceStatus.Undue; if (trigger.Recurrence != null && trigger.Recurrence.FollowTheEndOfMonth == true) { date = ToEoM(date); if (trigger.TriggerEndDate.HasValue && date > trigger.TriggerEndDate) { date = trigger.TriggerEndDate.Value; } } occurrence.ScheduledDate = date; return(occurrence); }
internal static IEnumerable <CalculationOccurrence> GetOccurrencesWithRecurrenceEvaluation(CalculationTrigger trigger, DateTime startDate, DateTime?endDate) { if (trigger == null) { throw new ArgumentNullException("trigger"); } List <CalculationTrigger> events = new List <CalculationTrigger>() { trigger }; return(GetOccurrencesWithRecurrenceEvaluation(events, startDate, endDate)); }
private static IEnumerable <CalculationOccurrence> GetDatesInternal(CalculationTrigger trigger, DateTime startDate, DateTime endDate) { List <CalculationOccurrence> dates = new List <CalculationOccurrence>(); if (trigger == null) { return(dates); } if (trigger.ScheduleRecurrenceType == ScheduleRecurrenceType.Custom) { if (trigger.Occurrences != null) { dates.AddRange(trigger.Occurrences); } return(dates); } // Fix dates trigger.TriggerStartDate = trigger.TriggerStartDate.Date; startDate = startDate.Date; endDate = endDate.Date; if (trigger.TriggerStartDate > startDate) { startDate = trigger.TriggerStartDate; } DateTime date = startDate; if (trigger.Recurrence == null || trigger.ScheduleRecurrenceType == ScheduleRecurrenceType.SingleOccurrence) { if (IsInRange(date, startDate, endDate) == false) { return(dates); } dates.Add(CreateCalendarEventOccurrence(date, trigger)); return(dates); } if (trigger.Recurrence == null) { return(dates); } if (trigger.Recurrence.IterationPeriodNumerator == 0) { trigger.Recurrence.IterationPeriodNumerator = 1; } long currentNumberOfOccurences = 0; switch (trigger.Recurrence.RecurrencePattern) { case RecurrencePattern.Daily: #region Daily if (trigger.Recurrence.DailyRecurrencePatternType.HasValue == false) { trigger.Recurrence.DailyRecurrencePatternType = DailyRecurrencePatternType.EveryNDays; } switch (trigger.Recurrence.DailyRecurrencePatternType.Value) { case DailyRecurrencePatternType.EveryNDays: #region Every N Days if (trigger.Recurrence.IterationPeriodNumerator > 0) { date = startDate; while (ShouldCreateOccurrence(trigger.ScheduleRecurrenceType, date, endDate, currentNumberOfOccurences, trigger.Recurrence.MaxOccurances)) { dates.Add(CreateCalendarEventOccurrence(date, trigger)); currentNumberOfOccurences++; date = date.AddDays(trigger.Recurrence.IterationPeriodNumerator); } } else { date = endDate; while (ShouldCreateOccurrence(trigger.ScheduleRecurrenceType, startDate, date, currentNumberOfOccurences, trigger.Recurrence.MaxOccurances)) { dates.Add(CreateCalendarEventOccurrence(date, trigger)); currentNumberOfOccurences++; date = date.AddDays(trigger.Recurrence.IterationPeriodNumerator); } } #endregion break; case DailyRecurrencePatternType.EveryWeekday: #region Every week day date = startDate; while (ShouldCreateOccurrence(trigger.ScheduleRecurrenceType, date, endDate, currentNumberOfOccurences, trigger.Recurrence.MaxOccurances)) { if (IsWorkingDay(date)) { dates.Add(CreateCalendarEventOccurrence(date, trigger)); currentNumberOfOccurences++; } date = date.AddDays(1); } #endregion break; default: throw new NotSupportedException(string.Format("DailyRecurrencePatternType {0} is not supported.", trigger.Recurrence.DailyRecurrencePatternType)); } break; #endregion case RecurrencePattern.Weekly: #region Weekly if (trigger.Recurrence.DayOfWeek.HasValue == false) { throw new Exception("Value of Recurrence.DayOfWeek is not set, it is null."); } var multiplier = Math.Abs(trigger.Recurrence.IterationPeriodNumerator); #region Create list of dates from flag enumeration daysOfWeek var daysOfWeek = new List <DayOfWeek>(); foreach (DayOfWeek dayOfWeek in Enum.GetValues(typeof(DayOfWeek))) { if (trigger.Recurrence.DayOfWeek.HasValue && trigger.Recurrence.DayOfWeek.Value.HasFlag(dayOfWeek)) { daysOfWeek.Add(dayOfWeek); } } #endregion #region Set first date date = startDate; if (!daysOfWeek.Where(a => a == date.DayOfWeek).Any()) { if (daysOfWeek.Where(a => a > date.DayOfWeek).Any()) { var currentDayOfWeek = daysOfWeek.Where(a => a > date.DayOfWeek).FirstOrDefault(); while (date.DayOfWeek != currentDayOfWeek) { date = date.AddDays(1); } } else { var currentDayOfWeek = daysOfWeek.FirstOrDefault(); date = date.AddDays(7 * multiplier); while (date.DayOfWeek != currentDayOfWeek) { date = date.AddDays(-1); } } } #endregion #region Create And Add Create Occurrences while (ShouldCreateOccurrence(trigger.ScheduleRecurrenceType, date, endDate, currentNumberOfOccurences, trigger.Recurrence.MaxOccurances)) { dates.Add(CreateCalendarEventOccurrence(date, trigger)); currentNumberOfOccurences++; if (daysOfWeek.Where(a => a > date.DayOfWeek).Any()) { var currentDayOfWeek = daysOfWeek.Where(a => a > date.DayOfWeek).FirstOrDefault(); while (date.DayOfWeek != currentDayOfWeek) { date = date.AddDays(1); } } else { var currentDayOfWeek = daysOfWeek.FirstOrDefault(); date = date.AddDays(7 * multiplier); while (date.DayOfWeek != currentDayOfWeek) { date = date.AddDays(-1); } } } #endregion break; #endregion case RecurrencePattern.Monthly: #region Monthly if (trigger.Recurrence.MonthlyRecurrencePatternType.HasValue == false) { trigger.Recurrence.MonthlyRecurrencePatternType = MonthlyRecurrencePatternType.DayOfMonth; } trigger.Recurrence.IterationPeriodNumerator = Math.Abs(trigger.Recurrence.IterationPeriodNumerator); switch (trigger.Recurrence.MonthlyRecurrencePatternType.Value) { case MonthlyRecurrencePatternType.DayOfMonth: #region Day Of Month if (trigger.Recurrence.DayOfMonth.HasValue == false) { trigger.Recurrence.DayOfMonth = startDate.Day; //throw new CalculationServiceException("Value of Recurrence.DayOfMonth is not set, it is null."); } #region Set first date if (startDate.Day == trigger.Recurrence.DayOfMonth) { date = startDate; } else { int day = DateTime.DaysInMonth(date.Year, date.Month) < trigger.Recurrence.DayOfMonth.Value ? DateTime.DaysInMonth(date.Year, date.Month) : trigger.Recurrence.DayOfMonth.Value; date = new DateTime(date.Year, date.Month, day); while (date < startDate) { date = date.AddMonths(1); day = DateTime.DaysInMonth(date.Year, date.Month) < trigger.Recurrence.DayOfMonth.Value ? DateTime.DaysInMonth(date.Year, date.Month) : trigger.Recurrence.DayOfMonth.Value; date = new DateTime(date.Year, date.Month, day); } } #endregion #region Create And Add Create Occurrences while (ShouldCreateOccurrence(trigger.ScheduleRecurrenceType, date, endDate, currentNumberOfOccurences, trigger.Recurrence.MaxOccurances)) { dates.Add(CreateCalendarEventOccurrence(date, trigger)); currentNumberOfOccurences++; date = date.AddMonths(trigger.Recurrence.IterationPeriodNumerator); int day = DateTime.DaysInMonth(date.Year, date.Month) < trigger.Recurrence.DayOfMonth.Value ? DateTime.DaysInMonth(date.Year, date.Month) : trigger.Recurrence.DayOfMonth.Value; date = new DateTime(date.Year, date.Month, day); } #endregion #endregion break; case MonthlyRecurrencePatternType.DayOfWeekOfMonth: #region Day of week of month if (trigger.Recurrence.DayOfWeek.HasValue == false) { throw new Exception("Value of Recurrence.DayOfWeek is not set, it is null."); } if (trigger.Recurrence.WeekOfMonth.HasValue == false) { throw new Exception("Value of Recurrence.WeekOfMonth is not set, it is null."); } #region Set first date date = FindDayOfWeekOfMonth(trigger.Recurrence.DayOfWeek.GetValueOrDefault(), (WeekOfMonth)trigger.Recurrence.WeekOfMonth, new DateTime(startDate.Year, startDate.Month, 1)); if (date < startDate) { date = FindDayOfWeekOfMonth(trigger.Recurrence.DayOfWeek.GetValueOrDefault(), (WeekOfMonth)trigger.Recurrence.WeekOfMonth, new DateTime(date.Year, date.Month, 1).AddMonths(1)); } #endregion #region Create and add Occurence while (ShouldCreateOccurrence(trigger.ScheduleRecurrenceType, date, endDate, currentNumberOfOccurences, trigger.Recurrence.MaxOccurances)) { dates.Add(CreateCalendarEventOccurrence(date, trigger)); currentNumberOfOccurences++; date = FindDayOfWeekOfMonth(trigger.Recurrence.DayOfWeek.GetValueOrDefault(), (WeekOfMonth)trigger.Recurrence.WeekOfMonth, new DateTime(date.Year, date.Month, 1).AddMonths(1)); } #endregion #endregion break; default: throw new NotSupportedException(string.Format("MonthlyRecurrencePatternType {0} is not supported.", trigger.Recurrence.MonthlyRecurrencePatternType));; } break; #endregion case RecurrencePattern.Yearly: #region Yearly if (trigger.Recurrence.MonthlyRecurrencePatternType.HasValue == false) { trigger.Recurrence.MonthlyRecurrencePatternType = MonthlyRecurrencePatternType.DayOfMonth; } trigger.Recurrence.IterationPeriodNumerator = Math.Abs(trigger.Recurrence.IterationPeriodNumerator); switch (trigger.Recurrence.MonthlyRecurrencePatternType.Value) { case MonthlyRecurrencePatternType.DayOfMonth: if (trigger.Recurrence.DayOfMonth.HasValue == false) { trigger.Recurrence.DayOfMonth = startDate.Day; //throw new CalculationServiceException("Value of Recurrence.DayOfMonth is not set."); } if (trigger.Recurrence.MonthOfYear.HasValue == false) { throw new NullReferenceException("Value of Recurrence.MonthOfYear is not set."); } #region Set start date int month = GetMonthNumber(trigger.Recurrence.MonthOfYear.Value); int day = DateTime.DaysInMonth(date.Year, date.Month) < trigger.Recurrence.DayOfMonth.Value ? DateTime.DaysInMonth(date.Year, date.Month) : trigger.Recurrence.DayOfMonth.Value; date = new DateTime(date.Year, month, day); while (date < startDate) { date = date.AddYears(1); } #endregion #region Create And Add Create Occurrences while (ShouldCreateOccurrence(trigger.ScheduleRecurrenceType, date, endDate, currentNumberOfOccurences, trigger.Recurrence.MaxOccurances)) { dates.Add(CreateCalendarEventOccurrence(date, trigger)); currentNumberOfOccurences++; date = date.AddYears(trigger.Recurrence.IterationPeriodNumerator); } #endregion break; case MonthlyRecurrencePatternType.DayOfWeekOfMonth: if (trigger.Recurrence.DayOfWeek.HasValue == false) { throw new Exception("Value of Recurrence.DayOfWeek is not set, it is null."); } if (trigger.Recurrence.WeekOfMonth.HasValue == false) { throw new Exception("Value of Recurrence.WeekOfMonth is not set, it is null."); } if (trigger.Recurrence.MonthOfYear.HasValue == false) { throw new Exception("Value of Recurrence.MonthOfYear is not set, it is null."); } #region Set start date date = new DateTime(startDate.Year, GetMonthNumber((MonthOfYear)trigger.Recurrence.MonthOfYear), 1); date = FindDayOfWeekOfMonth(trigger.Recurrence.DayOfWeek.GetValueOrDefault(), (WeekOfMonth)trigger.Recurrence.WeekOfMonth, new DateTime(date.Year, GetMonthNumber((MonthOfYear)trigger.Recurrence.MonthOfYear), 1)); if (date < startDate) { date = FindDayOfWeekOfMonth(trigger.Recurrence.DayOfWeek.GetValueOrDefault(), (WeekOfMonth)trigger.Recurrence.WeekOfMonth, new DateTime(date.Year + 1, GetMonthNumber((MonthOfYear)trigger.Recurrence.MonthOfYear), 1)); } #endregion #region Create and Add Occurrences while (ShouldCreateOccurrence(trigger.ScheduleRecurrenceType, date, endDate, currentNumberOfOccurences, trigger.Recurrence.MaxOccurances)) { dates.Add(CreateCalendarEventOccurrence(date, trigger)); currentNumberOfOccurences++; date = FindDayOfWeekOfMonth(trigger.Recurrence.DayOfWeek.GetValueOrDefault(), (WeekOfMonth)trigger.Recurrence.WeekOfMonth, new DateTime(date.Year + 1, GetMonthNumber((MonthOfYear)trigger.Recurrence.MonthOfYear), 1)); } #endregion break; default: throw new NotSupportedException(string.Format("MonthlyRecurrencePatternType {0} is not supported.", trigger.Recurrence.MonthlyRecurrencePatternType));; } break; #endregion default: throw new NotSupportedException(string.Format("RecurrencePattern {0} is not supported.", trigger.Recurrence.RecurrencePattern));; } return(dates); }