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); }
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); }