public static LocalDate alignProposedBillCycleDate(final LocalDate proposedDate, final int billingCycleDay, final BillingPeriod billingPeriod) { // billingCycleDay alignment only makes sense for month based BillingPeriod (MONTHLY, QUARTERLY, BIANNUAL, ANNUAL) final boolean isMonthBased = (billingPeriod.getPeriod().getMonths() | billingPeriod.getPeriod().getYears()) > 0; if (!isMonthBased) { return proposedDate; } final int lastDayOfMonth = proposedDate.dayOfMonth().getMaximumValue(); int proposedBillCycleDate = proposedDate.getDayOfMonth(); if (proposedBillCycleDate < billingCycleDay) { if (billingCycleDay <= lastDayOfMonth) { proposedBillCycleDate = billingCycleDay; } else { proposedBillCycleDate = lastDayOfMonth; } } return new LocalDate(proposedDate.getYear(), proposedDate.getMonthOfYear(), proposedBillCycleDate, proposedDate.getChronology()); }
DateTime proposedDate = chargedThroughDate; while (proposedDate.isAfter(clock.getUTCNow())) { proposedDate = proposedDate.minus(billingPeriod.getPeriod());
public static LocalDate recedeByNPeriods(final LocalDate initialDate, final BillingPeriod billingPeriod, final int nbPeriods) { LocalDate proposedDate = initialDate; for (int i = 0; i < nbPeriods; i++) { proposedDate = proposedDate.minus(billingPeriod.getPeriod()); } return proposedDate; } }
public static LocalDate advanceByNPeriods(final LocalDate initialDate, final BillingPeriod billingPeriod, final int nbPeriods) { LocalDate proposedDate = initialDate; for (int i = 0; i < nbPeriods; i++) { proposedDate = proposedDate.plus(billingPeriod.getPeriod()); } return proposedDate; }
public LocalDate getNextBillingCycleDate() { final LocalDate proposedDate = lastBillingCycleDate != null ? lastBillingCycleDate.plus(billingPeriod.getPeriod()) : firstBillingCycleDate; final LocalDate nextBillingCycleDate = BillCycleDayCalculator.alignProposedBillCycleDate(proposedDate, billingCycleDay, billingPeriod); return nextBillingCycleDate; }
public static BigDecimal calculateProRationAfterLastBillingCycleDate(final LocalDate endDate, final LocalDate previousBillThroughDate, final BillingPeriod billingPeriod) { // Note: assumption is that previousBillThroughDate is correctly aligned with the billing cycle day final LocalDate nextBillThroughDate = previousBillThroughDate.plus(billingPeriod.getPeriod()); return calculateProrationBetweenDates(previousBillThroughDate, endDate, previousBillThroughDate, nextBillThroughDate); }
public static BigDecimal calculateProRationBeforeFirstBillingPeriod(final LocalDate startDate, final LocalDate nextBillingCycleDate, final BillingPeriod billingPeriod) { final LocalDate previousBillingCycleDate = nextBillingCycleDate.minus(billingPeriod.getPeriod()); return calculateProrationBetweenDates(startDate, nextBillingCycleDate, previousBillingCycleDate, nextBillingCycleDate); }
public static int calculateNumberOfWholeBillingPeriods(final LocalDate startDate, final LocalDate endDate, final BillingPeriod billingPeriod) { final int numberBetween; final int numberInPeriod; if (billingPeriod.getPeriod().getDays() != 0) { numberBetween = Days.daysBetween(startDate, endDate).getDays(); numberInPeriod = billingPeriod.getPeriod().getDays(); } else if (billingPeriod.getPeriod().getWeeks() != 0) { numberBetween = Weeks.weeksBetween(startDate, endDate).getWeeks(); numberInPeriod = billingPeriod.getPeriod().getWeeks(); } else if (billingPeriod.getPeriod().getMonths() != 0) { numberBetween = Months.monthsBetween(startDate, endDate).getMonths(); numberInPeriod = billingPeriod.getPeriod().getMonths(); } else { numberBetween = Years.yearsBetween(startDate, endDate).getYears(); numberInPeriod = billingPeriod.getPeriod().getYears(); } return numberBetween / numberInPeriod; }
public BillingIntervalDetail(final LocalDate startDate, final LocalDate endDate, final LocalDate targetDate, final int billingCycleDay, final BillingPeriod billingPeriod, final BillingMode billingMode) { this.startDate = startDate; this.endDate = endDate; this.targetDate = targetDate; if (billingPeriod.getPeriod().getMonths() != 0 || billingPeriod.getPeriod().getYears() != 0) { this.billingCycleDay = billingCycleDay; } else { this.billingCycleDay = startDate.getDayOfMonth(); } this.billingPeriod = billingPeriod; this.billingMode = billingMode; computeAll(); }
public static LocalDate alignProposedBillCycleDate(final LocalDate proposedDate, final int billingCycleDay, final BillingPeriod billingPeriod) { // billingCycleDay alignment only makes sense for month based BillingPeriod (MONTHLY, QUARTERLY, BIANNUAL, ANNUAL) final boolean isMonthBased = (billingPeriod.getPeriod().getMonths() | billingPeriod.getPeriod().getYears()) > 0; if (!isMonthBased) { return proposedDate; } final int lastDayOfMonth = proposedDate.dayOfMonth().getMaximumValue(); int proposedBillCycleDate = proposedDate.getDayOfMonth(); if (proposedBillCycleDate < billingCycleDay) { if (billingCycleDay <= lastDayOfMonth) { proposedBillCycleDate = billingCycleDay; } else { proposedBillCycleDate = lastDayOfMonth; } } return new LocalDate(proposedDate.getYear(), proposedDate.getMonthOfYear(), proposedBillCycleDate, proposedDate.getChronology()); }
private void calculateFirstBillingCycleDate() { final int lastDayOfMonth = startDate.dayOfMonth().getMaximumValue(); final LocalDate billingCycleDate; if (billingCycleDay > lastDayOfMonth) { billingCycleDate = new LocalDate(startDate.getYear(), startDate.getMonthOfYear(), lastDayOfMonth, startDate.getChronology()); } else { billingCycleDate = new LocalDate(startDate.getYear(), startDate.getMonthOfYear(), billingCycleDay, startDate.getChronology()); } LocalDate proposedDate = billingCycleDate; while (proposedDate.isBefore(startDate)) { proposedDate = proposedDate.plus(billingPeriod.getPeriod()); } firstBillingCycleDate = BillCycleDayCalculator.alignProposedBillCycleDate(proposedDate, billingCycleDay, billingPeriod); }
@Test(groups = "fast") public void testSinglePlan_ExactlyOnePeriodAfterStart() throws InvalidDateSequenceException { final LocalDate startDate = invoiceUtil.buildDate(2011, 2, 15); final LocalDate targetDate = startDate.plus(getBillingPeriod().getPeriod()); testCalculateNumberOfBillingCycles(startDate, targetDate, 15, TWO); }
@Test(groups = "fast") public void testSinglePlan_StartingMidFebruary() throws InvalidDateSequenceException { final LocalDate startDate = invoiceUtil.buildDate(2011, 2, 15); final LocalDate targetDate = startDate.plus(getBillingPeriod().getPeriod()); testCalculateNumberOfBillingCycles(startDate, targetDate, 15, TWO); }
@Test(groups = "fast") public void testSinglePlan_StartingMidFebruaryOfLeapYear() throws InvalidDateSequenceException { final LocalDate startDate = invoiceUtil.buildDate(2012, 2, 15); final LocalDate targetDate = startDate.plus(getBillingPeriod().getPeriod()); testCalculateNumberOfBillingCycles(startDate, targetDate, 15, TWO); }
DateTime proposedDate = chargedThroughDate; while (proposedDate.isAfter(clock.getUTCNow())) { proposedDate = proposedDate.minus(billingPeriod.getPeriod());
@Test(groups = "fast") public void testSinglePlan_SlightlyMoreThanOnePeriodAfterStart() throws InvalidDateSequenceException { final LocalDate startDate = invoiceUtil.buildDate(2011, 2, 15); final LocalDate targetDate = startDate.plus(getBillingPeriod().getPeriod()).plusDays(1); testCalculateNumberOfBillingCycles(startDate, targetDate, 15, TWO); }
@Test(groups = "fast") public void testSinglePlan_OnePeriodLessADayAfterStart() throws InvalidDateSequenceException { final LocalDate startDate = invoiceUtil.buildDate(2011, 2, 15); final LocalDate targetDate = startDate.plus(getBillingPeriod().getPeriod()).plusDays(-1); testCalculateNumberOfBillingCycles(startDate, targetDate, 15, ONE); }
private void calculateLastBillingCycleDate() { // IN_ARREAR cases if (effectiveEndDate == null || effectiveEndDate.compareTo(firstBillingCycleDate) < 0 ) { lastBillingCycleDate = null; return; } // Start from firstBillingCycleDate and billingPeriod until we pass the effectiveEndDate LocalDate proposedDate = firstBillingCycleDate; int numberOfPeriods = 0; while (!proposedDate.isAfter(effectiveEndDate)) { proposedDate = InvoiceDateUtils.advanceByNPeriods(firstBillingCycleDate, billingPeriod, numberOfPeriods); numberOfPeriods += 1; } // Our proposed date is billingCycleDate prior to the effectiveEndDate proposedDate = proposedDate.minus(billingPeriod.getPeriod()); proposedDate = BillCycleDayCalculator.alignProposedBillCycleDate(proposedDate, billingCycleDay, billingPeriod); if (proposedDate.isBefore(firstBillingCycleDate)) { // Make sure not to go too far in the past lastBillingCycleDate = firstBillingCycleDate; } else { lastBillingCycleDate = proposedDate; } } }
@Test(groups = "fast") public void testSinglePlan_MovingForwardThroughTime() throws InvalidDateSequenceException { final LocalDate startDate = invoiceUtil.buildDate(2011, 1, 31); BigDecimal expectedValue = ONE; for (int i = 1; i <= 12; i++) { LocalDate oneCycleLater = startDate; for (int j = 0; j < i; j++) { oneCycleLater = oneCycleLater.plus(getBillingPeriod().getPeriod()); } // test just before the billing cycle day testCalculateNumberOfBillingCycles(startDate, oneCycleLater.plusDays(-1), 31, expectedValue); expectedValue = expectedValue.add(ONE); // test on the billing cycle day testCalculateNumberOfBillingCycles(startDate, oneCycleLater, 31, expectedValue); // test just after the billing cycle day testCalculateNumberOfBillingCycles(startDate, oneCycleLater.plusDays(1), 31, expectedValue); } }
@Test(groups = "fast") public void testSinglePlan_CrossingYearBoundary() throws InvalidDateSequenceException { final LocalDate startDate = invoiceUtil.buildDate(2011, 12, 15); final LocalDate oneCycleLater = startDate.plus(getBillingPeriod().getPeriod()); // test just before the billing cycle day testCalculateNumberOfBillingCycles(startDate, oneCycleLater.plusDays(-1), 15, ONE); // test on the billing cycle day testCalculateNumberOfBillingCycles(startDate, oneCycleLater, 15, TWO); // test just after the billing cycle day testCalculateNumberOfBillingCycles(startDate, oneCycleLater.plusDays(1), 15, TWO); }