killbill-uncached

Details

diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionApiService.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionApiService.java
index e050201..3aebac0 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionApiService.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionApiService.java
@@ -98,7 +98,8 @@ public class SubscriptionApiService {
             }
 
             DateTime now = clock.getUTCNow();
-            requestedDate = (requestedDate != null) ? DefaultClock.truncateMs(requestedDate) : null;
+            requestedDate = (requestedDate != null) ? DefaultClock.truncateMs(requestedDate) : now;
+            // STEPH needs to check if requestedDate is before last 'erasable event'?
             if (requestedDate != null && requestedDate.isAfter(now)) {
                 throw new EntitlementUserApiException(ErrorCode.ENT_INVALID_REQUESTED_DATE, requestedDate.toString());
             }
@@ -112,7 +113,7 @@ public class SubscriptionApiService {
 
             ActionPolicy policy = null;
             policy = catalogService.getCatalog().planCancelPolicy(planPhase);
-            DateTime effectiveDate = subscription.getPlanChangeEffectiveDate(policy, now);
+            DateTime effectiveDate = subscription.getPlanChangeEffectiveDate(policy, requestedDate);
 
             EntitlementEvent cancelEvent = new ApiEventCancel(new ApiEventBuilder()
             .setSubscriptionId(subscription.getId())
@@ -164,68 +165,74 @@ public class SubscriptionApiService {
         throws EntitlementUserApiException {
 
         try {
-        requestedDate = (requestedDate != null) ? DefaultClock.truncateMs(requestedDate) : null;
-        String currentPriceList = subscription.getCurrentPriceList();
 
-        SubscriptionState currentState = subscription.getState();
-        if (currentState != SubscriptionState.ACTIVE) {
-            throw new EntitlementUserApiException(ErrorCode.ENT_CHANGE_NON_ACTIVE, subscription.getId(), currentState);
-        }
 
-        if (subscription.isSubscriptionFutureCancelled()) {
-            throw new EntitlementUserApiException(ErrorCode.ENT_CHANGE_FUTURE_CANCELLED, subscription.getId());
-        }
+            DateTime now = clock.getUTCNow();
+            requestedDate = (requestedDate != null) ? DefaultClock.truncateMs(requestedDate) : now;
+            // STEPH needs to check if requestedDate is before last 'erasable event'?
+            if (requestedDate != null && requestedDate.isAfter(now)) {
+                throw new EntitlementUserApiException(ErrorCode.ENT_INVALID_REQUESTED_DATE, requestedDate.toString());
+            }
 
-        DateTime now = clock.getUTCNow();
-        PlanChangeResult planChangeResult = null;
-        try {
+            String currentPriceList = subscription.getCurrentPriceList();
 
-            Product destProduct = catalogService.getCatalog().findProduct(productName);
-            Plan currentPlan = subscription.getCurrentPlan();
-            PlanPhaseSpecifier fromPlanPhase = new PlanPhaseSpecifier(currentPlan.getProduct().getName(),
-                    currentPlan.getProduct().getCategory(),
-                    currentPlan.getBillingPeriod(),
-                    currentPriceList, subscription.getCurrentPhase().getPhaseType());
-            PlanSpecifier toPlanPhase = new PlanSpecifier(productName,
-                    destProduct.getCategory(),
-                    term,
-                    priceList);
-
-            planChangeResult = catalogService.getCatalog().planChange(fromPlanPhase, toPlanPhase);
-        } catch (CatalogApiException e) {
-            throw new EntitlementUserApiException(e);
-        }
+            SubscriptionState currentState = subscription.getState();
+            if (currentState != SubscriptionState.ACTIVE) {
+                throw new EntitlementUserApiException(ErrorCode.ENT_CHANGE_NON_ACTIVE, subscription.getId(), currentState);
+            }
+
+            if (subscription.isSubscriptionFutureCancelled()) {
+                throw new EntitlementUserApiException(ErrorCode.ENT_CHANGE_FUTURE_CANCELLED, subscription.getId());
+            }
+            PlanChangeResult planChangeResult = null;
+            try {
+
+                Product destProduct = catalogService.getCatalog().findProduct(productName);
+                Plan currentPlan = subscription.getCurrentPlan();
+                PlanPhaseSpecifier fromPlanPhase = new PlanPhaseSpecifier(currentPlan.getProduct().getName(),
+                        currentPlan.getProduct().getCategory(),
+                        currentPlan.getBillingPeriod(),
+                        currentPriceList, subscription.getCurrentPhase().getPhaseType());
+                PlanSpecifier toPlanPhase = new PlanSpecifier(productName,
+                        destProduct.getCategory(),
+                        term,
+                        priceList);
+
+                planChangeResult = catalogService.getCatalog().planChange(fromPlanPhase, toPlanPhase);
+            } catch (CatalogApiException e) {
+                throw new EntitlementUserApiException(e);
+            }
 
-        ActionPolicy policy = planChangeResult.getPolicy();
-        PriceList newPriceList = planChangeResult.getNewPriceList();
+            ActionPolicy policy = planChangeResult.getPolicy();
+            PriceList newPriceList = planChangeResult.getNewPriceList();
 
-        Plan newPlan = catalogService.getCatalog().findPlan(productName, term, newPriceList.getName());
-        DateTime effectiveDate = subscription.getPlanChangeEffectiveDate(policy, now);
+            Plan newPlan = catalogService.getCatalog().findPlan(productName, term, newPriceList.getName());
+            DateTime effectiveDate = subscription.getPlanChangeEffectiveDate(policy, now);
 
-        TimedPhase currentTimedPhase = planAligner.getCurrentTimedPhaseOnChange(subscription, newPlan, newPriceList.getName(), effectiveDate);
+            TimedPhase currentTimedPhase = planAligner.getCurrentTimedPhaseOnChange(subscription, newPlan, newPriceList.getName(), effectiveDate);
 
-        EntitlementEvent changeEvent = new ApiEventChange(new ApiEventBuilder()
-        .setSubscriptionId(subscription.getId())
-        .setEventPlan(newPlan.getName())
-        .setEventPlanPhase(currentTimedPhase.getPhase().getName())
-        .setEventPriceList(newPriceList.getName())
-        .setActiveVersion(subscription.getActiveVersion())
-        .setProcessedDate(now)
-        .setEffectiveDate(effectiveDate)
-        .setRequestedDate(now));
+            EntitlementEvent changeEvent = new ApiEventChange(new ApiEventBuilder()
+            .setSubscriptionId(subscription.getId())
+            .setEventPlan(newPlan.getName())
+            .setEventPlanPhase(currentTimedPhase.getPhase().getName())
+            .setEventPriceList(newPriceList.getName())
+            .setActiveVersion(subscription.getActiveVersion())
+            .setProcessedDate(now)
+            .setEffectiveDate(effectiveDate)
+            .setRequestedDate(now));
 
-        TimedPhase nextTimedPhase = planAligner.getNextTimedPhaseOnChange(subscription, newPlan, newPriceList.getName(), effectiveDate);
-        PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ?
-                PhaseEventData.getNextPhaseEvent(nextTimedPhase.getPhase().getName(), subscription, now, nextTimedPhase.getStartPhase()) :
-                    null;
-        List<EntitlementEvent> changeEvents = new ArrayList<EntitlementEvent>();
-        // Only add the PHASE if it does not coincide with the CHANGE, if not this is 'just' a CHANGE.
-        if (nextPhaseEvent != null && ! nextPhaseEvent.getEffectiveDate().equals(changeEvent.getEffectiveDate())) {
-            changeEvents.add(nextPhaseEvent);
-        }
-        changeEvents.add(changeEvent);
-        dao.changePlan(subscription.getId(), changeEvents);
-        subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId()), catalogService.getCatalog());
+            TimedPhase nextTimedPhase = planAligner.getNextTimedPhaseOnChange(subscription, newPlan, newPriceList.getName(), effectiveDate);
+            PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ?
+                    PhaseEventData.getNextPhaseEvent(nextTimedPhase.getPhase().getName(), subscription, now, nextTimedPhase.getStartPhase()) :
+                        null;
+                    List<EntitlementEvent> changeEvents = new ArrayList<EntitlementEvent>();
+                    // Only add the PHASE if it does not coincide with the CHANGE, if not this is 'just' a CHANGE.
+                    if (nextPhaseEvent != null && ! nextPhaseEvent.getEffectiveDate().equals(changeEvent.getEffectiveDate())) {
+                        changeEvents.add(nextPhaseEvent);
+                    }
+                    changeEvents.add(changeEvent);
+                    dao.changePlan(subscription.getId(), changeEvents);
+                    subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId()), catalogService.getCatalog());
         } catch (CatalogApiException e) {
             throw new EntitlementUserApiException(e);
         }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
index a5778f3..3e8ede5 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
@@ -277,10 +277,10 @@ public class SubscriptionData implements Subscription {
     }
 
 
-    public DateTime getPlanChangeEffectiveDate(ActionPolicy policy, DateTime now) {
+    public DateTime getPlanChangeEffectiveDate(ActionPolicy policy, DateTime requestedDate) {
 
         if (policy == ActionPolicy.IMMEDIATE) {
-            return now;
+            return requestedDate;
         }
         if (policy != ActionPolicy.END_OF_TERM) {
             throw new EntitlementError(String.format("Unexpected policy type %s", policy.toString()));
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigration.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigration.java
index 1116eed..271de3c 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigration.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigration.java
@@ -132,7 +132,8 @@ public abstract class TestMigration extends TestApiBase {
 
         try {
             DateTime beforeMigration = clock.getUTCNow();
-            EntitlementAccountMigration toBeMigrated = createAccountFuturePendingPhase();
+            final DateTime trialDate = clock.getUTCNow().minusDays(10);
+            EntitlementAccountMigration toBeMigrated = createAccountFuturePendingPhase(trialDate);
             DateTime afterMigration = clock.getUTCNow();
 
             testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
@@ -146,7 +147,8 @@ public abstract class TestMigration extends TestApiBase {
             List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId());
             assertEquals(subscriptions.size(), 1);
             Subscription subscription = subscriptions.get(0);
-            assertDateWithin(subscription.getStartDate(), beforeMigration, afterMigration);
+
+            assertEquals(subscription.getStartDate(), trialDate);
             assertEquals(subscription.getEndDate(), null);
             assertEquals(subscription.getCurrentPriceList(), PriceListSet.DEFAULT_PRICELIST_NAME);
             assertEquals(subscription.getCurrentPhase().getPhaseType(), PhaseType.TRIAL);
@@ -158,7 +160,7 @@ public abstract class TestMigration extends TestApiBase {
             clock.setDeltaFromReality(thirtyDays, 0);
             assertTrue(testListener.isCompleted(5000));
 
-            assertDateWithin(subscription.getStartDate(), beforeMigration, afterMigration);
+            assertEquals(subscription.getStartDate(), trialDate);
             assertEquals(subscription.getEndDate(), null);
             assertEquals(subscription.getCurrentPriceList(), PriceListSet.DEFAULT_PRICELIST_NAME);
             assertEquals(subscription.getCurrentPhase().getPhaseType(), PhaseType.EVERGREEN);
@@ -299,9 +301,8 @@ public abstract class TestMigration extends TestApiBase {
     }
 
 
-    private EntitlementAccountMigration createAccountFuturePendingPhase() {
+    private EntitlementAccountMigration createAccountFuturePendingPhase(final DateTime trialDate) {
         List<EntitlementSubscriptionMigrationCase> cases = new LinkedList<EntitlementSubscriptionMigrationCase>();
-        final DateTime trialDate = clock.getUTCNow().minusDays(10);
         cases.add(new EntitlementSubscriptionMigrationCase() {
             @Override
             public PlanPhaseSpecifier getPlanPhaseSpecifer() {
@@ -323,7 +324,7 @@ public abstract class TestMigration extends TestApiBase {
             }
             @Override
             public DateTime getEffectiveDate() {
-                return trialDate.plusDays(31);
+                return trialDate.plusDays(30);
             }
             @Override
             public DateTime getCancelledDate() {
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationMemory.java
index e3fc9be..05d6fb5 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationMemory.java
@@ -30,25 +30,25 @@ public class TestMigrationMemory extends TestMigration {
     }
 
     @Override
-    @Test(enabled=true, groups="sql")
+    @Test(enabled=true, groups="fast")
     public void testSingleBasePlan() {
         super.testSingleBasePlan();
     }
 
     @Override
-    @Test(enabled=true, groups="sql")
+    @Test(enabled=true, groups="fast")
     public void testSingleBasePlanFutureCancelled() {
         super.testSingleBasePlanFutureCancelled();
     }
 
     @Override
-    @Test(enabled=true, groups="sql")
+    @Test(enabled=true, groups="fast")
     public void testSingleBasePlanWithPendingPhase() {
         super.testSingleBasePlanWithPendingPhase();
     }
 
     @Override
-    @Test(enabled=true, groups="sql")
+    @Test(enabled=true, groups="fast")
     public void testSingleBasePlanWithPendingChange() {
         super.testSingleBasePlanWithPendingChange();
     }