コード例 #1
0
ファイル: ScheduleManager.cs プロジェクト: mparsin/Elements
        /// <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
ファイル: ScheduleManager.cs プロジェクト: mparsin/Elements
        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;
        }
コード例 #3
0
ファイル: ScheduleManager.cs プロジェクト: mparsin/Elements
        /// <summary>
        /// Calculates the next date.
        /// </summary>
        /// <param name="dateTime">The date time.</param>
        /// <param name="fp">The fp.</param>
        /// <param name="calendar">The calendar.</param>
        /// <returns>DateTime.</returns>
        private static DateTime CalculateNextDate(DateTime dateTime, IFrequencyPattern fp, ICalendar calendar)
        {
            var nextdate = GetNextDate(dateTime, fp, calendar);

            var nextDateTime = GetTime(nextdate, calendar);

            return nextDateTime ?? nextdate;
        }
コード例 #4
0
ファイル: ScheduleManager.cs プロジェクト: mparsin/Elements
        /// <summary>
        /// Calculates the and save.
        /// </summary>
        /// <param name="nextdate">The next date.</param>
        /// <param name="info">The information.</param>
        /// <param name="scheduleEdit">The schedule edit.</param>
        /// <param name="fp">The fp.</param>
        /// <param name="calendar">The calendar.</param>
        /// <exception cref="Cebos.Veyron.SharedTypes.VeyronException"></exception>
        private static void CalculateAndSave(ref DateTime nextdate, IInfoClass info, ISupportScheduling scheduleEdit, IFrequencyPattern fp, ICalendar calendar)
        {
            var edit = info == null
                           ? TheDynamicTypeManager.NewEditableRoot<ISupportScheduling>(scheduleEdit.ProcessName)
                           : TheDynamicTypeManager.GetEditableRoot<ISupportScheduling>(scheduleEdit.ProcessName, info.Id);

            if (!edit.IsNew && scheduleEdit.SchedulingSeriesItemNumber > edit.SchedulingSeriesItemNumber)
                return;

            scheduleEdit.CopyScheduledPropertiesTo(edit);

            nextdate = CalculateNextDate(nextdate, fp, calendar);

            if (scheduleEdit.SchedulingEndOption == SchedulingEndOption.EndByDate.ToString() && nextdate > scheduleEdit.SchedulingEndByDate)
            {
                return;
            }

            edit.ScheduleDisplayDate = fp.PatternType.Equals(FrequencyPatternType.Daily.ToString()) ?
                nextdate :
                CheckAdjustWorkingExceptions(ref nextdate, calendar, fp);
            //duplicated due to exceptions, go to next frequency
            while ((_scheduledList.Contains(((DateTime)edit.ScheduleDisplayDate).Date) ||
                       _previousScheduleDate > ((DateTime)edit.ScheduleDisplayDate).Date) && calendar != null) 
            {
                nextdate = CalculateNextDate(nextdate, fp, calendar);

                if (scheduleEdit.SchedulingEndOption == SchedulingEndOption.EndByDate.ToString() && nextdate > scheduleEdit.SchedulingEndByDate)
                {
                    return;
                }
                edit.ScheduleDisplayDate = fp.PatternType.Equals(FrequencyPatternType.Daily.ToString()) ?
               nextdate :
               CheckAdjustWorkingExceptions(ref nextdate, calendar, fp);
            }
            _scheduledList.Add(((DateTime)edit.ScheduleDisplayDate).Date);
            _previousScheduleDate = ((DateTime)edit.ScheduleDisplayDate).Date;

            edit.SchedulingSeriesGuid = scheduleEdit.SchedulingSeriesGuid;
            edit.SchedulingEndOption = scheduleEdit.SchedulingEndOption;
            edit.SchedulingEndAfterOccurrences = scheduleEdit.SchedulingEndAfterOccurrences;
            edit.SchedulingEndAfterOccurrencesIndex = scheduleEdit.SchedulingEndAfterOccurrencesIndex;
            edit.SchedulingEndByDate = scheduleEdit.SchedulingEndByDate;
            edit.ScheduledItemsCount = scheduleEdit.ScheduledItemsCount;
            edit.SchedulingFrequencyPatternId = scheduleEdit.SchedulingFrequencyPatternId;
            edit.ProcessingScheduling = true;

            var businessBase = edit as BusinessBase;
            if (businessBase != null && !businessBase.IsValid)
            {
                var allValidationErrors = businessBase.BrokenRulesCollection.Select(x => string.IsNullOrEmpty(x.Description) ? x.RuleName : x.Description).ToList();

                var parent = edit.GetBaseEdit() as BusinessBase;
                if (parent != null && !parent.IsValid)
                    allValidationErrors.AddRange(parent.BrokenRulesCollection.Select(x => string.IsNullOrEmpty(x.Description) ? x.RuleName : x.Description).ToList());

                throw new VeyronException(string.Format(CultureInfo.InvariantCulture, "Scheduled process '{0}' is not valid and cannot be saved{1}{2}", edit.ProcessDisplayName, Environment.NewLine, string.Join(Environment.NewLine, allValidationErrors)));
            }

            var savedObject = (ISupportScheduling)((ISavable)edit).Save();

            scheduleEdit.CopyScheduledPropertiesAfterEditableRootWasSaved(savedObject);
        }
コード例 #5
0
ファイル: ScheduleManager.cs プロジェクト: mparsin/Elements
        /// <summary>
        /// Get a valid previous working day without exception.
        /// </summary>
        /// <param name="nextDate"></param>
        /// <param name="calendar"></param>
        /// <param name="fp"></param>
        /// <returns></returns>
        private static DateTime CheckAdjustPreviousWorkingExceptions(ref DateTime nextDate, ICalendar calendar, IFrequencyPattern fp)
        {
            DateTime scheduledDate;

            var workingIntervals = GetPreviousWorkingIntervals(out scheduledDate, nextDate, calendar);
            if (workingIntervals == null || !workingIntervals.Any())
                return nextDate;

            var exception = GetWorkingException(scheduledDate, calendar, workingIntervals);
            if (exception == null)
                return scheduledDate;

            var dayBeforeException = exception.StartDate == null ? scheduledDate : exception.StartDate.Value.AddDays(-1);

            return CheckAdjustPreviousWorkingExceptions(ref dayBeforeException, calendar, fp);
        }
コード例 #6
0
ファイル: ScheduleManager.cs プロジェクト: mparsin/Elements
        /// <summary>If there is a working exception, try to find available day on the same week.</summary>
        /// <param name="nextDate">Scheduled next date.</param>
        /// <param name="calendar">The calendar.</param>
        /// <param name="fp"></param>
        /// <returns>Scheduled next date adjusted for an exception.</returns>
        private static DateTime CheckAdjustWorkingExceptions(ref DateTime nextDate, ICalendar calendar, IFrequencyPattern fp)
        {
            DateTime scheduledDate;

            var workingIntervals = GetWorkingIntervals(out scheduledDate, nextDate, calendar);
            if (workingIntervals == null || !workingIntervals.Any())
                return nextDate;

            var exception = GetWorkingException(scheduledDate, calendar, workingIntervals);
            if (exception == null)
                return scheduledDate;

            ExceptionBehavior exceptionBehavior = ExceptionBehavior.ScheduleAfter;
            if (!string.IsNullOrEmpty(exception.ExceptionBehavior) && !Enum.TryParse(exception.ExceptionBehavior, out exceptionBehavior))
                exceptionBehavior = ExceptionBehavior.ScheduleAfter;

            switch (exceptionBehavior)
            {
                case ExceptionBehavior.Skip:
                    scheduledDate = nextDate = GetNextDate(scheduledDate, fp, calendar);
                    break;
                case ExceptionBehavior.ScheduleAfter:
                    scheduledDate = exception.FinishDate == null ? scheduledDate : exception.FinishDate.Value.AddDays(1);
                    GetWorkingIntervals(out scheduledDate, scheduledDate, calendar);
                    break;
                case ExceptionBehavior.ScheduleBefore:
                     var dayBeforeException = exception.StartDate == null ? scheduledDate : exception.StartDate.Value.AddDays(-1);
                     return CheckAdjustPreviousWorkingExceptions(ref dayBeforeException,calendar,fp);
            }

            return CheckAdjustWorkingExceptions(ref scheduledDate, calendar, fp);
        }