예제 #1
0
        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));
        }
예제 #2
0
        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());
            }
        }
예제 #3
0
        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);
        }
예제 #4
0
        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));
        }
예제 #5
0
        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);
        }