예제 #1
0
        public bool AddCycleEntry(DateTime dtEffectiveDate, ECALENDARCYCLE_CYCLETYPE eCycleType, short eFYEndMonth, ECALENDARCYCLE_DATEOFWEEK ePeriodDayOfWeek, ECALENDARCYCLE_YEARENDELECTION eYearEndElection, ECALENDARCYCLE_PDCOUNTING ePDCounting)
        {
            IBACycleObject   objCalCycle;
            BAFASCycleObject objNewCalCycle;
            int      posi, count, origCount;
            bool     hr;
            DateTime dtFYStart, dtFYEnd, dtDate;
            ECALENDARCYCLE_DATEOFWEEK      eTmpDateOfWeek;
            ECALENDARCYCLE_CYCLETYPE       eTmpCycleType;
            ECALENDARCYCLE_YEARENDELECTION eTmpYearEndElection;
            IBACycleObject            objPrevCalCycle;
            short                     eNumberOfYears, eYearNumberOffset, eTmpFYEndMonth;
            ECALENDARCYCLE_PDCOUNTING eTmpPDCounting;

            dtEffectiveDate = dtEffectiveDate.Date;
            if (eCycleType == ECALENDARCYCLE_CYCLETYPE.CYCLETYPE_MONTHLY)
            {
                eYearEndElection = ECALENDARCYCLE_YEARENDELECTION.YEARENDELECTION_LASTWEEKDAY;
                ePDCounting      = ECALENDARCYCLE_PDCOUNTING.PDCOUNT_BACKWARD;
            }

            ClearBuckets();

            if (m_FYList == null)
            {
                throw new Exception("Cycle list is uninitialized.");
            }

            count = m_FYList.Count;

            origCount = count;

            if (count > 0)
            {
                for (posi = count - 1; posi >= 0; --posi)
                {
                    objCalCycle = m_FYList[posi];
                    dtDate      = objCalCycle.EffectiveDate;


                    objCalCycle = null;

                    if (dtDate >= dtEffectiveDate.AddDays(-7))
                    {
                        --count;
                    }
                }

                if (count > 0)
                {
                    objCalCycle = m_FYList[count - 1];

                    if (objCalCycle == null)
                    {
                        throw new Exception("Invalid effective date.");
                    }

                    eTmpCycleType       = objCalCycle.CycleType;
                    eTmpFYEndMonth      = objCalCycle.FYEndMonth;
                    eTmpYearEndElection = objCalCycle.YearEndElect;
                    eTmpDateOfWeek      = objCalCycle.DateOfWeek;
                    eTmpPDCounting      = objCalCycle.PDCounting;

                    if (eTmpCycleType == eCycleType &&
                        eTmpDateOfWeek == ePeriodDayOfWeek &&
                        eTmpFYEndMonth == eFYEndMonth &&
                        eTmpYearEndElection == eYearEndElection &&
                        eTmpPDCounting == ePDCounting)
                    {
                        for (posi = origCount - 1; posi >= count; posi--)
                        {
                            m_FYList.RemoveAt(posi);
                        }
                        objCalCycle.EndDate = DateTime.MinValue;
                        return(true);
                    }

                    if (!(FiscalYearEndDate((dtEffectiveDate.AddDays(-1)).Year,
                                            eTmpCycleType,
                                            eTmpFYEndMonth,
                                            eTmpYearEndElection,
                                            eTmpDateOfWeek,
                                            out dtFYEnd)) ||
                        !(FiscalYearStartDate((dtEffectiveDate.AddDays(-1)).Year + 1,
                                              eCycleType,
                                              eTmpFYEndMonth,
                                              eYearEndElection,
                                              ePeriodDayOfWeek,
                                              out dtFYStart)))
                    {
                        return(false);
                    }

                    if (dtEffectiveDate != dtFYEnd && dtEffectiveDate != dtFYStart && dtEffectiveDate != dtFYEnd.AddDays(+1))
                    {
                        if ((dtEffectiveDate.Month) == 1 && (dtEffectiveDate.Day) < 7)
                        {
                            if (!(FiscalYearEndDate((dtEffectiveDate.AddDays(-7)).Year,
                                                    eTmpCycleType,
                                                    eTmpFYEndMonth,
                                                    eTmpYearEndElection,
                                                    eTmpDateOfWeek,
                                                    out dtFYEnd)) ||
                                !(FiscalYearStartDate((dtEffectiveDate.Year),
                                                      eCycleType,
                                                      eTmpFYEndMonth,
                                                      eYearEndElection,
                                                      ePeriodDayOfWeek,
                                                      out dtFYStart)))
                            {
                                return(false);
                            }
                        }
                        if (dtEffectiveDate != dtFYEnd && dtEffectiveDate != dtFYStart && dtEffectiveDate != dtFYEnd.AddDays(+1))
                        {
                            throw new Exception("Not a valid fiscal year end");
                        }
                    }
                }
                count = origCount;

                // remove use case 8.1b 4.2.a.1 calendar cycles
                for (posi = count - 1; posi >= 0; posi--)
                {
                    objCalCycle = null;
                    objCalCycle = m_FYList[posi];
                    dtDate      = objCalCycle.EffectiveDate;

                    objCalCycle = null;

                    if (dtDate >= dtEffectiveDate.AddDays(-7))
                    {
                        m_FYList.RemoveAt(posi);
                        --count;
                    }
                }
            }



            if (count <= 0)
            {
                if (dtEffectiveDate == DateTime.MinValue ||
                    eCycleType < ECALENDARCYCLE_CYCLETYPE.CYCLETYPE_MONTHLY ||
                    eCycleType > ECALENDARCYCLE_CYCLETYPE.CYCLETYPE_CUSTOM ||
                    eFYEndMonth < 0 ||
                    eFYEndMonth > 12 ||
                    ePeriodDayOfWeek < ECALENDARCYCLE_DATEOFWEEK.DATEOFWEEK_SUNDAY ||
                    ePeriodDayOfWeek > ECALENDARCYCLE_DATEOFWEEK.DATEOFWEEK_SATURDAY ||
                    eYearEndElection < ECALENDARCYCLE_YEARENDELECTION.YEARENDELECTION_LASTWEEKDAY ||
                    eYearEndElection > ECALENDARCYCLE_YEARENDELECTION.YEARENDELECTION_CLOSESTWEEKDAY)
                {
                    throw new Exception("Parameter out of range.");
                }

                objNewCalCycle = new BAFASCycleObject();
                objCalCycle    = objNewCalCycle;

                objCalCycle.EffectiveDate = (dtEffectiveDate);
                objCalCycle.CycleType     = (eCycleType);
                objCalCycle.DateOfWeek    = (ePeriodDayOfWeek);
                objCalCycle.FYEndMonth    = (eFYEndMonth);
                objCalCycle.YearEndElect  = (eYearEndElection);
                objCalCycle.PDCounting    = (ePDCounting);
            }
            else               // count > 0 (modify cycle)
            {
                // assign the CycleEndDate for the previous CBAFASCycleObject
                objCalCycle         = m_FYList[count - 1];
                objCalCycle.EndDate = dtEffectiveDate.AddDays(-1);

                objCalCycle = null;

                objNewCalCycle = new BAFASCycleObject();
                objCalCycle    = objNewCalCycle;

                objCalCycle.EffectiveDate = (dtEffectiveDate);
                objCalCycle.CycleType     = (eCycleType);
                objCalCycle.DateOfWeek    = (ePeriodDayOfWeek);
                objCalCycle.FYEndMonth    = (eFYEndMonth);
                objCalCycle.YearEndElect  = (eYearEndElection);
                objCalCycle.PDCounting    = (ePDCounting);


                objPrevCalCycle = m_FYList[count - 1];
                dtDate          = objPrevCalCycle.EffectiveDate;


                if (dtDate >= dtEffectiveDate)
                {
                    --count;
                    m_FYList.RemoveAt(count);
                }

                objPrevCalCycle = null;

                objPrevCalCycle = m_FYList[count - 1];

                eYearNumberOffset = objPrevCalCycle.YearNumberOffset;
                eNumberOfYears    = objPrevCalCycle.NumberOfYears;

                objPrevCalCycle = null;

                if (count >= 2)
                {
                    objCalCycle.YearNumberOffset = (short)(eYearNumberOffset + eNumberOfYears);
                }
                else if (count == 1)
                {
                    objCalCycle.YearNumberOffset = (eNumberOfYears);
                }
            }

            m_FYList.Add(objCalCycle);
            m_IsDirty = true;
            return(true);
        }
예제 #2
0
        protected bool CalcPeriod(out _PeriodInfo info, DateTime dtStartDate, DateTime dtEndDate, ECALENDARCYCLE_PDCOUNTING ePDCounting,
                                  ECALENDARCYCLE_CYCLETYPE eCycleType, short iPeriodNum, BAFASFiscalYear obj, short periodCount, bool bShortYear)
        {
            DateTime dtDate;
            short    iBegNumWeeks;
            short    iEndNumWeeks;
            short    iTmpPeriodNum    = 0;
            bool     bHas6WeeksPeriod = false;
            short    periodBias       = 0;

            dtStartDate = dtStartDate.Date;
            dtEndDate   = dtEndDate.Date;

            info = new _PeriodInfo();

            // make the start date for the calculation
            if (ePDCounting == ECALENDARCYCLE_PDCOUNTING.PDCOUNT_FORWARD)
            {
                // When change from monthly to AAP, a user has two days to select, the ME or LD/CD
                // If a user selects LD/CD, the DeemedDate(dtStartDate) will give the same date as the
                // dtStartDate, then use this date to layout all the periods
                // If a user selects ME, the dtDate = DeemedDate(dtStartDate) will give either
                // LD or CD, according to the SAI calc doc, for counting forward always use close day
                // if it is LD then move to CD
                //     |<- 6 days ->|< 3 >|
                //   --+------------+-----+---------------------------------
                //    LD           ME    CD
                //    LD --- the last week date
                //    ME --- the end of the month
                //    CD --- the closest week date

                dtDate = DeemedDate(dtStartDate, obj);
                if (Math.Abs((dtDate - dtStartDate).TotalDays) > 4)
                {
                    dtDate = dtDate.AddDays(+7);
                }
            }
            else if (ePDCounting == ECALENDARCYCLE_PDCOUNTING.PDCOUNT_BACKWARD)
            {
                // For this case, the dtEndDate is calculated according to the calendar cycle
                // parameters and could be either LD or CD.  To see if this fiscal year has a 6
                // week period, look backward from the dtEndDate - 366 - 3, one may have the previous
                // end of month
                // The EndOfMonth will give the month end date
                // The DeemedDate will give this fiscal year start date
                // then use this info to see if there is a 6 week period.
                //      |< 6 >|<--------------------------- 366 ------------------------------>| 3|
                //   ---+-----+--+--------------------------------------------------------+----+--+--->
                //     LD    ME  CD                                                      LD   ME  CD
                //     LD --- the last week date
                //     ME --- the end of the month
                //     CD --- the closest week date

                dtDate = DateTimeHelper.GetEndOfMonth(dtEndDate.AddDays(-Constants.MAXDAYCHANGE));
                dtDate = DeemedDate(dtDate, obj);
                if ((dtEndDate - dtDate).TotalDays >= Constants.FIFTYTHREEWEEKYEAR)
                {
                    bHas6WeeksPeriod = true;
                }
                dtDate        = DeemedDate(dtEndDate, obj);
                iTmpPeriodNum = (short)(periodCount - iPeriodNum + 1);
            }
            else
            {
                // For this case, we know it is a short year, the end date is calculated by
                // the calendar cycle parameters.  The start date is entered by the user and
                // can be located in either of the following locations (LD, ME, CD)
                //     |< 6 >|<----------------------- 365 ------------------------->| 3|
                //  ---+-----+--+----------------------------------------------+-----+--+---->
                //    LD    ME  CD                                            LD    ME CD
                //    LD --- the last week date
                //    ME --- the end of the month
                //    CD --- the closest week date
                // From the start date + 365 - 3, one may have the previous end of month
                // the EndOfMonth will give the month end date
                // the DeemedDate will give the date calculated by using the calendar
                // cycle parameters
                // dtDate is used as a base date to layout the periods
                // the dtStartDate - 3 will give a date between LD and CD
                // the DeemedDate(dtStartDate - 3) will give either LD or CD

                dtDate = DateTimeHelper.GetEndOfMonth(dtStartDate.AddDays(+Constants.MINDAYCHANGE));
                dtDate = DeemedDate(dtDate, obj);

                if ((dtDate - DeemedDate(dtStartDate.AddDays(-Constants.THREEDAYS), obj)).TotalDays >= Constants.FIFTYTHREEWEEKYEAR)
                {
                    bHas6WeeksPeriod = true;
                }
                if (eCycleType != ECALENDARCYCLE_CYCLETYPE.CYCLETYPE_THIRTEENPERIOD)
                {
                    iTmpPeriodNum = (short)(12 - iPeriodNum + 1);
                }
                else
                {
                    iTmpPeriodNum = (short)(13 - iPeriodNum + 1);
                }
            }

            if (ePDCounting == ECALENDARCYCLE_PDCOUNTING.PDCOUNT_FORWARD)
            {
                // Calculate the number of weeks from the base date
                if (eCycleType == ECALENDARCYCLE_CYCLETYPE.CYCLETYPE_FOURFOURFIVE)
                {
                    iBegNumWeeks = PeriodNumToWeekNum((short)(iPeriodNum - 1), ECALENDARCYCLE_CYCLETYPE.CYCLETYPE_FIVEFOURFOUR);
                    iEndNumWeeks = PeriodNumToWeekNum(iPeriodNum, ECALENDARCYCLE_CYCLETYPE.CYCLETYPE_FIVEFOURFOUR);
                }
                else if (eCycleType == ECALENDARCYCLE_CYCLETYPE.CYCLETYPE_FIVEFOURFOUR)
                {
                    iBegNumWeeks = PeriodNumToWeekNum((short)(iPeriodNum - 1), ECALENDARCYCLE_CYCLETYPE.CYCLETYPE_FOURFOURFIVE);
                    iEndNumWeeks = PeriodNumToWeekNum(iPeriodNum, ECALENDARCYCLE_CYCLETYPE.CYCLETYPE_FOURFOURFIVE);
                }
                else
                {
                    iBegNumWeeks = PeriodNumToWeekNum((short)(iPeriodNum - 1), eCycleType);
                    iEndNumWeeks = PeriodNumToWeekNum(iPeriodNum, eCycleType);
                }
                // Calculate the period start and end dates
                info.dtStartDate = dtDate.AddDays(+(iBegNumWeeks * 7 + 1));
                info.dtEndDate   = dtDate.AddDays(+(iEndNumWeeks * 7));
            }
            else if (ePDCounting == ECALENDARCYCLE_PDCOUNTING.PDCOUNT_BACKWARD)
            {
                // Calculate the number of weeks from the base date
                iBegNumWeeks = PeriodNumToWeekNum(iTmpPeriodNum, eCycleType);
                iEndNumWeeks = PeriodNumToWeekNum((short)(iTmpPeriodNum - 1), eCycleType);

                if (bHas6WeeksPeriod)
                {
                    // Because the formula is based on the regular 445/454/544 pattern
                    // if it has a 6 week period then
                    iBegNumWeeks++;
                    iEndNumWeeks++;
                }
                // Calculate the period start and end dates
                info.dtStartDate = dtDate.AddDays(-(iBegNumWeeks * 7 - 1));
                info.dtEndDate   = dtDate.AddDays(-iEndNumWeeks * 7);
            }
            else
            {
                // Calculate the number of weeks from the base date
                iBegNumWeeks = PeriodNumToWeekNum(iTmpPeriodNum, eCycleType);
                iEndNumWeeks = PeriodNumToWeekNum((short)(iTmpPeriodNum - 1), eCycleType);

                if (bHas6WeeksPeriod)
                {
                    // Because the formula is based on the regular 445/454/544 pattern
                    // it has a 6 week period then
                    iBegNumWeeks++;
                    iEndNumWeeks++;
                }
                // Calculate the period start and end dates
                info.dtStartDate = dtDate.AddDays(-(iBegNumWeeks * 7 - 1));
                info.dtEndDate   = dtDate.AddDays(-iEndNumWeeks * 7);
            }
            // Set other period information
            info.iPeriodNumber = iPeriodNum;
            info.IsIdle        = false;

            // Some fiscal years may have a few more days at the fiscal year start
            if (info.dtStartDate < dtStartDate || iPeriodNum == 1)
            {
                periodBias       = (short)((dtStartDate - info.dtStartDate).TotalDays / 7);
                info.dtStartDate = dtStartDate;
            }

            // Some fiscal years may have a few more days at the fiscal year end
            if (iPeriodNum == periodCount || info.dtEndDate > dtEndDate)
            {
                info.dtEndDate = dtEndDate;
            }

            info.iWeight = (short)(((info.dtEndDate - info.dtStartDate).TotalDays + 4) / 7);
            if (!bShortYear)
            {
                if (info.iWeight < 4)
                {
                    info.iWeight = (short)(4 - periodBias);
                }
            }
            if (info.iWeight > 5)
            {
                info.iWeight = 5;
            }
            else if (info.iWeight == 5 && eCycleType == ECALENDARCYCLE_CYCLETYPE.CYCLETYPE_THIRTEENPERIOD)
            {
                info.iWeight = 4;
            }
            else //if (info.iWeight == 5) // now check for 53 week falling on a 4 period
            {
                switch (ePDCounting)
                {
                case ECALENDARCYCLE_PDCOUNTING.PDCOUNT_FORWARD:
                    switch (eCycleType)
                    {
                    case ECALENDARCYCLE_CYCLETYPE.CYCLETYPE_FOURFOURFIVE:    // This is really 544
                        if (iPeriodNum % 3 != 1 && (info.iWeight > 4 || !bShortYear))
                        {
                            info.iWeight = 4;
                        }
                        else if (iPeriodNum % 3 == 1 && (info.iWeight > 5 || !bShortYear))
                        {
                            info.iWeight = 5;
                        }
                        break;

                    case ECALENDARCYCLE_CYCLETYPE.CYCLETYPE_FOURFIVEFOUR:
                        if (iPeriodNum % 3 != 2 && (info.iWeight > 4 || !bShortYear))
                        {
                            info.iWeight = 4;
                        }
                        else if (iPeriodNum % 3 == 2 && (info.iWeight > 5 || !bShortYear))
                        {
                            info.iWeight = 5;
                        }
                        break;

                    case ECALENDARCYCLE_CYCLETYPE.CYCLETYPE_FIVEFOURFOUR:    // This is really 445
                        if (iPeriodNum % 3 != 0 && (info.iWeight > 4 || !bShortYear))
                        {
                            info.iWeight = 4;
                        }
                        else if (iPeriodNum % 3 == 0 && (info.iWeight > 5 || !bShortYear))
                        {
                            info.iWeight = 5;
                        }
                        break;
                    }
                    break;

                case ECALENDARCYCLE_PDCOUNTING.PDCOUNT_BACKWARD:
                    switch (eCycleType)
                    {
                    case ECALENDARCYCLE_CYCLETYPE.CYCLETYPE_FOURFOURFIVE:    // This is really 544
                        if ((periodCount - iPeriodNum) % 3 != 2 && (info.iWeight > 4 || !bShortYear))
                        {
                            info.iWeight = 4;
                        }
                        else if ((periodCount - iPeriodNum) % 3 == 2 && (info.iWeight > 5 || !bShortYear))
                        {
                            info.iWeight = 5;
                        }
                        break;

                    case ECALENDARCYCLE_CYCLETYPE.CYCLETYPE_FOURFIVEFOUR:
                        if ((periodCount - iPeriodNum) % 3 != 1 && (info.iWeight > 4 || !bShortYear))
                        {
                            info.iWeight = 4;
                        }
                        else if ((periodCount - iPeriodNum) % 3 == 1 && (info.iWeight > 5 || !bShortYear))
                        {
                            info.iWeight = 5;
                        }
                        break;

                    case ECALENDARCYCLE_CYCLETYPE.CYCLETYPE_FIVEFOURFOUR:    // This is really 445
                        if ((periodCount - iPeriodNum) % 3 != 0 && (info.iWeight > 4 || !bShortYear))
                        {
                            info.iWeight = 4;
                        }
                        else if ((periodCount - iPeriodNum) % 3 == 0 && (info.iWeight > 5 || !bShortYear))
                        {
                            info.iWeight = 5;
                        }
                        break;
                    }
                    break;

                case ECALENDARCYCLE_PDCOUNTING.PDCOUNT_BACKWARD_OLDMONTH:
                    switch (eCycleType)
                    {
                    case ECALENDARCYCLE_CYCLETYPE.CYCLETYPE_FOURFOURFIVE:    // This is really 544
                        if ((13 - iTmpPeriodNum) % 3 != 1 && (info.iWeight > 4 || !bShortYear))
                        {
                            info.iWeight = 4;
                        }
                        else if ((13 - iTmpPeriodNum) % 3 == 1 && (info.iWeight > 5 || !bShortYear))
                        {
                            info.iWeight = 5;
                        }
                        break;

                    case ECALENDARCYCLE_CYCLETYPE.CYCLETYPE_FOURFIVEFOUR:
                        if ((13 - iTmpPeriodNum) % 3 != 2 && (info.iWeight > 4 || !bShortYear))
                        {
                            info.iWeight = 4;
                        }
                        else if ((13 - iTmpPeriodNum) % 3 == 2 && (info.iWeight > 5 || !bShortYear))
                        {
                            info.iWeight = 5;
                        }
                        break;

                    case ECALENDARCYCLE_CYCLETYPE.CYCLETYPE_FIVEFOURFOUR:    // This is really 445
                        if ((13 - iTmpPeriodNum) % 3 != 0 && (info.iWeight > 4 || !bShortYear))
                        {
                            info.iWeight = 4;
                        }
                        else if ((13 - iTmpPeriodNum) % 3 == 0 && (info.iWeight > 5 || !bShortYear))
                        {
                            info.iWeight = 5;
                        }
                        break;
                    }
                    break;
                }
            }

            if (info.dtEndDate > dtEndDate)
            {
                return(false);
            }
            return(true);
        }