diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlement.java b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlement.java
index 970e1cd..6a99e3b 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlement.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlement.java
@@ -642,7 +642,9 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
final WithEntitlementPlugin<Entitlement> changePlanWithPlugin = new WithEntitlementPlugin<Entitlement>() {
@Override
public Entitlement doCall(final EntitlementApi entitlementApi, final EntitlementContext updatedPluginContext) throws EntitlementApiException {
- if (!eventsStream.isEntitlementActive()) {
+
+ if ((effectiveDate == null && !eventsStream.isEntitlementActive()) ||
+ (effectiveDate != null && effectiveDate.compareTo(eventsStream.getEntitlementEffectiveStartDate()) < 0)) {
throw new EntitlementApiException(ErrorCode.SUB_CHANGE_NON_ACTIVE, getId(), getState());
}
@@ -715,7 +717,9 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
final WithEntitlementPlugin<Entitlement> changePlanWithPlugin = new WithEntitlementPlugin<Entitlement>() {
@Override
public Entitlement doCall(final EntitlementApi entitlementApi, final EntitlementContext updatedPluginContext) throws EntitlementApiException {
- if (!eventsStream.isEntitlementActive()) {
+
+ if ((entitlementEffectiveDate == null && !eventsStream.isEntitlementActive()) ||
+ (entitlementEffectiveDate != null && entitlementEffectiveDate.compareTo(eventsStream.getEntitlementEffectiveStartDate()) < 0)) {
throw new EntitlementApiException(ErrorCode.SUB_CHANGE_NON_ACTIVE, getId(), getState());
}
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlement.java b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlement.java
index 692995f..7d29cb7 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlement.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlement.java
@@ -282,7 +282,7 @@ public class TestDefaultEntitlement extends EntitlementTestSuiteWithEmbeddedDB {
}
@Test(groups = "slow")
- public void testEntitlementStartedInFuture() throws AccountApiException, EntitlementApiException {
+ public void testEntitlementChangePlanOnPendingEntitlement() throws AccountApiException, EntitlementApiException {
final LocalDate initialDate = new LocalDate(2013, 8, 7);
clock.setDay(initialDate);
@@ -298,12 +298,37 @@ public class TestDefaultEntitlement extends EntitlementTestSuiteWithEmbeddedDB {
assertListenerStatus();
assertEquals(entitlement.getState(), EntitlementState.PENDING);
- testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
+ final PlanPhaseSpecifier spec2 = new PlanPhaseSpecifier("pistol-monthly", null);
+ try {
+ entitlement.changePlan(spec2, ImmutableList.<PlanPhasePriceOverride>of(), ImmutableList.<PluginProperty>of(), callContext);
+ Assert.fail("Changing plan immediately prior the subscription is active is not allowed");
+ } catch (EntitlementApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.SUB_CHANGE_NON_ACTIVE.getCode());
+ }
+
+ try {
+ entitlement.changePlanWithDate(spec2, ImmutableList.<PlanPhasePriceOverride>of(), null, ImmutableList.<PluginProperty>of(), callContext);
+ Assert.fail("Changing plan immediately prior the subscription is active is not allowed");
+ } catch (EntitlementApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.SUB_CHANGE_NON_ACTIVE.getCode());
+ }
+
+ try {
+ entitlement.changePlanWithDate(spec2, ImmutableList.<PlanPhasePriceOverride>of(), startDate.minusDays(1), ImmutableList.<PluginProperty>of(), callContext);
+ Assert.fail("Changing plan immediately prior the subscription is active is not allowed");
+ } catch (EntitlementApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.SUB_CHANGE_NON_ACTIVE.getCode());
+ }
+
+ entitlement.changePlanWithDate(spec2, ImmutableList.<PlanPhasePriceOverride>of(), startDate, ImmutableList.<PluginProperty>of(), callContext);
+
+ testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.CHANGE, NextEvent.BLOCK);
clock.addDays(10);
assertListenerStatus();
final Entitlement entitlement1 = entitlementApi.getEntitlementForId(entitlement.getId(), callContext);
assertEquals(entitlement1.getState(), EntitlementState.ACTIVE);
+ assertEquals(entitlement1.getLastActiveProduct().getName(), "Pistol");
}
}