killbill-memoizeit

Fix invoicing issue when BCD is larger than end of month (special

4/7/2017 2:46:39 AM

Details

diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoice.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoice.java
index 442d316..9d10762 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoice.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoice.java
@@ -30,8 +30,12 @@ import org.killbill.billing.account.api.Account;
 import org.killbill.billing.api.TestApiListener.NextEvent;
 import org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck;
 import org.killbill.billing.catalog.api.BillingPeriod;
+import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
+import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
+import org.killbill.billing.catalog.api.PriceListSet;
 import org.killbill.billing.catalog.api.ProductCategory;
 import org.killbill.billing.entitlement.api.DefaultEntitlement;
+import org.killbill.billing.entitlement.api.Entitlement;
 import org.killbill.billing.invoice.api.DryRunArguments;
 import org.killbill.billing.invoice.api.DryRunType;
 import org.killbill.billing.invoice.api.Invoice;
@@ -325,4 +329,36 @@ public class TestIntegrationInvoice extends TestIntegrationBase {
         assertEquals(accountPayments.get(2).getPurchasedAmount(), new BigDecimal("10.00"));
     }
 
+    @Test(groups = "slow")
+    public void testIntegrationWithBCDLargerThanEndMonth() throws Exception {
+
+        final int billingDay = 31;
+        final DateTime initialCreationDate = new DateTime(2017, 01, 31, 0, 0, 0, 0, testTimeZone);
+        // set clock to the initial start date
+        clock.setTime(initialCreationDate);
+
+        final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(billingDay));
+
+        final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Blowdart", BillingPeriod.MONTHLY, "notrial", null);
+        busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
+        final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleExternalKey", ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, ImmutableList.<PluginProperty>of(), callContext);
+        assertListenerStatus();
+
+        // 2017-02-28
+        busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
+        clock.addMonths(1);
+        assertListenerStatus();
+
+        // 2017-03-31
+        busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
+        clock.addMonths(1);
+        clock.addDays(3);
+        assertListenerStatus();
+
+        // 2017-04-30
+        busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
+        clock.addMonths(1);
+        assertListenerStatus();
+    }
+
 }
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/generator/BillingIntervalDetail.java b/invoice/src/main/java/org/killbill/billing/invoice/generator/BillingIntervalDetail.java
index 846b057..c25c66f 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/generator/BillingIntervalDetail.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/generator/BillingIntervalDetail.java
@@ -212,8 +212,12 @@ public class BillingIntervalDetail {
     public static LocalDate alignProposedBillCycleDate(final LocalDate proposedDate, final int billingCycleDay) {
         final int lastDayOfMonth = proposedDate.dayOfMonth().getMaximumValue();
         int proposedBillCycleDate = proposedDate.getDayOfMonth();
-        if (proposedBillCycleDate < billingCycleDay && billingCycleDay <= lastDayOfMonth) {
-            proposedBillCycleDate = billingCycleDay;
+        if (proposedBillCycleDate < billingCycleDay) {
+            if (billingCycleDay <= lastDayOfMonth) {
+                proposedBillCycleDate = billingCycleDay;
+            } else {
+                proposedBillCycleDate = lastDayOfMonth;
+            }
         }
         return new LocalDate(proposedDate.getYear(), proposedDate.getMonthOfYear(), proposedBillCycleDate, proposedDate.getChronology());
     }
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/generator/TestInAdvanceBillingIntervalDetail.java b/invoice/src/test/java/org/killbill/billing/invoice/generator/TestInAdvanceBillingIntervalDetail.java
index 121ff05..1e3b59a 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/generator/TestInAdvanceBillingIntervalDetail.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/generator/TestInAdvanceBillingIntervalDetail.java
@@ -25,8 +25,30 @@ import org.killbill.billing.invoice.InvoiceTestSuiteNoDB;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
+import static org.killbill.billing.invoice.generator.InvoiceDateUtils.calculateNumberOfWholeBillingPeriods;
+
 public class TestInAdvanceBillingIntervalDetail extends InvoiceTestSuiteNoDB {
 
+
+    @Test(groups = "fast")
+    public void testWithBCDLargerThanEndMonth() throws Exception {
+        final LocalDate startDate = new LocalDate("2017-01-31");
+        final LocalDate endDate = null;
+        final LocalDate targetDate = new LocalDate("2017-03-31");
+        int BCD = 31;
+        final BillingIntervalDetail billingIntervalDetail = new BillingIntervalDetail(startDate, endDate, targetDate, BCD, BillingPeriod.MONTHLY, BillingMode.IN_ADVANCE);
+
+        final LocalDate firstBillingCycleDate = billingIntervalDetail.getFirstBillingCycleDate();
+        final LocalDate lastBillingCycleDate = billingIntervalDetail.getLastBillingCycleDate();
+
+        final int numberOfWholeBillingPeriods = calculateNumberOfWholeBillingPeriods(firstBillingCycleDate, lastBillingCycleDate, BillingPeriod.MONTHLY);
+
+
+        Assert.assertEquals(numberOfWholeBillingPeriods, 3);
+    }
+
+
+
     /*
      *
      *         Start         BCD    END_MONTH