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/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();
}