killbill-memoizeit

junction: fix issue in BillCycleDayCalculator The code

8/8/2012 3:14:29 PM

Details

diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestBundleTransfer.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestBundleTransfer.java
index de00151..f6c2124 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestBundleTransfer.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestBundleTransfer.java
@@ -21,9 +21,6 @@ import static org.testng.Assert.assertTrue;
 
 import java.math.BigDecimal;
 import java.util.List;
-import java.util.UUID;
-
-import junit.framework.Assert;
 
 import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
@@ -32,6 +29,7 @@ import org.testng.annotations.Test;
 
 import com.google.common.collect.ImmutableList;
 import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.BillCycleDay;
 import com.ning.billing.api.TestApiListener.NextEvent;
 import com.ning.billing.beatrix.util.InvoiceChecker.ExpectedItemCheck;
 import com.ning.billing.catalog.api.BillingPeriod;
@@ -103,15 +101,15 @@ public class TestBundleTransfer extends TestIntegrationBase {
         final List<InvoiceItem> invoiceItems = invoices.get(0).getInvoiceItems();
         assertEquals(invoiceItems.size(), 1);
         InvoiceItem theItem = invoiceItems.get(0);
-        Assert.assertTrue(theItem.getStartDate().compareTo(new LocalDate(2012,5,11)) == 0);
-        Assert.assertTrue(theItem.getEndDate().compareTo(new LocalDate(2013,5,11)) == 0);
-        Assert.assertTrue(theItem.getAmount().compareTo(new BigDecimal("2399.9500")) == 0);
+        assertTrue(theItem.getStartDate().compareTo(new LocalDate(2012,5,11)) == 0);
+        assertTrue(theItem.getEndDate().compareTo(new LocalDate(2013,5,11)) == 0);
+        assertTrue(theItem.getAmount().compareTo(new BigDecimal("2399.9500")) == 0);
     }
 
     @Test(groups = "slow")
     public void testBundleTransferWithBPMonthlyOnly() throws Exception {
 
-        final Account account = createAccountWithPaymentMethod(getAccountData(9));
+        final Account account = createAccountWithPaymentMethod(getAccountData(0));
 
         // Set clock to the initial start date - we implicitly assume here that the account timezone is UTC
 
@@ -148,7 +146,7 @@ public class TestBundleTransfer extends TestIntegrationBase {
         assertListenerStatus();
 
         // BUNDLE TRANSFER
-        final Account newAccount = createAccountWithPaymentMethod(getAccountData(15));
+        final Account newAccount = createAccountWithPaymentMethod(getAccountData(0));
 
         busHandler.pushExpectedEvent(NextEvent.TRANSFER);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
@@ -157,15 +155,22 @@ public class TestBundleTransfer extends TestIntegrationBase {
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
 
-        List<Invoice> invoices =invoiceUserApi.getInvoicesByAccount(newAccount.getId());
+        // Verify the BCD of the new account
+        final BillCycleDay oldBCD = accountUserApi.getAccountById(account.getId()).getBillCycleDay();
+        final BillCycleDay newBCD = accountUserApi.getAccountById(newAccount.getId()).getBillCycleDay();
+        assertEquals(oldBCD.getDayOfMonthUTC(), 1);
+        // Day of the transfer
+        assertEquals(newBCD.getDayOfMonthUTC(), 3);
+
+        final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(newAccount.getId());
         assertEquals(invoices.size(), 1);
 
         final List<InvoiceItem> invoiceItems = invoices.get(0).getInvoiceItems();
         assertEquals(invoiceItems.size(), 1);
-        InvoiceItem theItem = invoiceItems.get(0);
-        Assert.assertTrue(theItem.getStartDate().compareTo(new LocalDate(2012,5,3)) == 0);
-        Assert.assertTrue(theItem.getEndDate().compareTo(new LocalDate(2012,5,15)) == 0);
-        Assert.assertTrue(theItem.getAmount().compareTo(new BigDecimal("99.98")) == 0);
+        final InvoiceItem theItem = invoiceItems.get(0);
+        assertTrue(theItem.getStartDate().compareTo(new LocalDate(2012, 5, 3)) == 0);
+        assertTrue(theItem.getEndDate().compareTo(new LocalDate(2012, 6, 3)) == 0);
+        assertTrue(theItem.getAmount().compareTo(new BigDecimal("249.95")) == 0);
     }
 
     @Test(groups = "slow")
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BillCycleDayCalculator.java b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BillCycleDayCalculator.java
index 8ecc101..0580d60 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BillCycleDayCalculator.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BillCycleDayCalculator.java
@@ -16,6 +16,8 @@
 
 package com.ning.billing.junction.plumbing.billing;
 
+import java.util.List;
+
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.slf4j.Logger;
@@ -92,7 +94,7 @@ public class BillCycleDayCalculator {
             case ACCOUNT:
                 result = account.getBillCycleDay();
                 if (result == null || result.getDayOfMonthUTC() == 0) {
-                    result = calculateBcdFromSubscription(subscription, plan, account);
+                    result = calculateBcdFromSubscription(subscription, plan, account, catalog);
                 }
                 break;
             case BUNDLE:
@@ -103,10 +105,10 @@ public class BillCycleDayCalculator {
                     final EffectiveSubscriptionEvent previousTransition = baseSub.getPreviousTransition();
                     basePlan = catalog.findPlan(previousTransition.getPreviousPlan(), previousTransition.getEffectiveTransitionTime(), previousTransition.getSubscriptionStartDate());
                 }
-                result = calculateBcdFromSubscription(baseSub, basePlan, account);
+                result = calculateBcdFromSubscription(baseSub, basePlan, account, catalog);
                 break;
             case SUBSCRIPTION:
-                result = calculateBcdFromSubscription(subscription, plan, account);
+                result = calculateBcdFromSubscription(subscription, plan, account, catalog);
                 break;
         }
 
@@ -118,10 +120,30 @@ public class BillCycleDayCalculator {
     }
 
     @VisibleForTesting
-    BillCycleDay calculateBcdFromSubscription(final Subscription subscription, final Plan plan, final Account account) throws AccountApiException {
+    BillCycleDay calculateBcdFromSubscription(final Subscription subscription, final Plan plan, final Account account, final Catalog catalog)
+            throws AccountApiException, CatalogApiException {
+        // Retrieve the initial phase type for that subscription
+        // TODO - this should be extracted somewhere, along with this code above
+        final PhaseType initialPhaseType;
+        final List<EffectiveSubscriptionEvent> transitions = subscription.getAllTransitions();
+        if (transitions.size() == 0) {
+            initialPhaseType = null;
+        } else {
+            final DateTime requestedDate = subscription.getStartDate();
+            final String initialPhaseString = transitions.get(0).getNextPhase();
+            if (initialPhaseString == null) {
+                initialPhaseType = null;
+            } else {
+                final PlanPhase initialPhase = catalog.findPhase(initialPhaseString, requestedDate, subscription.getStartDate());
+                if (initialPhase == null) {
+                    initialPhaseType = null;
+                } else {
+                    initialPhaseType = initialPhase.getPhaseType();
+                }
+            }
+        }
 
-        final PhaseType currentPhaseType = subscription.getCurrentPhase() != null ?  subscription.getCurrentPhase().getPhaseType() : null;
-        final DateTime date = plan.dateOfFirstRecurringNonZeroCharge(subscription.getStartDate(), currentPhaseType);
+        final DateTime date = plan.dateOfFirstRecurringNonZeroCharge(subscription.getStartDate(), initialPhaseType);
         // There are really two kinds of billCycleDay:
         // - a System billingCycleDay which should be computed from UTC time (in order to get the correct notification time at
         //   the end of each service period)
diff --git a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillCycleDayCalculator.java b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillCycleDayCalculator.java
index f243bbf..fc10afb 100644
--- a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillCycleDayCalculator.java
+++ b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillCycleDayCalculator.java
@@ -29,6 +29,7 @@ import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.BillCycleDay;
 import com.ning.billing.catalog.api.BillingAlignment;
 import com.ning.billing.catalog.api.Catalog;
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.entitlement.api.user.EffectiveSubscriptionEvent;
@@ -133,7 +134,7 @@ public class TestBillCycleDayCalculator {
         verifyBCDCalculation(accountTimeZone, startDate, bcdUTC, bcdLocal);
     }
 
-    private void verifyBCDCalculation(final DateTimeZone accountTimeZone, final DateTime startDateUTC, final int bcdUTC, final int bcdLocal) throws AccountApiException {
+    private void verifyBCDCalculation(final DateTimeZone accountTimeZone, final DateTime startDateUTC, final int bcdUTC, final int bcdLocal) throws AccountApiException, CatalogApiException {
         final BillCycleDayCalculator billCycleDayCalculator = new BillCycleDayCalculator(Mockito.mock(CatalogService.class), Mockito.mock(EntitlementUserApi.class));
 
         final Subscription subscription = Mockito.mock(Subscription.class);
@@ -145,7 +146,7 @@ public class TestBillCycleDayCalculator {
         final Account account = Mockito.mock(Account.class);
         Mockito.when(account.getTimeZone()).thenReturn(accountTimeZone);
 
-        final BillCycleDay bcd = billCycleDayCalculator.calculateBcdFromSubscription(subscription, plan, account);
+        final BillCycleDay bcd = billCycleDayCalculator.calculateBcdFromSubscription(subscription, plan, account, Mockito.mock(Catalog.class));
         Assert.assertEquals(bcd.getDayOfMonthUTC(), bcdUTC);
         Assert.assertEquals(bcd.getDayOfMonthLocal(), bcdLocal);
     }