private static void CalcRunDatesWeekly(Schedule schedule, ScheduleDet occurrence)
        {
            DateTime?nextRunDateL   = schedule.NextRunDate;
            DateTime?iteratorDate   = schedule.NextRunDate;
            DateTime?scheduledDateL = null;

            do
            {
                DayOfWeek dayOfWeek = ((DateTime)iteratorDate).DayOfWeek;

                if (schedule.WeeklyOnDay1 == true && dayOfWeek == DayOfWeek.Sunday ||
                    schedule.WeeklyOnDay2 == true && dayOfWeek == DayOfWeek.Monday ||
                    schedule.WeeklyOnDay3 == true && dayOfWeek == DayOfWeek.Tuesday ||
                    schedule.WeeklyOnDay4 == true && dayOfWeek == DayOfWeek.Wednesday ||
                    schedule.WeeklyOnDay5 == true && dayOfWeek == DayOfWeek.Thursday ||
                    schedule.WeeklyOnDay6 == true && dayOfWeek == DayOfWeek.Friday)
                {
                    if (scheduledDateL == null)
                    {
                        scheduledDateL = iteratorDate;
                    }
                    else
                    {
                        nextRunDateL = iteratorDate;
                    }
                }
                else if (dayOfWeek == DayOfWeek.Saturday)
                {
                    if (schedule.WeeklyOnDay7 == true)
                    {
                        if (scheduledDateL == null)
                        {
                            scheduledDateL = iteratorDate;
                        }
                        else
                        {
                            nextRunDateL = iteratorDate;
                        }
                    }
                    if (nextRunDateL == schedule.NextRunDate)
                    {
                        iteratorDate = ((DateTime)iteratorDate).AddDays(7 * ((short)schedule.WeeklyFrequency - 1) + 1);
                        continue;
                    }
                }
                iteratorDate = ((DateTime)iteratorDate).AddDays(1);
            }while (nextRunDateL == schedule.NextRunDate);

            schedule.NextRunDate     = nextRunDateL;
            occurrence.ScheduledDate = scheduledDateL;
        }
        private static void CalcRunDatesWeekly(Schedule s, ScheduleDet d)
        {
            DateTime?nextRunDateL = s.NextRunDate, iteratorDate = s.NextRunDate;
            DateTime?scheduledDateL = null;

            do
            {
                DayOfWeek dow = ((DateTime)iteratorDate).DayOfWeek;
                if ((bool)s.WeeklyOnDay1 && dow == DayOfWeek.Sunday ||
                    (bool)s.WeeklyOnDay2 && dow == DayOfWeek.Monday ||
                    (bool)s.WeeklyOnDay3 && dow == DayOfWeek.Tuesday ||
                    (bool)s.WeeklyOnDay4 && dow == DayOfWeek.Wednesday ||
                    (bool)s.WeeklyOnDay5 && dow == DayOfWeek.Thursday ||
                    (bool)s.WeeklyOnDay6 && dow == DayOfWeek.Friday)
                {
                    if (scheduledDateL == null)
                    {
                        scheduledDateL = iteratorDate;
                    }
                    else
                    {
                        nextRunDateL = iteratorDate;
                    }
                }
                else if (dow == DayOfWeek.Saturday)
                {
                    if ((bool)s.WeeklyOnDay7)
                    {
                        if (scheduledDateL == null)
                        {
                            scheduledDateL = iteratorDate;
                        }
                        else
                        {
                            nextRunDateL = iteratorDate;
                        }
                    }
                    if (nextRunDateL == s.NextRunDate)
                    {
                        iteratorDate = ((DateTime)iteratorDate).AddDays(7 * ((short)s.WeeklyFrequency - 1) + 1);
                        continue;
                    }
                }
                iteratorDate = ((DateTime)iteratorDate).AddDays(1);
            } while (nextRunDateL == s.NextRunDate);
            s.NextRunDate   = nextRunDateL;
            d.ScheduledDate = scheduledDateL;
        }
        public static List <ScheduleDet> MakeSchedule(PXGraph graph, Schedule s, short Times, DateTime runDate)
        {
            List <ScheduleDet> ret = new List <ScheduleDet>();

            if (s.NextRunDate == null && s.LastRunDate == null)
            {
                s.NextRunDate = s.StartDate;
            }
            else if (s.NextRunDate == null)
            {
                s.NextRunDate = s.LastRunDate;
            }

            int   i          = 0;
            short oldRunCntr = s.RunCntr ?? 0;

            do
            {
                ScheduleDet d = new ScheduleDet();
                do
                {
                    switch (s.ScheduleType)
                    {
                    case "D":
                        d.ScheduledDate = s.NextRunDate;
                        s.NextRunDate   = ((DateTime)s.NextRunDate).AddDays((short)s.DailyFrequency);
                        break;

                    case "W":
                        CalcRunDatesWeekly(s, d);
                        break;

                    case "P":
                        try
                        {
                            switch (s.PeriodDateSel)
                            {
                            case "S":
                                d.ScheduledDate = FinPeriodIDAttribute.PeriodStartDate(graph, FinPeriodIDAttribute.PeriodFromDate(graph, s.NextRunDate));
                                s.NextRunDate   = FinPeriodIDAttribute.PeriodStartDate(graph, FinPeriodIDAttribute.PeriodPlusPeriod(graph, FinPeriodIDAttribute.PeriodFromDate(graph, s.NextRunDate), (short)s.PeriodFrequency));
                                break;

                            case "E":
                                d.ScheduledDate = FinPeriodIDAttribute.PeriodEndDate(graph, FinPeriodIDAttribute.PeriodFromDate(graph, s.NextRunDate));
                                s.NextRunDate   = FinPeriodIDAttribute.PeriodEndDate(graph, FinPeriodIDAttribute.PeriodPlusPeriod(graph, FinPeriodIDAttribute.PeriodFromDate(graph, s.NextRunDate), (short)s.PeriodFrequency));
                                break;

                            case "D":
                                d.ScheduledDate = FinPeriodIDAttribute.PeriodStartDate(graph, FinPeriodIDAttribute.PeriodFromDate(graph, s.NextRunDate)).AddDays((short)s.PeriodFixedDay - 1);
                                if (((DateTime)d.ScheduledDate).CompareTo(FinPeriodIDAttribute.PeriodEndDate(graph, FinPeriodIDAttribute.PeriodFromDate(graph, s.NextRunDate))) > 0)
                                {
                                    d.ScheduledDate = FinPeriodIDAttribute.PeriodEndDate(graph, FinPeriodIDAttribute.PeriodFromDate(graph, s.NextRunDate));
                                }

                                DateTime?OldNextRunDate = s.NextRunDate;
                                s.NextRunDate = FinPeriodIDAttribute.PeriodStartDate(graph, FinPeriodIDAttribute.PeriodPlusPeriod(graph, FinPeriodIDAttribute.PeriodFromDate(graph, s.NextRunDate), (short)s.PeriodFrequency)).AddDays((short)s.PeriodFixedDay - 1);
                                if (((DateTime)s.NextRunDate).CompareTo(FinPeriodIDAttribute.PeriodEndDate(graph, FinPeriodIDAttribute.PeriodPlusPeriod(graph, FinPeriodIDAttribute.PeriodFromDate(graph, OldNextRunDate), (short)s.PeriodFrequency))) > 0)
                                {
                                    s.NextRunDate = FinPeriodIDAttribute.PeriodEndDate(graph, FinPeriodIDAttribute.PeriodPlusPeriod(graph, FinPeriodIDAttribute.PeriodFromDate(graph, OldNextRunDate), (short)s.PeriodFrequency));
                                }
                                break;
                            }
                        }
                        catch (PXFinPeriodException)
                        {
                            if (d.ScheduledDate != null && (bool)s.NoRunLimit == false && s.RunCntr + 1 == s.RunLimit)
                            {
                                s.NextRunDate = null;
                            }
                            else
                            {
                                s.RunCntr = oldRunCntr;
                                throw;
                            }
                        }
                        break;

                    case "M":
                        switch (s.MonthlyDaySel)
                        {
                        case "D":
                            d.ScheduledDate = new PXDateTime((short)((DateTime)s.NextRunDate).Year, (short)((DateTime)s.NextRunDate).Month, (short)s.MonthlyOnDay);
                            s.NextRunDate   = PXDateTime.DatePlusMonthSetDay((DateTime)d.ScheduledDate, (short)s.MonthlyFrequency, (short)s.MonthlyOnDay);
                            break;

                        case "W":
                            d.ScheduledDate = PXDateTime.MakeDayOfWeek((short)((DateTime)s.NextRunDate).Year, (short)((DateTime)s.NextRunDate).Month, (short)s.MonthlyOnWeek, (short)s.MonthlyOnDayOfWeek);

                            //s.NextRunDate = ((DateTime)d.ScheduledDate).AddMonths((short)s.MonthlyFrequency);
                            s.NextRunDate = new PXDateTime(((DateTime)d.ScheduledDate).Year, ((DateTime)d.ScheduledDate).Month, 1).AddMonths((short)s.MonthlyFrequency);
                            s.NextRunDate = PXDateTime.MakeDayOfWeek((short)((DateTime)s.NextRunDate).Year, (short)((DateTime)s.NextRunDate).Month, (short)s.MonthlyOnWeek, (short)s.MonthlyOnDayOfWeek);
                            break;
                        }
                        break;

                    default:
                        throw new PXException();
                    }
                } while (d.ScheduledDate == s.LastRunDate);

                if (d.ScheduledDate != null &&
                    ((DateTime)d.ScheduledDate).CompareTo(s.StartDate) >= 0 &&
                    ((bool)s.NoEndDate || ((DateTime)d.ScheduledDate).CompareTo(s.EndDate) <= 0) &&
                    (((DateTime)d.ScheduledDate).CompareTo(runDate) <= 0) &&
                    ((bool)s.NoRunLimit || s.RunCntr < s.RunLimit))
                {
                    try
                    {
                        d.ScheduledPeriod = FinPeriodIDAttribute.PeriodFromDate(graph, d.ScheduledDate);
                    }
                    catch
                    {
                        s.RunCntr = oldRunCntr;
                        throw;
                    }
                    ret.Add(d);
                    s.RunCntr++;

                    if ((bool)s.NoRunLimit == false && s.RunCntr >= s.RunLimit ||
                        (s.NextRunDate != null) && (bool)s.NoEndDate == false && ((DateTime)s.NextRunDate).CompareTo(s.EndDate) > 0)
                    {
                        s.Active      = false;
                        s.NextRunDate = null;
                    }

                    if (s.NextRunDate == null)
                    {
                        break;
                    }

                    if (++i >= Times)
                    {
                        return(ret);
                    }
                }
                else
                {
                    if (d.ScheduledDate != null)
                    {
                        s.NextRunDate = d.ScheduledDate;
                    }
                    break;
                }
            } while (true);

            return(ret);
        }
        public virtual IEnumerable <ScheduleDet> MakeSchedule(
            Schedule scheduleParameters,
            short numberOccurrences,
            DateTime?runDate = null)
        {
            runDate = runDate ?? _graph.Accessinfo.BusinessDate;

            List <ScheduleDet> scheduleOccurrences = new List <ScheduleDet>();

            if (scheduleParameters.NextRunDate == null && scheduleParameters.LastRunDate == null)
            {
                scheduleParameters.NextRunDate = scheduleParameters.StartDate;
            }
            else if (scheduleParameters.NextRunDate == null)
            {
                scheduleParameters.NextRunDate = scheduleParameters.LastRunDate;
            }

            int   occurrencesCreated = 0;
            short oldRunCounter      = scheduleParameters.RunCntr ?? 0;

            do
            {
                ScheduleDet occurrence = new ScheduleDet();
                do
                {
                    switch (scheduleParameters.ScheduleType)
                    {
                    case GLScheduleType.Daily:
                        occurrence.ScheduledDate       = scheduleParameters.NextRunDate;
                        scheduleParameters.NextRunDate = ((DateTime)scheduleParameters.NextRunDate).AddDays((short)scheduleParameters.DailyFrequency);
                        break;

                    case GLScheduleType.Weekly:
                        CalcRunDatesWeekly(scheduleParameters, occurrence);
                        break;

                    case GLScheduleType.Periodically:
                        try
                        {
                            switch (scheduleParameters.PeriodDateSel)
                            {
                            case PeriodDateSelOption.PeriodStart:
                                occurrence.ScheduledDate       = _financialPeriodProvider.PeriodStartDate(_graph, _financialPeriodProvider.PeriodFromDate(_graph, scheduleParameters.NextRunDate));
                                scheduleParameters.NextRunDate = _financialPeriodProvider.PeriodStartDate(_graph, _financialPeriodProvider.PeriodPlusPeriod(_graph, _financialPeriodProvider.PeriodFromDate(_graph, scheduleParameters.NextRunDate), (short)scheduleParameters.PeriodFrequency));
                                break;

                            case PeriodDateSelOption.PeriodEnd:
                                occurrence.ScheduledDate       = _financialPeriodProvider.PeriodEndDate(_graph, _financialPeriodProvider.PeriodFromDate(_graph, scheduleParameters.NextRunDate));
                                scheduleParameters.NextRunDate = _financialPeriodProvider.PeriodEndDate(_graph, _financialPeriodProvider.PeriodPlusPeriod(_graph, _financialPeriodProvider.PeriodFromDate(_graph, scheduleParameters.NextRunDate), (short)scheduleParameters.PeriodFrequency));
                                break;

                            case PeriodDateSelOption.PeriodFixedDate:
                                occurrence.ScheduledDate = _financialPeriodProvider.PeriodStartDate(_graph, _financialPeriodProvider.PeriodFromDate(_graph, scheduleParameters.NextRunDate)).AddDays((short)scheduleParameters.PeriodFixedDay - 1);
                                if (((DateTime)occurrence.ScheduledDate).CompareTo(_financialPeriodProvider.PeriodEndDate(_graph, _financialPeriodProvider.PeriodFromDate(_graph, scheduleParameters.NextRunDate))) > 0)
                                {
                                    occurrence.ScheduledDate = _financialPeriodProvider.PeriodEndDate(_graph, _financialPeriodProvider.PeriodFromDate(_graph, scheduleParameters.NextRunDate));
                                }

                                DateTime?OldNextRunDate = scheduleParameters.NextRunDate;
                                scheduleParameters.NextRunDate = _financialPeriodProvider.PeriodStartDate(_graph, _financialPeriodProvider.PeriodPlusPeriod(_graph, _financialPeriodProvider.PeriodFromDate(_graph, scheduleParameters.NextRunDate), (short)scheduleParameters.PeriodFrequency)).AddDays((short)scheduleParameters.PeriodFixedDay - 1);
                                if (((DateTime)scheduleParameters.NextRunDate).CompareTo(_financialPeriodProvider.PeriodEndDate(_graph, _financialPeriodProvider.PeriodPlusPeriod(_graph, _financialPeriodProvider.PeriodFromDate(_graph, OldNextRunDate), (short)scheduleParameters.PeriodFrequency))) > 0)
                                {
                                    scheduleParameters.NextRunDate = _financialPeriodProvider.PeriodEndDate(_graph, _financialPeriodProvider.PeriodPlusPeriod(_graph, _financialPeriodProvider.PeriodFromDate(_graph, OldNextRunDate), (short)scheduleParameters.PeriodFrequency));
                                }
                                break;
                            }
                        }
                        catch (PXFinPeriodException financialPeriodException)
                        {
                            if (occurrence.ScheduledDate != null &&
                                (bool)scheduleParameters.NoRunLimit == false &&
                                scheduleParameters.RunCntr + 1 == scheduleParameters.RunLimit &&
                                scheduleParameters.NextRunDate != null)
                            {
                                scheduleParameters.NextRunDate = null;
                            }
                            else
                            {
                                scheduleParameters.RunCntr = oldRunCounter;
                                throw new PXFinPeriodException(
                                          financialPeriodException,
                                          Messages.NoFinancialPeriodForNextExecutionDate);
                            }
                        }
                        break;

                    case GLScheduleType.Monthly:
                        switch (scheduleParameters.MonthlyDaySel)
                        {
                        case "D":
                            occurrence.ScheduledDate       = new PXDateTime((short)((DateTime)scheduleParameters.NextRunDate).Year, (short)((DateTime)scheduleParameters.NextRunDate).Month, (short)scheduleParameters.MonthlyOnDay);
                            scheduleParameters.NextRunDate = PXDateTime.DatePlusMonthSetDay((DateTime)occurrence.ScheduledDate, (short)scheduleParameters.MonthlyFrequency, (short)scheduleParameters.MonthlyOnDay);
                            break;

                        case "W":
                            occurrence.ScheduledDate = PXDateTime.MakeDayOfWeek((short)((DateTime)scheduleParameters.NextRunDate).Year, (short)((DateTime)scheduleParameters.NextRunDate).Month, (short)scheduleParameters.MonthlyOnWeek, (short)scheduleParameters.MonthlyOnDayOfWeek);

                            scheduleParameters.NextRunDate = new PXDateTime(((DateTime)occurrence.ScheduledDate).Year, ((DateTime)occurrence.ScheduledDate).Month, 1).AddMonths((short)scheduleParameters.MonthlyFrequency);
                            scheduleParameters.NextRunDate = PXDateTime.MakeDayOfWeek((short)((DateTime)scheduleParameters.NextRunDate).Year, (short)((DateTime)scheduleParameters.NextRunDate).Month, (short)scheduleParameters.MonthlyOnWeek, (short)scheduleParameters.MonthlyOnDayOfWeek);
                            break;
                        }
                        break;

                    default:
                        throw new PXException();
                    }
                } while (occurrence.ScheduledDate == scheduleParameters.LastRunDate);

                if (occurrence.ScheduledDate != null &&
                    ((DateTime)occurrence.ScheduledDate).CompareTo(scheduleParameters.StartDate) >= 0 &&
                    ((bool)scheduleParameters.NoEndDate || ((DateTime)occurrence.ScheduledDate).CompareTo(scheduleParameters.EndDate) <= 0) &&
                    (((DateTime)occurrence.ScheduledDate).CompareTo(runDate) <= 0) &&
                    ((bool)scheduleParameters.NoRunLimit || scheduleParameters.RunCntr < scheduleParameters.RunLimit))
                {
                    try
                    {
                        occurrence.ScheduledPeriod = _financialPeriodProvider.PeriodFromDate(_graph, occurrence.ScheduledDate);
                    }
                    catch (PXFinPeriodException financialPeriodException)
                    {
                        scheduleParameters.RunCntr = oldRunCounter;
                        throw new PXFinPeriodException(
                                  financialPeriodException,
                                  Messages.NoFinancialPeriodForNextExecutionDate);
                    }

                    scheduleOccurrences.Add(occurrence);
                    scheduleParameters.RunCntr++;

                    if ((bool)scheduleParameters.NoRunLimit == false && scheduleParameters.RunCntr >= scheduleParameters.RunLimit ||
                        (scheduleParameters.NextRunDate != null) && (bool)scheduleParameters.NoEndDate == false && ((DateTime)scheduleParameters.NextRunDate).CompareTo(scheduleParameters.EndDate) > 0)
                    {
                        scheduleParameters.Active      = false;
                        scheduleParameters.NextRunDate = null;
                    }

                    if (scheduleParameters.NextRunDate == null)
                    {
                        break;
                    }

                    if (++occurrencesCreated >= numberOccurrences)
                    {
                        return(scheduleOccurrences);
                    }
                }
                else
                {
                    if (((DateTime)occurrence.ScheduledDate).CompareTo(scheduleParameters.StartDate) < 0)
                    {
                        continue;
                    }
                    if (occurrence.ScheduledDate != null)
                    {
                        scheduleParameters.NextRunDate = occurrence.ScheduledDate;
                    }
                    break;
                }
            } while (true);

            return(scheduleOccurrences);
        }