Пример #1
0
        /// <summary>Gets the previous date.</summary>
        /// <param name="dateTime">The date time.</param>
        /// <param name="fp">The frequency pattern.</param>
        /// <returns></returns>
        private static DateTime GetPreviousDate(DateTime dateTime, IFrequencyPattern fp)
        {
            fp.DisableBusinessRules();

            #region Set FrequencyPatternType

            FrequencyPatternType fpType;
            if (!Enum.TryParse(fp.PatternType, out fpType))
            {
                Logger.Log(LogSeverity.Warning, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", "ScheduleManager", Environment.NewLine, "GetNextDate"), "Error parsing FrequencyPattern, fpType");
            }

            DailyPatternVariant fpDailyPatternVariant;
            if (Enum.TryParse(fp.DailyPatternOption, out fpDailyPatternVariant))
            {
                Logger.Log(LogSeverity.Warning, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", "ScheduleManager", Environment.NewLine, "GetNextDate"), "Error parsing FrequencyPattern, fpDailyPatternVariant");
            }

            MonthlyPatternVariant fpMonthlyPatternVariant;
            if (Enum.TryParse(fp.MonPatOption, out fpMonthlyPatternVariant))
            {
                Logger.Log(LogSeverity.Warning, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", "ScheduleManager", Environment.NewLine, "GetNextDate"), "Error parsing FrequencyPattern, fpMonthlyPatternVariant");
            }

            DayOfWeek fpMonthlyPatternDayOfWeek;
            if (Enum.TryParse(fp.MonPatDayOfWeek, out fpMonthlyPatternDayOfWeek))
            {
                Logger.Log(LogSeverity.Warning, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", "ScheduleManager", Environment.NewLine, "GetNextDate"), "Error parsing FrequencyPattern, fpMonthlyPatternDayOfWeek");
            }

            RecurYearlyOption fpRecurYearlyOption;
            if (Enum.TryParse(fp.YearPatRecurYearlyOption, out fpRecurYearlyOption))
            {
                Logger.Log(LogSeverity.Warning, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", "ScheduleManager", Environment.NewLine, "GetNextDate"), "Error parsing FrequencyPattern, fpRecurYearlyOption");
            }

            YearlyPatternVariant fpYearlyPatternVariant;
            if (Enum.TryParse(fp.YearPatOption, out fpYearlyPatternVariant))
            {
                Logger.Log(LogSeverity.Warning, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", "ScheduleManager", Environment.NewLine, "GetNextDate"), "Error parsing FrequencyPattern, fpYearlyPatternVariant");
            }

            DayOfWeek fpYearlyPatternDayOfWeek;
            if (Enum.TryParse(fp.YearPatDayOfWeek, out fpYearlyPatternDayOfWeek))
            {
                Logger.Log(LogSeverity.Warning, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", "ScheduleManager", Environment.NewLine, "GetNextDate"), "Error parsing FrequencyPattern, fpYearlyPatternDayOfWeek");
            }

            TimeIntervalPosition fpYearlyPatternTimeIntervalPosition;
            if (Enum.TryParse(fp.YearPatTimeIntervalPosition, out fpYearlyPatternTimeIntervalPosition))
            {
                Logger.Log(LogSeverity.Warning, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", "ScheduleManager", Environment.NewLine, "GetNextDate"), "Error parsing FrequencyPattern, fpYearlyPatternTimeIntervalPosition");
            }

            TimeIntervalPosition fpMonthlyPatternTimeIntervalPosition;
            if (Enum.TryParse(fp.MonPatTimeIntervalPosition, out fpMonthlyPatternTimeIntervalPosition))
            {
                Logger.Log(LogSeverity.Warning, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", "ScheduleManager", Environment.NewLine, "GetNextDate"), "Error parsing FrequencyPattern, fpMonthlyPatternTimeIntervalPosition");
            }

            #endregion

            switch (fpType)
            {
                case FrequencyPatternType.Weekly:

                    #region GetPreviousDate for Weekly pattern

                    var currentDay = dateTime.DayOfWeek;
                    var selectedDays = new List<DayOfWeek>();

                    if (fp.IsSundaySelected.GetValueOrDefault(false)) selectedDays.Add(DayOfWeek.Sunday);
                    if (fp.IsMondaySelected.GetValueOrDefault(false)) selectedDays.Add(DayOfWeek.Monday);
                    if (fp.IsTuesdaySelected.GetValueOrDefault(false)) selectedDays.Add(DayOfWeek.Tuesday);
                    if (fp.IsWednesdaySelected.GetValueOrDefault(false)) selectedDays.Add(DayOfWeek.Wednesday);
                    if (fp.IsThursdaySelected.GetValueOrDefault(false)) selectedDays.Add(DayOfWeek.Thursday);
                    if (fp.IsFridaySelected.GetValueOrDefault(false)) selectedDays.Add(DayOfWeek.Friday);
                    if (fp.IsSaturdaySelected.GetValueOrDefault(false)) selectedDays.Add(DayOfWeek.Saturday);

                    var possibleDays = selectedDays.Where(x => x < currentDay).ToArray();

                    return possibleDays.Any() ?
                                dateTime.AddDays(possibleDays.Max() - currentDay) :
                                dateTime.AddDays((-fp.WeeklyPatternWeeksToRecur.GetValueOrDefault(0) * 7 + (selectedDays.Max() - currentDay)));

                    #endregion

                case FrequencyPatternType.Monthly:

                    #region GetPreviousDate for Monthly pattern

                    DateTime previousMonth;

                    switch (fpMonthlyPatternVariant)
                    {
                        case MonthlyPatternVariant.NumberOfMonths:
                            {
                                return dateTime.AddMonths(-fp.MonPatMonthsToRec.GetValueOrDefault(0));
                            }

                        case MonthlyPatternVariant.DayByDate:
                            {
                                var currentDayOfMonth = dateTime.Day;
                                var recurDate = fp.MonPatRecurDate >
                                                DateTime.DaysInMonth(dateTime.Year, dateTime.Month)
                                                    ? DateTime.DaysInMonth(dateTime.Year, dateTime.Month)
                                                    : fp.MonPatRecurDate;

                                if (recurDate < currentDayOfMonth)
                                {
                                    return dateTime.AddDays((double)(recurDate - currentDayOfMonth));
                                }

                                previousMonth = dateTime.AddMonths(-fp.MonPatByDateOptionMonthsToRec.GetValueOrDefault(0));
                                return new DateTime(previousMonth.Year, previousMonth.Month, (fp.MonPatRecurDate.GetValueOrDefault(0) > DateTime.DaysInMonth(previousMonth.Year, previousMonth.Month)
                                                                                          ? DateTime.DaysInMonth(previousMonth.Year, previousMonth.Month)
                                                                                          : fp.MonPatRecurDate.GetValueOrDefault(0)));
                            }
                        case MonthlyPatternVariant.DayByPosition:
                            previousMonth = dateTime.AddMonths(-fp.MonPatByPositionOptionMonToRec.GetValueOrDefault(0));

                            var basicDates = new List<object>
                                                 {
                                                     new {
                                                             basicDate = previousMonth,
                                                             firstDay = new DateTime(previousMonth.Year, previousMonth.Month, 1),
                                                             lastDay = new DateTime(previousMonth.Year, previousMonth.Month, DateTime.DaysInMonth(previousMonth.Year, previousMonth.Month))
                                                         },
                                                         /* dateTime here is either Schedule based on or field to display schedule date. Fallback? */
                                                     new {
                                                             basicDate = dateTime,
                                                             firstDay = new DateTime(dateTime.Year, dateTime.Month, 1),
                                                             lastDay = new DateTime(dateTime.Year, dateTime.Month, DateTime.DaysInMonth(dateTime.Year, dateTime.Month))
                                                         }
                                                 };
                            foreach (var bd in basicDates)
                            {
                                DateTime testDate;

                                var basicDate = (DateTime)bd.GetType().GetProperty("basicDate").GetValue(bd, null);
                                var firstDay = (DateTime)bd.GetType().GetProperty("firstDay").GetValue(bd, null);
                                var lastDay = (DateTime)bd.GetType().GetProperty("lastDay").GetValue(bd, null);

                                if (fp.MonPatTimeIntervalPosition != TimeIntervalPosition.Last.ToString())
                                {

                                    if (fpMonthlyPatternDayOfWeek > firstDay.DayOfWeek)
                                    {
                                        testDate = new DateTime(basicDate.Year, basicDate.Month, 1 +
                                                                (fpMonthlyPatternDayOfWeek - firstDay.DayOfWeek +
                                                                 7 * (int)fpMonthlyPatternTimeIntervalPosition));
                                    }
                                    else if (fpMonthlyPatternDayOfWeek < firstDay.DayOfWeek)
                                    {
                                        testDate = new DateTime(basicDate.Year, basicDate.Month, 1 +
                                                                (7 - (firstDay.DayOfWeek - fpMonthlyPatternDayOfWeek) +
                                                                 7 * (int)fpMonthlyPatternTimeIntervalPosition));
                                    }
                                    else
                                    {
                                        testDate = new DateTime(basicDate.Year, basicDate.Month, 1 + 7 * (int)fpMonthlyPatternTimeIntervalPosition);
                                    }
                                }
                                else
                                {
                                    if (fpMonthlyPatternDayOfWeek < lastDay.DayOfWeek)
                                    {
                                        testDate = new DateTime(basicDate.Year, basicDate.Month, lastDay.Day -
                                                                (lastDay.DayOfWeek - fpMonthlyPatternDayOfWeek));
                                    }
                                    else if (fpMonthlyPatternDayOfWeek > lastDay.DayOfWeek)
                                    {
                                        testDate = new DateTime(basicDate.Year, basicDate.Month, lastDay.Day -
                                                                (7 - (fpMonthlyPatternDayOfWeek - lastDay.DayOfWeek)));
                                    }
                                    else
                                    {
                                        testDate = new DateTime(basicDate.Year, basicDate.Month, lastDay.Day);
                                    }
                                }

                                if (testDate > dateTime)
                                    return testDate;
                            }
                            break;
                    }

	                #endregion
                    break;
                case FrequencyPatternType.Yearly:

                    #region GetPreviousDate for Yearly pattern

                    if (fpRecurYearlyOption == RecurYearlyOption.RecurYearly)
                    {
                        dateTime = dateTime.AddYears(-fp.YearPatYearsToRec.GetValueOrDefault(0));
                        break;
                    }

                    switch (fpYearlyPatternVariant)
                    {
                        case YearlyPatternVariant.DayByDate:
                            var withinTheSameYear = new DateTime(dateTime.Year,
                                                                 DateTime.ParseExact(
                                                                     fp.YearPatByDateOptionSelectMon, "MMMM",
                                                                     new CultureInfo(Constants.DefaultCultureName)).Month, fp.YearPatDayOfSelectMon.GetValueOrDefault(0));
                            if (dateTime < withinTheSameYear)
                                return withinTheSameYear;

                            return new DateTime(-dateTime.AddYears(fp.YearPatYearsToRec.GetValueOrDefault(0)).Year,
                                                DateTime.ParseExact(
                                                    fp.YearPatByDateOptionSelectMon, "MMMM",
                                                    new CultureInfo(Constants.DefaultCultureName)).Month, fp.YearPatDayOfSelectMon.GetValueOrDefault(0));

                        case YearlyPatternVariant.DayByName:
                            var nextYear = dateTime.AddYears(-fp.YearPatYearsToRec.GetValueOrDefault(0));
                            var selectedMonth = DateTime.ParseExact(fp.YearPatByNameOptionSelectMon, "MMMM",
                                                                                        new CultureInfo(Constants.DefaultCultureName)).Month;

                            var basicDates = new List<object>
                                                 {
                                                     new {
                                                             basicDate = dateTime,
                                                             firstDay = new DateTime(dateTime.Year, selectedMonth, 1),
                                                             lastDay = new DateTime(dateTime.Year, selectedMonth,
                                                                                    DateTime.DaysInMonth(dateTime.Year, selectedMonth))
                                                         },
                                                     new {
                                                             basicDate = nextYear,
                                                             firstDay = new DateTime(nextYear.Year, selectedMonth, 1),
                                                             lastDay = new DateTime(nextYear.Year, selectedMonth,
                                                                                    DateTime.DaysInMonth(nextYear.Year, selectedMonth))
                                                         }
                                                 };
                            foreach (var bd in basicDates)
                            {
                                DateTime testDate;

                                var basicDate = (DateTime)bd.GetType().GetProperty("basicDate").GetValue(bd, null);
                                var firstDay = (DateTime)bd.GetType().GetProperty("firstDay").GetValue(bd, null);
                                var lastDay = (DateTime)bd.GetType().GetProperty("lastDay").GetValue(bd, null);

                                if (fp.YearPatTimeIntervalPosition != TimeIntervalPosition.Last.ToString())
                                {

                                    if (fpYearlyPatternDayOfWeek > firstDay.DayOfWeek)
                                    {
                                        testDate = new DateTime(basicDate.Year, firstDay.Month, 1 +
                                                                (fpYearlyPatternDayOfWeek - firstDay.DayOfWeek +
                                                                 7 * (int)fpYearlyPatternTimeIntervalPosition));
                                    }
                                    else if (fpYearlyPatternDayOfWeek < firstDay.DayOfWeek)
                                    {
                                        testDate = new DateTime(basicDate.Year, firstDay.Month, 1 +
                                                                (7 - (firstDay.DayOfWeek - fpYearlyPatternDayOfWeek) +
                                                                 7 * (int)fpYearlyPatternTimeIntervalPosition));
                                    }
                                    else
                                    {
                                        testDate = new DateTime(basicDate.Year, firstDay.Month, 1 + 7 * (int)fpYearlyPatternTimeIntervalPosition);
                                    }
                                }
                                else
                                {
                                    if (fpYearlyPatternDayOfWeek < lastDay.DayOfWeek)
                                    {
                                        testDate = new DateTime(basicDate.Year, firstDay.Month, lastDay.Day -
                                                                (lastDay.DayOfWeek - fpYearlyPatternDayOfWeek));
                                    }
                                    else if (fpYearlyPatternDayOfWeek > lastDay.DayOfWeek)
                                    {
                                        testDate = new DateTime(basicDate.Year, firstDay.Month, lastDay.Day -
                                                                (7 - (fpYearlyPatternDayOfWeek - lastDay.DayOfWeek)));
                                    }
                                    else
                                    {
                                        testDate = new DateTime(basicDate.Year, firstDay.Month, lastDay.Day);
                                    }
                                }

                                if (testDate > dateTime)
                                    return testDate;
                            }
                            break;
                    }

                    #endregion                    
                    break;
            }
            return dateTime;
        }
Пример #2
0
        private static DateTime GetNextDate(DateTime dateTime, IFrequencyPattern fp, ICalendar calendar)
        {
            fp.DisableBusinessRules();

            #region Set FrequencyPatternType

            FrequencyPatternType fpType;
            if (!Enum.TryParse(fp.PatternType, out fpType))
            {
                Logger.Log(LogSeverity.Warning, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", "ScheduleManager", Environment.NewLine, "GetNextDate"), "Error parsing FrequencyPattern, fpType");
            }

            DailyPatternVariant fpDailyPatternVariant;
            if (Enum.TryParse(fp.DailyPatternOption, out fpDailyPatternVariant))
            {
                Logger.Log(LogSeverity.Warning, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", "ScheduleManager", Environment.NewLine, "GetNextDate"), "Error parsing FrequencyPattern, fpDailyPatternVariant");
            }

            MonthlyPatternVariant fpMonthlyPatternVariant;
            if (Enum.TryParse(fp.MonPatOption, out fpMonthlyPatternVariant))
            {
                Logger.Log(LogSeverity.Warning, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", "ScheduleManager", Environment.NewLine, "GetNextDate"), "Error parsing FrequencyPattern, fpMonthlyPatternVariant");
            }

            DayOfWeek fpMonthlyPatternDayOfWeek;
            if (Enum.TryParse(fp.MonPatDayOfWeek, out fpMonthlyPatternDayOfWeek))
            {
                Logger.Log(LogSeverity.Warning, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", "ScheduleManager", Environment.NewLine, "GetNextDate"), "Error parsing FrequencyPattern, fpMonthlyPatternDayOfWeek");
            }

            RecurYearlyOption fpRecurYearlyOption;
            if (Enum.TryParse(fp.YearPatRecurYearlyOption, out fpRecurYearlyOption))
            {
                Logger.Log(LogSeverity.Warning, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", "ScheduleManager", Environment.NewLine, "GetNextDate"), "Error parsing FrequencyPattern, fpRecurYearlyOption");
            }

            YearlyPatternVariant fpYearlyPatternVariant;
            if (Enum.TryParse(fp.YearPatOption, out fpYearlyPatternVariant))
            {
                Logger.Log(LogSeverity.Warning, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", "ScheduleManager", Environment.NewLine, "GetNextDate"), "Error parsing FrequencyPattern, fpYearlyPatternVariant");
            }

            DayOfWeek fpYearlyPatternDayOfWeek;
            if (Enum.TryParse(fp.YearPatDayOfWeek, out fpYearlyPatternDayOfWeek))
            {
                Logger.Log(LogSeverity.Warning, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", "ScheduleManager", Environment.NewLine, "GetNextDate"), "Error parsing FrequencyPattern, fpYearlyPatternDayOfWeek");
            }

            TimeIntervalPosition fpYearlyPatternTimeIntervalPosition;
            if (Enum.TryParse(fp.YearPatTimeIntervalPosition, out fpYearlyPatternTimeIntervalPosition))
            {
                Logger.Log(LogSeverity.Warning, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", "ScheduleManager", Environment.NewLine, "GetNextDate"), "Error parsing FrequencyPattern, fpYearlyPatternTimeIntervalPosition");
            }

            TimeIntervalPosition fpMonthlyPatternTimeIntervalPosition;
            if (Enum.TryParse(fp.MonPatTimeIntervalPosition, out fpMonthlyPatternTimeIntervalPosition))
            {
                Logger.Log(LogSeverity.Warning, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", "ScheduleManager", Environment.NewLine, "GetNextDate"), "Error parsing FrequencyPattern, fpMonthlyPatternTimeIntervalPosition");
            }

            #endregion

            switch (fpType)
            {
                case FrequencyPatternType.Daily:

                    #region GetNextDate for Daily pattern

                    var nextDate = dateTime;

                    if (calendar != null && calendar.WorkingIntervals != null && calendar.WorkingExceptions != null && calendar.WorkingIntervals.Any())
                    {
                        var calendarWorkingIntervals = calendar.WorkingIntervals.Where(wi => wi.StartDate.HasValue && wi.FinishDate.HasValue && wi.StartDate.Value < wi.FinishDate.Value).ToList();
                        var calendarWorkingExceptions = calendar.WorkingExceptions.Where(we => we.StartDate.HasValue && we.FinishDate.HasValue && we.StartDate.Value < we.FinishDate.Value).ToList();

                        var isWorkingDay = false;
                        short infiniteLoop = 0;

                        while (!isWorkingDay)
                        {
                            infiniteLoop++;
                            if (infiniteLoop > 100)
                            {
                                nextDate = fpDailyPatternVariant == DailyPatternVariant.WorkingDays ? dateTime.AddDays(1.0) : dateTime.AddDays(fp.DailyPatternDaysToRecur.GetValueOrDefault(0));
                                break;
                            }

                            var exception = GetWorkingException(nextDate, calendar, calendarWorkingIntervals, FrequencyPatternType.Daily);
                            if (exception != null)
                            {
                                ExceptionBehavior exceptionBehavior = ExceptionBehavior.ScheduleAfter;
                                if (!string.IsNullOrEmpty(exception.ExceptionBehavior) && !Enum.TryParse(exception.ExceptionBehavior, out exceptionBehavior))
                                    exceptionBehavior = ExceptionBehavior.ScheduleAfter;

                                switch (exceptionBehavior)
                                {
                                    case ExceptionBehavior.Skip:
                                    case ExceptionBehavior.ScheduleAfter:
                                        var exceptionEndDate = exception.FinishDate.Value;
                                        nextDate = fpDailyPatternVariant == DailyPatternVariant.WorkingDays ? 
                                            (new DateTime(exceptionEndDate.Year, exceptionEndDate.Month, exceptionEndDate.Day, nextDate.Hour, nextDate.Minute, nextDate.Second)).AddDays(1.0) : 
                                            nextDate.AddDays(fp.DailyPatternDaysToRecur.GetValueOrDefault(0));
                                        break;
                                    case ExceptionBehavior.ScheduleBefore:
                                        var exceptionStartDate = exception.StartDate.Value;
                                        nextDate = fpDailyPatternVariant == DailyPatternVariant.WorkingDays ?
                                            (new DateTime(exceptionStartDate.Year, exceptionStartDate.Month, exceptionStartDate.Day, nextDate.Hour, nextDate.Minute, nextDate.Second)).AddDays(-1.0) : 
                                            nextDate.AddDays(-fp.DailyPatternDaysToRecur.GetValueOrDefault(0));
                                        break;
                                }
                            }
                            else
                            {
                                nextDate = fpDailyPatternVariant == DailyPatternVariant.WorkingDays ? nextDate.AddDays(1.0) : nextDate.AddDays(fp.DailyPatternDaysToRecur.GetValueOrDefault(0));
                            }

                            if (!calendar.WorkingExceptions.Any())
                            {
                                isWorkingDay = (from wi in calendarWorkingIntervals
                                                where nextDate.DayOfWeek.ToString() == wi.Weekday
                                                select wi).Any();
                            }
                            else
                            {
/*
                                var tryNextDate = GetTime(nextDate, calendar);
                                if (tryNextDate.HasValue)
                                {
                                    nextDate = tryNextDate.Value;
                                    isWorkingDay = (from wi in calendarWorkingIntervals
                                                    where nextDate.DayOfWeek.ToString() == wi.Weekday
                                                    select wi).Any();
                                }
*/
                                isWorkingDay = (from wi in calendarWorkingIntervals
                                                from we in calendarWorkingExceptions
/*
                                                let peopleHaveToWork = 
                                                    ((nextDate.Date == we.StartDate.Value.Date & (wi.StartDate.Value.TimeOfDay < we.StartDate.Value.TimeOfDay)) ||
                                                     (nextDate.Date == we.FinishDate.Value.Date & (wi.FinishDate.Value.TimeOfDay > we.FinishDate.Value.TimeOfDay)))
*/
                                                let res = nextDate.DayOfWeek.ToString() == wi.Weekday &&
                                                          //(peopleHaveToWork ||
                                                          !(from x in calendarWorkingExceptions

                                                            let wiComplete =
                                                                (from y in calendarWorkingIntervals
                                                                 where y.Weekday == nextDate.DayOfWeek.ToString()
                                                                 group y by y.Weekday into wiWide
                                                                 select new
                                                                     {
                                                                         Weekday = wiWide.Key,
                                                                         StartDate = wiWide.Min(st => st.StartDate.Value),
                                                                         FinishDate = wiWide.Max(ft => ft.FinishDate.Value)
                                                                     }).First()

                                                            where ((nextDate.Date > x.StartDate.Value.Date ||
                                                                   (nextDate.Date == x.StartDate.Value.Date & (wiComplete.StartDate.TimeOfDay >= x.StartDate.Value.TimeOfDay))) &
                                                                   (nextDate.Date < x.FinishDate.Value.Date ||
                                                                   (nextDate.Date == x.FinishDate.Value.Date &
                                                                   (wiComplete.FinishDate.TimeOfDay <= x.FinishDate.Value.TimeOfDay))))

                                                            select x).Any()//)

                                                where res
                                                select res).FirstOrDefault();
                            }
                        }

                        return nextDate;
                    }

                    nextDate = fpDailyPatternVariant == DailyPatternVariant.WorkingDays ? nextDate.AddDays(1.0) : nextDate.AddDays(fp.DailyPatternDaysToRecur.GetValueOrDefault(0));
                    while (nextDate.DayOfWeek == DayOfWeek.Saturday || nextDate.DayOfWeek == DayOfWeek.Sunday)
                    {
                        nextDate = fpDailyPatternVariant == DailyPatternVariant.WorkingDays ? nextDate.AddDays(1.0) : nextDate.AddDays(fp.DailyPatternDaysToRecur.GetValueOrDefault(0));
                    }
                    return nextDate;

                    #endregion

                case FrequencyPatternType.Weekly:

                    #region GetNextDate for Weekly pattern

                    var currentDay = dateTime.DayOfWeek;
                    var selectedDays = new List<DayOfWeek>();

                    if (fp.IsSundaySelected.GetValueOrDefault(false)) selectedDays.Add(DayOfWeek.Sunday);
                    if (fp.IsMondaySelected.GetValueOrDefault(false)) selectedDays.Add(DayOfWeek.Monday);
                    if (fp.IsTuesdaySelected.GetValueOrDefault(false)) selectedDays.Add(DayOfWeek.Tuesday);
                    if (fp.IsWednesdaySelected.GetValueOrDefault(false)) selectedDays.Add(DayOfWeek.Wednesday);
                    if (fp.IsThursdaySelected.GetValueOrDefault(false)) selectedDays.Add(DayOfWeek.Thursday);
                    if (fp.IsFridaySelected.GetValueOrDefault(false)) selectedDays.Add(DayOfWeek.Friday);
                    if (fp.IsSaturdaySelected.GetValueOrDefault(false)) selectedDays.Add(DayOfWeek.Saturday);

                    var possibleDays = selectedDays.Where(x => x > currentDay).ToArray();

                    return possibleDays.Any() ?
                                dateTime.AddDays(possibleDays.Min() - currentDay) :
                                dateTime.AddDays((fp.WeeklyPatternWeeksToRecur.GetValueOrDefault(0) * 7 - (currentDay - selectedDays.Min())));

                    #endregion

                case FrequencyPatternType.Monthly:

                    #region GetNextDate for Monthly pattern

                    DateTime nextMonth;

                    switch (fpMonthlyPatternVariant)
                    {
                        case MonthlyPatternVariant.NumberOfMonths:
                            {
                                return dateTime.AddMonths(fp.MonPatMonthsToRec.GetValueOrDefault(0));
                            }

                        case MonthlyPatternVariant.DayByDate:
                            {
                                var currentDayOfMonth = dateTime.Day;
                                var recurDate = fp.MonPatRecurDate >
                                                DateTime.DaysInMonth(dateTime.Year, dateTime.Month)
                                                    ? DateTime.DaysInMonth(dateTime.Year, dateTime.Month)
                                                    : fp.MonPatRecurDate;

                                if (recurDate > currentDayOfMonth)
                                {
                                    return dateTime.AddDays((double)(recurDate - currentDayOfMonth));
                                }

                                nextMonth = dateTime.AddMonths(fp.MonPatByDateOptionMonthsToRec.GetValueOrDefault(0));
                                return new DateTime(nextMonth.Year, nextMonth.Month, (fp.MonPatRecurDate.GetValueOrDefault(0) > DateTime.DaysInMonth(nextMonth.Year, nextMonth.Month)
                                                                                          ? DateTime.DaysInMonth(nextMonth.Year, nextMonth.Month)
                                                                                          : fp.MonPatRecurDate.GetValueOrDefault(0)));
                            }
                        case MonthlyPatternVariant.DayByPosition:
                            nextMonth = dateTime.AddMonths(fp.MonPatByPositionOptionMonToRec.GetValueOrDefault(0));

                            var basicDates = new List<object>
                                                 {
                                                     new {
                                                             basicDate = nextMonth,
                                                             firstDay = new DateTime(nextMonth.Year, nextMonth.Month, 1),
                                                             lastDay = new DateTime(nextMonth.Year, nextMonth.Month, DateTime.DaysInMonth(nextMonth.Year, nextMonth.Month))
                                                         },
                                                         /* dateTime here is either Schedule based on or field to display schedule date. Fallback? */
                                                     new {
                                                             basicDate = dateTime,
                                                             firstDay = new DateTime(dateTime.Year, dateTime.Month, 1),
                                                             lastDay = new DateTime(dateTime.Year, dateTime.Month, DateTime.DaysInMonth(dateTime.Year, dateTime.Month))
                                                         }
                                                 };
                            foreach (var bd in basicDates)
                            {
                                DateTime testDate;

                                var basicDate = (DateTime)bd.GetType().GetProperty("basicDate").GetValue(bd, null);
                                var firstDay = (DateTime)bd.GetType().GetProperty("firstDay").GetValue(bd, null);
                                var lastDay = (DateTime)bd.GetType().GetProperty("lastDay").GetValue(bd, null);

                                if (fp.MonPatTimeIntervalPosition != TimeIntervalPosition.Last.ToString())
                                {

                                    if (fpMonthlyPatternDayOfWeek > firstDay.DayOfWeek)
                                    {
                                        testDate = new DateTime(basicDate.Year, basicDate.Month, 1 +
                                                                (fpMonthlyPatternDayOfWeek - firstDay.DayOfWeek +
                                                                 7 * (int)fpMonthlyPatternTimeIntervalPosition));
                                    }
                                    else if (fpMonthlyPatternDayOfWeek < firstDay.DayOfWeek)
                                    {
                                        testDate = new DateTime(basicDate.Year, basicDate.Month, 1 +
                                                                (7 - (firstDay.DayOfWeek - fpMonthlyPatternDayOfWeek) +
                                                                 7 * (int)fpMonthlyPatternTimeIntervalPosition));
                                    }
                                    else
                                    {
                                        testDate = new DateTime(basicDate.Year, basicDate.Month, 1 + 7 * (int)fpMonthlyPatternTimeIntervalPosition);
                                    }
                                }
                                else
                                {
                                    if (fpMonthlyPatternDayOfWeek < lastDay.DayOfWeek)
                                    {
                                        testDate = new DateTime(basicDate.Year, basicDate.Month, lastDay.Day -
                                                                (lastDay.DayOfWeek - fpMonthlyPatternDayOfWeek));
                                    }
                                    else if (fpMonthlyPatternDayOfWeek > lastDay.DayOfWeek)
                                    {
                                        testDate = new DateTime(basicDate.Year, basicDate.Month, lastDay.Day -
                                                                (7 - (fpMonthlyPatternDayOfWeek - lastDay.DayOfWeek)));
                                    }
                                    else
                                    {
                                        testDate = new DateTime(basicDate.Year, basicDate.Month, lastDay.Day);
                                    }
                                }

                                if (testDate > dateTime)
                                    return testDate;
                            }
                            break;
                    }

	                #endregion
                    break;
                case FrequencyPatternType.Yearly:

                    #region GetNextDate for Yearly pattern

                    if (fpRecurYearlyOption == RecurYearlyOption.RecurYearly)
                    {
                        dateTime = dateTime.AddYears(fp.YearPatYearsToRec.GetValueOrDefault(0));
                        break;
                    }

                    switch (fpYearlyPatternVariant)
                    {
                        case YearlyPatternVariant.DayByDate:
                            var withinTheSameYear = new DateTime(dateTime.Year,
                                                                 DateTime.ParseExact(
                                                                     fp.YearPatByDateOptionSelectMon, "MMMM",
                                                                     new CultureInfo(Constants.DefaultCultureName)).Month, fp.YearPatDayOfSelectMon.GetValueOrDefault(0));
                            if (dateTime < withinTheSameYear)
                                return withinTheSameYear;

                            return new DateTime(dateTime.AddYears(fp.YearPatYearsToRec.GetValueOrDefault(0)).Year,
                                                DateTime.ParseExact(
                                                    fp.YearPatByDateOptionSelectMon, "MMMM",
                                                    new CultureInfo(Constants.DefaultCultureName)).Month, fp.YearPatDayOfSelectMon.GetValueOrDefault(0));

                        case YearlyPatternVariant.DayByName:
                            var nextYear = dateTime.AddYears(fp.YearPatYearsToRec.GetValueOrDefault(0));
                            var selectedMonth = DateTime.ParseExact(fp.YearPatByNameOptionSelectMon, "MMMM",
                                                                                        new CultureInfo(Constants.DefaultCultureName)).Month;

                            var basicDates = new List<object>
                                                 {
                                                     new {
                                                             basicDate = dateTime,
                                                             firstDay = new DateTime(dateTime.Year, selectedMonth, 1),
                                                             lastDay = new DateTime(dateTime.Year, selectedMonth,
                                                                                    DateTime.DaysInMonth(dateTime.Year, selectedMonth))
                                                         },
                                                     new {
                                                             basicDate = nextYear,
                                                             firstDay = new DateTime(nextYear.Year, selectedMonth, 1),
                                                             lastDay = new DateTime(nextYear.Year, selectedMonth,
                                                                                    DateTime.DaysInMonth(nextYear.Year, selectedMonth))
                                                         }
                                                 };
                            foreach (var bd in basicDates)
                            {
                                DateTime testDate;

                                var basicDate = (DateTime)bd.GetType().GetProperty("basicDate").GetValue(bd, null);
                                var firstDay = (DateTime)bd.GetType().GetProperty("firstDay").GetValue(bd, null);
                                var lastDay = (DateTime)bd.GetType().GetProperty("lastDay").GetValue(bd, null);

                                if (fp.YearPatTimeIntervalPosition != TimeIntervalPosition.Last.ToString())
                                {

                                    if (fpYearlyPatternDayOfWeek > firstDay.DayOfWeek)
                                    {
                                        testDate = new DateTime(basicDate.Year, firstDay.Month, 1 +
                                                                (fpYearlyPatternDayOfWeek - firstDay.DayOfWeek +
                                                                 7 * (int)fpYearlyPatternTimeIntervalPosition));
                                    }
                                    else if (fpYearlyPatternDayOfWeek < firstDay.DayOfWeek)
                                    {
                                        testDate = new DateTime(basicDate.Year, firstDay.Month, 1 +
                                                                (7 - (firstDay.DayOfWeek - fpYearlyPatternDayOfWeek) +
                                                                 7 * (int)fpYearlyPatternTimeIntervalPosition));
                                    }
                                    else
                                    {
                                        testDate = new DateTime(basicDate.Year, firstDay.Month, 1 + 7 * (int)fpYearlyPatternTimeIntervalPosition);
                                    }
                                }
                                else
                                {
                                    if (fpYearlyPatternDayOfWeek < lastDay.DayOfWeek)
                                    {
                                        testDate = new DateTime(basicDate.Year, firstDay.Month, lastDay.Day -
                                                                (lastDay.DayOfWeek - fpYearlyPatternDayOfWeek));
                                    }
                                    else if (fpYearlyPatternDayOfWeek > lastDay.DayOfWeek)
                                    {
                                        testDate = new DateTime(basicDate.Year, firstDay.Month, lastDay.Day -
                                                                (7 - (fpYearlyPatternDayOfWeek - lastDay.DayOfWeek)));
                                    }
                                    else
                                    {
                                        testDate = new DateTime(basicDate.Year, firstDay.Month, lastDay.Day);
                                    }
                                }

                                if (testDate > dateTime)
                                    return testDate;
                            }
                            break;
                    }

                    #endregion                    
                    break;
            }
            return dateTime;
        }