killbill-aplcache

Details

diff --git a/api/src/main/java/com/ning/billing/ErrorCode.java b/api/src/main/java/com/ning/billing/ErrorCode.java
index da22812..28ef5d4 100644
--- a/api/src/main/java/com/ning/billing/ErrorCode.java
+++ b/api/src/main/java/com/ning/billing/ErrorCode.java
@@ -74,6 +74,7 @@ public enum ErrorCode {
     ENT_REPAIR_SUB_EMPTY(1102, "Subscription %s with recreation for bundle %s should specify all existing events to be deleted"),    
     ENT_REPAIR_BP_RECREATE_MISSING_AO(1103, "BP recreation for bundle %s implies repair all subscriptions"),    
     ENT_REPAIR_BP_RECREATE_MISSING_AO_CREATE(1104, "BP recreation for bundle %s implies that all AO should be start also with a CREATE"),        
+    ENT_REPAIR_AO_CREATE_BEFORE_BP_START(1105, "Can't recreate AO %s for bundle %s before BP starts"),    
     
     /*
     *
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java
index d8315f7..88f0d08 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java
@@ -211,13 +211,6 @@ public class PlanAligner  {
 
         Catalog catalog = catalogService.getFullCatalog();
         ProductCategory currentCategory = currentPlan.getProduct().getCategory();
-        // STEPH tiered ADDON not implemented yet
-        /*
-        if (currentCategory != ProductCategory.BASE) {
-            throw new EntitlementError(String.format("Only implemented changePlan for BasePlan"));
-        }
-        */
-
         PlanPhaseSpecifier fromPlanPhaseSpecifier = new PlanPhaseSpecifier(currentPlan.getProduct().getName(),
                 currentCategory,
                 currentPlan.getBillingPeriod(),
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/repair/DefaultEntitlementRepairApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/repair/DefaultEntitlementRepairApi.java
index 6f2f3bb..547cc93 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/repair/DefaultEntitlementRepairApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/repair/DefaultEntitlementRepairApi.java
@@ -155,6 +155,10 @@ public class DefaultEntitlementRepairApi implements EntitlementRepairApi {
                     repairDao.initializeRepair(curInputRepair.getId(), remaining);
                     inRepair.add(curOutputRepair);
                     if (curOutputRepair.getCategory() == ProductCategory.ADD_ON) {
+                        // Check if ADD_ON RE_CREATE is before BP start
+                        if (isPlanRecreate && subscriptions.get(0).getStartDate().isAfter(curRepair.getNewEvents().get(0).getRequestedDate())) {
+                            throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_AO_CREATE_BEFORE_BP_START, cur.getId(), cur.getBundleId());                            
+                        }
                         addOnSubscriptionInRepair.add(curOutputRepair);
                     } else if (curOutputRepair.getCategory() == ProductCategory.BASE) {
                         baseSubscriptionRepair = curOutputRepair;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java
index 16f75d3..1b7fc80 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java
@@ -142,6 +142,9 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
                 if (baseSubscription == null) {
                     throw new EntitlementUserApiException(ErrorCode.ENT_CREATE_NO_BP, bundleId);
                 }
+                if (effectiveDate.isBefore(baseSubscription.getStartDate())) {
+                    throw new EntitlementUserApiException(ErrorCode.ENT_INVALID_REQUESTED_DATE, requestedDate.toString());
+                }
                 addonUtils.checkAddonCreationRights(baseSubscription, plan);
                 bundleStartDate = baseSubscription.getStartDate();
                 break;
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestApiBaseRepair.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestApiBaseRepair.java
index 9c6244d..31e178d 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestApiBaseRepair.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestApiBaseRepair.java
@@ -125,6 +125,15 @@ public abstract class TestApiBaseRepair extends TestApiBase {
         return ev;
     }
     
+    protected SubscriptionRepair getSubscriptionRepair(final UUID id, final BundleRepair bundleRepair) {
+        for (SubscriptionRepair cur : bundleRepair.getSubscriptions()) {
+            if (cur.getId().equals(id)) {
+                return cur;
+            }
+        }
+        Assert.fail("Failed to find SubscriptionReapir " + id);
+        return null;
+    }
     protected void validateExistingEventForAssertion(final ExistingEvent expected, final ExistingEvent input) {
         assertEquals(input.getPlanPhaseSpecifier().getProductName(), expected.getPlanPhaseSpecifier().getProductName());
         assertEquals(input.getPlanPhaseSpecifier().getPhaseType(), expected.getPlanPhaseSpecifier().getPhaseType());
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairBP.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairBP.java
index 6671b8f..96b42c1 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairBP.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairBP.java
@@ -519,7 +519,7 @@ public class TestRepairBP extends TestApiBaseRepair {
     
     // Needs real SQL backend to be tested properly
     @Test(groups={"slow"})
-    public void testENT_REPAIR_VIEW_CHANGED() throws Exception {
+    public void testENT_REPAIR_VIEW_CHANGED_newEvent() throws Exception {
        
         TestWithException test = new TestWithException();
         DateTime startDate = clock.getUTCNow();
@@ -555,7 +555,43 @@ public class TestRepairBP extends TestApiBaseRepair {
         }, ErrorCode.ENT_REPAIR_VIEW_CHANGED);
     }
 
+    @Test(groups={"slow"}, enabled=false)
+    public void testENT_REPAIR_VIEW_CHANGED_ctd() throws Exception {
+       
+        TestWithException test = new TestWithException();
+        DateTime startDate = clock.getUTCNow();
+        
+        testListener.reset();
+        clock.resetDeltaFromReality();
+
+        final Subscription baseSubscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, startDate);
+        
+        test.withException(new TestWithExceptionCallback() {
+            @Override
+            public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
+
+                /*
+                BundleRepair bundleRepair = repairApi.getBundleRepair(bundle.getId());
+                sortEventsOnBundle(bundleRepair);
+                PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
+                NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, baseSubscription.getStartDate().plusDays(10), spec);
+                List<DeletedEvent> des = new LinkedList<SubscriptionRepair.DeletedEvent>();
+                des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(0).getEventId()));                
+                des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(1).getEventId()));                                
+                SubscriptionRepair sRepair = createSubscriptionReapir(baseSubscription.getId(), des, Collections.singletonList(ne));
+
+                BundleRepair bRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
+
 
+                testListener.pushExpectedEvent(NextEvent.CHANGE);
+                DateTime changeTime = clock.getUTCNow();
+                baseSubscription.changePlan("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, changeTime, context);
+                assertTrue(testListener.isCompleted(5000));
 
+                repairApi.repairBundle(bRepair, true, context);
+                */
+            }
+        }, ErrorCode.ENT_REPAIR_VIEW_CHANGED);
+    }
 
 }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairWithAO.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairWithAO.java
index 24955be..ac28307 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairWithAO.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairWithAO.java
@@ -52,14 +52,29 @@ import com.ning.billing.entitlement.glue.MockEngineModuleSql;
 
 public class TestRepairWithAO extends TestApiBaseRepair {
 
-    
-
     @Override
     public Injector getInjector() {
         return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleSql());
     }
 
     @Test(groups={"slow"})
+    public void testRepairChangeBPWithAddonIncluded() throws Exception {
+        
+    }
+
+    @Test(groups={"slow"})
+    public void testRepairChangeBPWithAddonNonAvailable() throws Exception {
+        
+    }
+
+    @Test(groups={"slow"})
+    public void testRepairCancelBPWithAddons() throws Exception {
+        
+    }
+
+    
+    
+    @Test(groups={"slow"})
     public void testRepairCancelAO() throws Exception {
         String baseProduct = "Shotgun";
         BillingPeriod baseTerm = BillingPeriod.MONTHLY;
@@ -104,6 +119,8 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), dryRunBundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 2);
         
+        bpRepair = getSubscriptionRepair(baseSubscription.getId(), bundleRepair);
+        assertEquals(bpRepair.getExistingEvents().size(), 2);        
         
         List<ExistingEvent> expected = new LinkedList<SubscriptionRepair.ExistingEvent>();
         expected.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, "Telescopic-Scope", PhaseType.DISCOUNT,
@@ -117,6 +134,12 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         SubscriptionData newAoSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(aoSubscription.getId());
         assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription.getAllTransitions().size(), 2);
+        assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
+                
+        SubscriptionData newBaseSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
+        assertEquals(newBaseSubscription.getAllTransitions().size(), 2);
+        assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
         
         dryRun = false;
         BundleRepair realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
@@ -131,6 +154,12 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         newAoSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(aoSubscription.getId());
         assertEquals(newAoSubscription.getState(), SubscriptionState.CANCELLED);
         assertEquals(newAoSubscription.getAllTransitions().size(), 2);
+        assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);        
+                
+        newBaseSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
+        assertEquals(newBaseSubscription.getAllTransitions().size(), 2);
+        assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
     }
     
     
@@ -327,15 +356,4 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         assertNotNull(currentPhase);
         assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
     }
-    
-    
-    private SubscriptionRepair getSubscriptionRepair(final UUID id, final BundleRepair bundleRepair) {
-        for (SubscriptionRepair cur : bundleRepair.getSubscriptions()) {
-            if (cur.getId().equals(id)) {
-                return cur;
-            }
-        }
-        Assert.fail("Failed to find SubscriptionReapir " + id);
-        return null;
-    }
 }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairWithError.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairWithError.java
index 385cb56..87f3cea 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairWithError.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairWithError.java
@@ -43,6 +43,7 @@ import com.ning.billing.entitlement.api.repair.SubscriptionRepair.DeletedEvent;
 import com.ning.billing.entitlement.api.repair.SubscriptionRepair.NewEvent;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.entitlement.glue.MockEngineModuleMemory;
 
 public class TestRepairWithError extends TestApiBaseRepair {
@@ -202,6 +203,51 @@ public class TestRepairWithError extends TestApiBaseRepair {
         }, ErrorCode.ENT_REPAIR_SUB_EMPTY);
     }
     
+    @Test(groups={"fast"})
+    public void testENT_REPAIR_AO_CREATE_BEFORE_BP_START() throws Exception {
+        test.withException(new TestWithExceptionCallback() {
+            @Override
+            public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
+               
+
+                // MOVE CLOCK A LITTLE BIT-- STILL IN TRIAL
+                Duration someTimeLater = getDurationDay(3);
+                clock.setDeltaFromReality(someTimeLater, DAY_IN_MS);
+
+                SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+
+                // MOVE CLOCK A LITTLE BIT MORE -- STILL IN TRIAL
+                clock.addDeltaFromReality(someTimeLater);
+
+                BundleRepair bundleRepair = repairApi.getBundleRepair(bundle.getId());
+                sortEventsOnBundle(bundleRepair);
+                
+                // Quick check
+                SubscriptionRepair bpRepair = getSubscriptionRepair(baseSubscription.getId(), bundleRepair);
+                assertEquals(bpRepair.getExistingEvents().size(), 2);
+                
+                SubscriptionRepair aoRepair = getSubscriptionRepair(aoSubscription.getId(), bundleRepair);
+                assertEquals(aoRepair.getExistingEvents().size(), 2);
+                
+
+                List<DeletedEvent> des = new LinkedList<SubscriptionRepair.DeletedEvent>();
+                des.add(createDeletedEvent(aoRepair.getExistingEvents().get(0).getEventId()));        
+                des.add(createDeletedEvent(aoRepair.getExistingEvents().get(1).getEventId()));
+
+                DateTime aoRecreateDate = aoSubscription.getStartDate().minusDays(5);
+                PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.DISCOUNT);
+                NewEvent ne = createNewEvent(SubscriptionTransitionType.CREATE, aoRecreateDate, spec);
+                
+                SubscriptionRepair saoRepair = createSubscriptionReapir(aoSubscription.getId(), des, Collections.singletonList(ne));
+                
+                BundleRepair bRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(saoRepair));
+                
+                boolean dryRun = true;
+                repairApi.repairBundle(bRepair, dryRun, context);
+            }
+        }, ErrorCode.ENT_REPAIR_AO_CREATE_BEFORE_BP_START);
+    }
+    
     @Test(groups={"fast"}, enabled=false)
     public void testENT_REPAIR_NEW_EVENT_BEFORE_LAST_AO_REMAINING() throws Exception {
         test.withException(new TestWithExceptionCallback() {
@@ -222,7 +268,6 @@ public class TestRepairWithError extends TestApiBaseRepair {
         }, ErrorCode.ENT_REPAIR_MISSING_AO_DELETE_EVENT);
     }
 
-  
     @Test(groups={"fast"}, enabled=false)
     public void testENT_REPAIR_BP_RECREATE_MISSING_AO() throws Exception {
         test.withException(new TestWithExceptionCallback() {