diff --git a/invoice/src/main/java/com/ning/billing/invoice/generator/BillingIntervalDetail.java b/invoice/src/main/java/com/ning/billing/invoice/generator/BillingIntervalDetail.java
index 9c7de27..8c1d9cc 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/generator/BillingIntervalDetail.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/generator/BillingIntervalDetail.java
@@ -20,6 +20,8 @@ import org.joda.time.LocalDate;
import com.ning.billing.catalog.api.BillingPeriod;
+import com.google.common.annotations.VisibleForTesting;
+
public class BillingIntervalDetail {
private final LocalDate startDate;
@@ -65,7 +67,8 @@ public class BillingIntervalDetail {
calculateLastBillingCycleDate();
}
- private void calculateFirstBillingCycleDate() {
+ @VisibleForTesting
+ void calculateFirstBillingCycleDate() {
final int lastDayOfMonth = startDate.dayOfMonth().getMaximumValue();
final LocalDate billingCycleDate;
@@ -75,12 +78,10 @@ public class BillingIntervalDetail {
billingCycleDate = new LocalDate(startDate.getYear(), startDate.getMonthOfYear(), billingCycleDay, startDate.getChronology());
}
- int numberOfPeriods = 0;
final int numberOfMonthsInPeriod = billingPeriod.getNumberOfMonths();
LocalDate proposedDate = billingCycleDate;
while (proposedDate.isBefore(startDate)) {
- proposedDate = proposedDate.plusMonths(numberOfPeriods * numberOfMonthsInPeriod);
- numberOfPeriods += 1;
+ proposedDate = proposedDate.plusMonths(numberOfMonthsInPeriod);
}
firstBillingCycleDate = alignProposedBillCycleDate(proposedDate);
}
diff --git a/invoice/src/test/java/com/ning/billing/invoice/generator/TestBillingIntervalDetail.java b/invoice/src/test/java/com/ning/billing/invoice/generator/TestBillingIntervalDetail.java
index 65c692f..ce8f84e 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/generator/TestBillingIntervalDetail.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/generator/TestBillingIntervalDetail.java
@@ -25,6 +25,69 @@ import com.ning.billing.invoice.InvoiceTestSuiteNoDB;
public class TestBillingIntervalDetail extends InvoiceTestSuiteNoDB {
+ /*
+ *
+ * Start BCD END_MONTH
+ * |---------|------------|-------|
+ *
+ */
+ @Test(groups = "fast")
+ public void testCalculateFirstBillingCycleDate1() throws Exception {
+ final LocalDate from = new LocalDate("2012-01-16");
+ final int bcd = 17;
+ final BillingIntervalDetail billingIntervalDetail = new BillingIntervalDetail(from, null, new LocalDate(), bcd, BillingPeriod.ANNUAL);
+ billingIntervalDetail.calculateFirstBillingCycleDate();
+ Assert.assertEquals(billingIntervalDetail.getFirstBillingCycleDate(), new LocalDate("2012-01-17"));
+ }
+
+ /*
+ *
+ * Start END_MONTH BCD
+ * |---------|-------------------| - - - -|
+ *
+ */
+ @Test(groups = "fast")
+ public void testCalculateFirstBillingCycleDate2() throws Exception {
+ final LocalDate from = new LocalDate("2012-02-16");
+ final int bcd = 30;
+ final BillingIntervalDetail billingIntervalDetail = new BillingIntervalDetail(from, null, new LocalDate(), bcd, BillingPeriod.ANNUAL);
+ billingIntervalDetail.calculateFirstBillingCycleDate();
+ Assert.assertEquals(billingIntervalDetail.getFirstBillingCycleDate(), new LocalDate("2012-02-29"));
+ }
+
+ /*
+ * Here the interesting part is that BCD is prior start and
+ * i) we use MONTHLY billing period
+ * ii) on the next month, there is no such date (2012-02-30 does not exist)
+ *
+ * Start
+ * BCD END_MONTH
+ * |----------------------------|--------|
+ *
+ */
+ @Test(groups = "fast")
+ public void testCalculateFirstBillingCycleDate4() throws Exception {
+ final LocalDate from = new LocalDate("2012-01-31");
+ final int bcd = 30;
+ final BillingIntervalDetail billingIntervalDetail = new BillingIntervalDetail(from, null, new LocalDate(), bcd, BillingPeriod.MONTHLY);
+ billingIntervalDetail.calculateFirstBillingCycleDate();
+ Assert.assertEquals(billingIntervalDetail.getFirstBillingCycleDate(), new LocalDate("2012-02-29"));
+ }
+
+ /*
+ *
+ * BCD Start END_MONTH
+ * |---------|-------------------|-----------|
+ *
+ */
+ @Test(groups = "fast")
+ public void testCalculateFirstBillingCycleDate3() throws Exception {
+ final LocalDate from = new LocalDate("2012-02-16");
+ final int bcd = 14;
+ final BillingIntervalDetail billingIntervalDetail = new BillingIntervalDetail(from, null, new LocalDate(), bcd, BillingPeriod.ANNUAL);
+ billingIntervalDetail.calculateFirstBillingCycleDate();
+ Assert.assertEquals(billingIntervalDetail.getFirstBillingCycleDate(), new LocalDate("2013-02-14"));
+ }
@Test(groups = "fast")
public void testNextBCDShouldNotBeInThePast() throws Exception {
@@ -102,5 +165,4 @@ public class TestBillingIntervalDetail extends InvoiceTestSuiteNoDB {
Assert.assertEquals(effectiveEndDate, new LocalDate("2012-05-31"));
}
-
}