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 d31452d..289927b 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
@@ -16,6 +16,7 @@
package com.ning.billing.entitlement.alignment;
+import javax.annotation.Nullable;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
@@ -43,11 +44,10 @@ import com.ning.billing.entitlement.exceptions.EntitlementError;
import com.ning.billing.util.clock.DefaultClock;
/**
- * PlanAligner offers specific APIs to return the correct {@code TimedPhase} when creating, changing Plan or to compute next Phase on current Plan.
- * <p/>
+ * PlanAligner offers specific APIs to return the correct {@code TimedPhase} when creating, changing Plan or to compute
+ * next Phase on current Plan.
*/
public class PlanAligner {
-
private final CatalogService catalogService;
@Inject
@@ -62,22 +62,29 @@ public class PlanAligner {
/**
* Returns the current and next phase for the subscription in creation
- * <p/>
*
* @param subscription the subscription in creation
* @param plan the current Plan
* @param initialPhase the initialPhase on which we should create that subscription. can be null
* @param priceList the priceList
+ * @param requestedDate the requested date
* @param effectiveDate the effective creation date
- * @return
- * @throws CatalogApiException
- * @throws EntitlementUserApiException
+ * @return the current and next phase
+ * @throws CatalogApiException for catalog errors
+ * @throws EntitlementUserApiException for entitlement errors
*/
public TimedPhase[] getCurrentAndNextTimedPhaseOnCreate(final SubscriptionData subscription,
- final Plan plan, final PhaseType initialPhase, final String priceList, final DateTime requestedDate, final DateTime effectiveDate)
- throws CatalogApiException, EntitlementUserApiException {
+ final Plan plan,
+ final PhaseType initialPhase,
+ final String priceList,
+ final DateTime requestedDate,
+ final DateTime effectiveDate) throws CatalogApiException, EntitlementUserApiException {
final List<TimedPhase> timedPhases = getTimedPhaseOnCreate(subscription.getStartDate(),
- subscription.getBundleStartDate(), plan, initialPhase, priceList, requestedDate);
+ subscription.getBundleStartDate(),
+ plan,
+ initialPhase,
+ priceList,
+ requestedDate);
final TimedPhase[] result = new TimedPhase[2];
result[0] = getTimedPhase(timedPhases, effectiveDate, WhichPhase.CURRENT);
result[1] = getTimedPhase(timedPhases, effectiveDate, WhichPhase.NEXT);
@@ -86,52 +93,55 @@ public class PlanAligner {
/**
* Returns current Phase for that Plan change
- * <p/>
*
* @param subscription the subscription in creation
* @param plan the current Plan
* @param priceList the priceList on which we should change that subscription.
+ * @param requestedDate the requested date
* @param effectiveDate the effective change date
- * @return
- * @throws CatalogApiException
- * @throws EntitlementUserApiException
+ * @return the current phase
+ * @throws CatalogApiException for catalog errors
+ * @throws EntitlementUserApiException for entitlement errors
*/
public TimedPhase getCurrentTimedPhaseOnChange(final SubscriptionData subscription,
- final Plan plan, final String priceList, final DateTime requestedDate, final DateTime effectiveDate)
- throws CatalogApiException, EntitlementUserApiException {
+ final Plan plan,
+ final String priceList,
+ final DateTime requestedDate,
+ final DateTime effectiveDate) throws CatalogApiException, EntitlementUserApiException {
return getTimedPhaseOnChange(subscription, plan, priceList, requestedDate, effectiveDate, WhichPhase.CURRENT);
}
/**
* Returns next Phase for that Plan change
- * <p/>
*
* @param subscription the subscription in creation
* @param plan the current Plan
* @param priceList the priceList on which we should change that subscription.
+ * @param requestedDate the requested date
* @param effectiveDate the effective change date
- * @return
- * @throws CatalogApiException
- * @throws EntitlementUserApiException
+ * @return the next phase
+ * @throws CatalogApiException for catalog errors
+ * @throws EntitlementUserApiException for entitlement errors
*/
public TimedPhase getNextTimedPhaseOnChange(final SubscriptionData subscription,
- final Plan plan, final String priceList, final DateTime requestedDate, final DateTime effectiveDate)
- throws CatalogApiException, EntitlementUserApiException {
+ final Plan plan,
+ final String priceList,
+ final DateTime requestedDate,
+ final DateTime effectiveDate) throws CatalogApiException, EntitlementUserApiException {
return getTimedPhaseOnChange(subscription, plan, priceList, requestedDate, effectiveDate, WhichPhase.NEXT);
}
-
/**
* Returns next Phase for that Subscription at a point in time
* <p/>
*
* @param subscription the subscription for which we need to compute the next Phase event
+ * @param requestedDate the requested date
* @param effectiveDate the date at which we look to compute that event. effective needs to be after last Plan change or initial Plan
* @return The PhaseEvent at the correct point in time
*/
public TimedPhase getNextTimedPhase(final SubscriptionData subscription, final DateTime requestedDate, final DateTime effectiveDate) {
try {
-
final SubscriptionTransitionData lastPlanTransition = subscription.getInitialTransitionForCurrentPlan();
if (effectiveDate.isBefore(lastPlanTransition.getEffectiveTransitionTime())) {
throw new EntitlementError(String.format("Cannot specify an effectiveDate prior to last Plan Change, subscription = %s, effectiveDate = %s",
@@ -139,18 +149,18 @@ public class PlanAligner {
}
switch (lastPlanTransition.getTransitionType()) {
- // If we never had any Plan change, borrow the logics for createPlan alignment
+ // If we never had any Plan change, borrow the logic for createPlan alignment
case MIGRATE_ENTITLEMENT:
case CREATE:
case RE_CREATE:
final List<TimedPhase> timedPhases = getTimedPhaseOnCreate(subscription.getStartDate(),
- subscription.getBundleStartDate(),
- lastPlanTransition.getNextPlan(),
- lastPlanTransition.getNextPhase().getPhaseType(),
- lastPlanTransition.getNextPriceList().getName(),
- requestedDate);
+ subscription.getBundleStartDate(),
+ lastPlanTransition.getNextPlan(),
+ lastPlanTransition.getNextPhase().getPhaseType(),
+ lastPlanTransition.getNextPriceList().getName(),
+ requestedDate);
return getTimedPhase(timedPhases, effectiveDate, WhichPhase.NEXT);
- // If we went through Plan changes, borrow the logics for changePlan alignement
+ // If we went through Plan changes, borrow the logics for changePlan alignment
case CHANGE:
return getTimedPhaseOnChange(subscription.getStartDate(),
subscription.getBundleStartDate(),
@@ -163,7 +173,7 @@ public class PlanAligner {
effectiveDate,
WhichPhase.NEXT);
default:
- throw new EntitlementError(String.format("Unexpectd initial transition %s for current plan %s on subscription %s",
+ throw new EntitlementError(String.format("Unexpected initial transition %s for current plan %s on subscription %s",
lastPlanTransition.getTransitionType(), subscription.getCurrentPlan(), subscription.getId()));
}
} catch (Exception /* EntitlementUserApiException, CatalogApiException */ e) {
@@ -171,22 +181,23 @@ public class PlanAligner {
}
}
-
private List<TimedPhase> getTimedPhaseOnCreate(final DateTime subscriptionStartDate,
final DateTime bundleStartDate,
- final Plan plan, final PhaseType initialPhase, final String priceList, final DateTime requestedDate)
+ final Plan plan,
+ final PhaseType initialPhase,
+ final String priceList,
+ final DateTime requestedDate)
throws CatalogApiException, EntitlementUserApiException {
-
final Catalog catalog = catalogService.getFullCatalog();
final PlanSpecifier planSpecifier = new PlanSpecifier(plan.getProduct().getName(),
- plan.getProduct().getCategory(),
- plan.getBillingPeriod(),
- priceList);
+ plan.getProduct().getCategory(),
+ plan.getBillingPeriod(),
+ priceList);
- DateTime planStartDate = null;
- final PlanAlignmentCreate alignement = catalog.planCreateAlignment(planSpecifier, requestedDate);
- switch (alignement) {
+ final DateTime planStartDate;
+ final PlanAlignmentCreate alignment = catalog.planCreateAlignment(planSpecifier, requestedDate);
+ switch (alignment) {
case START_OF_SUBSCRIPTION:
planStartDate = subscriptionStartDate;
break;
@@ -194,14 +205,18 @@ public class PlanAligner {
planStartDate = bundleStartDate;
break;
default:
- throw new EntitlementError(String.format("Unknwon PlanAlignmentCreate %s", alignement));
+ throw new EntitlementError(String.format("Unknown PlanAlignmentCreate %s", alignment));
}
+
return getPhaseAlignments(plan, initialPhase, planStartDate);
}
private TimedPhase getTimedPhaseOnChange(final SubscriptionData subscription,
- final Plan nextPlan, final String nextPriceList, final DateTime requestedDate, final DateTime effectiveDate, final WhichPhase which)
- throws CatalogApiException, EntitlementUserApiException {
+ final Plan nextPlan,
+ final String nextPriceList,
+ final DateTime requestedDate,
+ final DateTime effectiveDate,
+ final WhichPhase which) throws CatalogApiException, EntitlementUserApiException {
return getTimedPhaseOnChange(subscription.getStartDate(),
subscription.getBundleStartDate(),
subscription.getCurrentPhase(),
@@ -214,29 +229,30 @@ public class PlanAligner {
which);
}
-
private TimedPhase getTimedPhaseOnChange(final DateTime subscriptionStartDate,
final DateTime bundleStartDate,
final PlanPhase currentPhase,
final Plan currentPlan,
final String currentPriceList,
- final Plan nextPlan, final String priceList, final DateTime requestedDate, final DateTime effectiveDate, final WhichPhase which)
- throws CatalogApiException, EntitlementUserApiException {
-
+ final Plan nextPlan,
+ final String priceList,
+ final DateTime requestedDate,
+ final DateTime effectiveDate,
+ final WhichPhase which) throws CatalogApiException, EntitlementUserApiException {
final Catalog catalog = catalogService.getFullCatalog();
final ProductCategory currentCategory = currentPlan.getProduct().getCategory();
final PlanPhaseSpecifier fromPlanPhaseSpecifier = new PlanPhaseSpecifier(currentPlan.getProduct().getName(),
- currentCategory,
- currentPlan.getBillingPeriod(),
- currentPriceList,
- currentPhase.getPhaseType());
+ currentCategory,
+ currentPlan.getBillingPeriod(),
+ currentPriceList,
+ currentPhase.getPhaseType());
final PlanSpecifier toPlanSpecifier = new PlanSpecifier(nextPlan.getProduct().getName(),
- nextPlan.getProduct().getCategory(),
- nextPlan.getBillingPeriod(),
- priceList);
+ nextPlan.getProduct().getCategory(),
+ nextPlan.getBillingPeriod(),
+ priceList);
- DateTime planStartDate = null;
+ final DateTime planStartDate;
final PlanAlignmentChange alignment = catalog.planChangeAlignment(fromPlanPhaseSpecifier, toPlanSpecifier, requestedDate);
switch (alignment) {
case START_OF_SUBSCRIPTION:
@@ -251,22 +267,21 @@ public class PlanAligner {
case CHANGE_OF_PRICELIST:
throw new EntitlementError(String.format("Not implemented yet %s", alignment));
default:
- throw new EntitlementError(String.format("Unknwon PlanAlignmentChange %s", alignment));
+ throw new EntitlementError(String.format("Unknown PlanAlignmentChange %s", alignment));
}
+
final List<TimedPhase> timedPhases = getPhaseAlignments(nextPlan, null, planStartDate);
return getTimedPhase(timedPhases, effectiveDate, which);
}
-
- private List<TimedPhase> getPhaseAlignments(final Plan plan, final PhaseType initialPhase, final DateTime initialPhaseStartDate)
- throws EntitlementUserApiException {
+ private List<TimedPhase> getPhaseAlignments(final Plan plan, @Nullable final PhaseType initialPhase, final DateTime initialPhaseStartDate) throws EntitlementUserApiException {
if (plan == null) {
return Collections.emptyList();
}
final List<TimedPhase> result = new LinkedList<TimedPhase>();
DateTime curPhaseStart = (initialPhase == null) ? initialPhaseStartDate : null;
- DateTime nextPhaseStart = null;
+ DateTime nextPhaseStart;
for (final PlanPhase cur : plan.getAllPhases()) {
// For create we can specify the phase so skip any phase until we reach initialPhase
if (curPhaseStart == null) {
@@ -289,9 +304,11 @@ public class PlanAligner {
curPhaseStart = nextPhaseStart;
}
}
+
if (initialPhase != null && curPhaseStart == null) {
throw new EntitlementUserApiException(ErrorCode.ENT_CREATE_BAD_PHASE, initialPhase);
}
+
return result;
}
@@ -306,6 +323,7 @@ public class PlanAligner {
}
cur = phase;
}
+
switch (which) {
case CURRENT:
return cur;