static BigDecimal getMrrFromBillingPeriod(final BillingPeriod period, final BigDecimal price) { if (period == null || period.getNumberOfMonths() == 0) { return BigDecimal.ZERO; } return price.divide(BigDecimal.valueOf(period.getNumberOfMonths()), Rounder.SCALE, RoundingMode.HALF_UP); }
public LocalDate getFutureBillingDateFor(int nbPeriod) { final int numberOfMonthsPerBillingPeriod = billingPeriod.getNumberOfMonths(); LocalDate proposedDate = firstBillingCycleDate.plusMonths((nbPeriod) * numberOfMonthsPerBillingPeriod); return alignProposedBillCycleDate(proposedDate); }
public static int calculateNumberOfWholeBillingPeriods(final LocalDate startDate, final LocalDate endDate, final BillingPeriod billingPeriod) { final int numberOfMonths = Months.monthsBetween(startDate, endDate).getMonths(); final int numberOfMonthsInPeriod = billingPeriod.getNumberOfMonths(); return numberOfMonths / numberOfMonthsInPeriod; }
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.plusMonths(billingPeriod.getNumberOfMonths()); return calculateProrationBetweenDates(previousBillThroughDate, endDate, previousBillThroughDate, nextBillThroughDate); }
public static BigDecimal calculateProRationBeforeFirstBillingPeriod(final LocalDate startDate, final LocalDate nextBillingCycleDate, final BillingPeriod billingPeriod) { final LocalDate previousBillingCycleDate = nextBillingCycleDate.plusMonths(-billingPeriod.getNumberOfMonths()); return calculateProrationBetweenDates(startDate, nextBillingCycleDate, previousBillingCycleDate, nextBillingCycleDate); }
private void calculateLastBillingCycleDate() { // Start from firstBillingCycleDate and billingPeriod until we pass the effectiveEndDate LocalDate proposedDate = firstBillingCycleDate; int numberOfPeriods = 0; while (!proposedDate.isAfter(effectiveEndDate)) { proposedDate = firstBillingCycleDate.plusMonths(numberOfPeriods * billingPeriod.getNumberOfMonths()); numberOfPeriods += 1; } // Our proposed date is billingCycleDate prior to the effectiveEndDate proposedDate = proposedDate.plusMonths(-billingPeriod.getNumberOfMonths()); proposedDate = alignProposedBillCycleDate(proposedDate); if (proposedDate.isBefore(firstBillingCycleDate)) { // Make sure not to go too far in the past lastBillingCycleDate = firstBillingCycleDate; } else { lastBillingCycleDate = proposedDate; } }
public static LocalDate calculateEffectiveEndDate(final LocalDate billCycleDate, final LocalDate targetDate, final BillingPeriod billingPeriod) { if (targetDate.isBefore(billCycleDate)) { return billCycleDate; } final int numberOfMonthsInPeriod = billingPeriod.getNumberOfMonths(); int numberOfPeriods = 0; LocalDate proposedDate = billCycleDate; while (!proposedDate.isAfter(targetDate)) { proposedDate = billCycleDate.plusMonths(numberOfPeriods * numberOfMonthsInPeriod); numberOfPeriods += 1; } return proposedDate; }
public static LocalDate calculateLastBillingCycleDateBefore(final LocalDate date, final LocalDate previousBillCycleDate, final int billingCycleDay, final BillingPeriod billingPeriod) { LocalDate proposedDate = previousBillCycleDate; int numberOfPeriods = 0; while (!proposedDate.isAfter(date)) { proposedDate = previousBillCycleDate.plusMonths(numberOfPeriods * billingPeriod.getNumberOfMonths()); numberOfPeriods += 1; } proposedDate = proposedDate.plusMonths(-billingPeriod.getNumberOfMonths()); if (proposedDate.dayOfMonth().get() < billingCycleDay) { final int lastDayOfTheMonth = proposedDate.dayOfMonth().getMaximumValue(); if (lastDayOfTheMonth < billingCycleDay) { proposedDate = new LocalDate(proposedDate.getYear(), proposedDate.getMonthOfYear(), lastDayOfTheMonth); } else { proposedDate = new LocalDate(proposedDate.getYear(), proposedDate.getMonthOfYear(), billingCycleDay); } } if (proposedDate.isBefore(previousBillCycleDate)) { // Make sure not to go too far in the past return previousBillCycleDate; } else { return proposedDate; } }
@Test(groups = "fast") public void testSinglePlan_ExactlyOnePeriodAfterStart() throws InvalidDateSequenceException { final LocalDate startDate = invoiceUtil.buildDate(2011, 2, 15); final LocalDate targetDate = startDate.plusMonths(getBillingPeriod().getNumberOfMonths()); 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.plusMonths(getBillingPeriod().getNumberOfMonths()); 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.plusMonths(getBillingPeriod().getNumberOfMonths()); testCalculateNumberOfBillingCycles(startDate, targetDate, 15, TWO); }
public static LocalDate calculateEffectiveEndDate(final LocalDate billCycleDate, final LocalDate targetDate, final LocalDate endDate, final BillingPeriod billingPeriod) { if (targetDate.isBefore(endDate)) { if (targetDate.isBefore(billCycleDate)) { return billCycleDate; } final int numberOfMonthsInPeriod = billingPeriod.getNumberOfMonths(); int numberOfPeriods = 0; LocalDate proposedDate = billCycleDate; while (!proposedDate.isAfter(targetDate)) { proposedDate = billCycleDate.plusMonths(numberOfPeriods * numberOfMonthsInPeriod); numberOfPeriods += 1; } // the current period includes the target date // check to see whether the end date truncates the period if (endDate.isBefore(proposedDate)) { return endDate; } else { return proposedDate; } } else { return endDate; } }
private void calculateEffectiveEndDate() { // We have an endDate and the targetDate is greater or equal to our endDate => return it if (endDate != null && !targetDate.isBefore(endDate)) { effectiveEndDate = endDate; return; } if (targetDate.isBefore(firstBillingCycleDate)) { effectiveEndDate = firstBillingCycleDate; return; } final int numberOfMonthsInPeriod = billingPeriod.getNumberOfMonths(); int numberOfPeriods = 0; LocalDate proposedDate = firstBillingCycleDate; while (!proposedDate.isAfter(targetDate)) { proposedDate = firstBillingCycleDate.plusMonths(numberOfPeriods * numberOfMonthsInPeriod); numberOfPeriods += 1; } proposedDate = alignProposedBillCycleDate(proposedDate); // The proposedDate is greater to our endDate => return it if (endDate != null && endDate.isBefore(proposedDate)) { effectiveEndDate = endDate; } else { effectiveEndDate = proposedDate; } }
@Test(groups = "fast") public void testSinglePlan_SlightlyMoreThanOnePeriodAfterStart() throws InvalidDateSequenceException { final LocalDate startDate = invoiceUtil.buildDate(2011, 2, 15); final LocalDate targetDate = startDate.plusMonths(getBillingPeriod().getNumberOfMonths()).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.plusMonths(getBillingPeriod().getNumberOfMonths()).plusDays(-1); testCalculateNumberOfBillingCycles(startDate, targetDate, 15, ONE); }
@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++) { final LocalDate oneCycleLater = startDate.plusMonths(i * getBillingPeriod().getNumberOfMonths()); // 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.plusMonths(getBillingPeriod().getNumberOfMonths()); // 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); }