Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2010-2013 Ning, Inc.
   *
   * Ning licenses this file to you under the Apache License, version 2.0
   * (the "License"); you may not use this file except in compliance with the
   * License.  You may obtain a copy of the License at:
   *
   *    http://www.apache.org/licenses/LICENSE-2.0
   *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
  * License for the specific language governing permissions and limitations
  * under the License.
  */
 
 package com.ning.billing.subscription.alignment;
 
 import java.util.List;
 
 import  javax.annotation.Nullable;
 
 
PlanAligner offers specific APIs to return the correct TimedPhase when creating, changing Plan or to compute next Phase on current Plan.
 
 public class PlanAligner extends BaseAligner {
 
     private final CatalogService catalogService;
 
     @Inject
     public PlanAligner(final CatalogService catalogService) {
         this. = catalogService;
     }
 
     private enum WhichPhase {
         CURRENT,
         NEXT
     }

    
Returns the current and next phase for the subscription in creation

Parameters:
subscription the subscription in creation (only the start date and the bundle start date are looked at)
plan the current Plan
initialPhase the initialPhase on which we should create that subscription. can be null
priceList the priceList
requestedDate the requested date (only used to load the catalog)
effectiveDate the effective creation date (driven by the catalog policy, i.e. when the creation occurs)
Returns:
the current and next phases
Throws:
CatalogApiException for catalog errors
com.ning.billing.subscription.api.user.SubscriptionBaseApiException for subscription errors
 
                                                             final Plan plan,
                                                             final PhaseType initialPhase,
                                                             final String priceList,
                                                             final DateTime requestedDate,
                                                             final DateTime effectiveDatethrows CatalogApiExceptionSubscriptionBaseApiException {
         final List<TimedPhasetimedPhases = getTimedPhaseOnCreate(subscription.getAlignStartDate(),
                                                                    subscription.getBundleStartDate(),
                                                                    plan,
                                                                    initialPhase,
                                                                    priceList,
                                                                    requestedDate);
         final TimedPhase[] result = new TimedPhase[2];
         result[0] = getTimedPhase(timedPhaseseffectiveDate.);
         result[1] = getTimedPhase(timedPhaseseffectiveDate.);
         return result;
     }

    
Returns current Phase for that Plan change

Parameters:
subscription the subscription in change (only start date, bundle start date, current phase, plan and pricelist are looked at)
plan the current Plan
priceList the priceList on which we should change that subscription.
requestedDate the requested date
effectiveDate the effective change date (driven by the catalog policy, i.e. when the change occurs)
Returns:
the current phase
Throws:
CatalogApiException for catalog errors
com.ning.billing.subscription.api.user.SubscriptionBaseApiException for subscription errors
                                                   final Plan plan,
                                                   final String priceList,
                                                   final DateTime requestedDate,
                                                   final DateTime effectiveDatethrows CatalogApiExceptionSubscriptionBaseApiException {
        return getTimedPhaseOnChange(subscriptionplanpriceListrequestedDateeffectiveDate.);
    }

    
Returns next Phase for that Plan change

Parameters:
subscription the subscription in change (only start date, bundle start date, current phase, plan and pricelist are looked at)
plan the current Plan
priceList the priceList on which we should change that subscription.
requestedDate the requested date
effectiveDate the effective change date (driven by the catalog policy, i.e. when the change occurs)
Returns:
the next phase
Throws:
CatalogApiException for catalog errors
com.ning.billing.subscription.api.user.SubscriptionBaseApiException for subscription errors
    public TimedPhase getNextTimedPhaseOnChange(final DefaultSubscriptionBase subscription,
                                                final Plan plan,
                                                final String priceList,
                                                final DateTime requestedDate,
                                                final DateTime effectiveDatethrows CatalogApiExceptionSubscriptionBaseApiException {
        return getTimedPhaseOnChange(subscriptionplanpriceListrequestedDateeffectiveDate.);
    }

    
Returns next Phase for that SubscriptionBase at a point in time

Parameters:
subscription the subscription for which we need to compute the next Phase event
requestedDate the requested date
effectiveDate the date at which we look to compute that event. effective needs to be after last Plan change or initial Plan
Returns:
the next phase
    public TimedPhase getNextTimedPhase(final DefaultSubscriptionBase subscriptionfinal DateTime requestedDatefinal DateTime effectiveDate) {
        try {
            final SubscriptionBaseTransitionData lastPlanTransition = subscription.getInitialTransitionForCurrentPlan();
            if (effectiveDate.isBefore(lastPlanTransition.getEffectiveTransitionTime())) {
                throw new SubscriptionBaseError(String.format("Cannot specify an effectiveDate prior to last Plan Change, subscription = %s, effectiveDate = %s",
                                                         subscription.getId(), effectiveDate));
            }
            switch (lastPlanTransition.getTransitionType()) {
                // If we never had any Plan change, borrow the logic for createPlan alignment
                case :
                case :
                case :
                case :
                    final List<TimedPhasetimedPhases = getTimedPhaseOnCreate(subscription.getAlignStartDate(),
                                                                               subscription.getBundleStartDate(),
                                                                               lastPlanTransition.getNextPlan(),
                                                                               lastPlanTransition.getNextPhase().getPhaseType(),
                                                                               lastPlanTransition.getNextPriceList().getName(),
                                                                               requestedDate);
                    return getTimedPhase(timedPhaseseffectiveDate.);
                // If we went through Plan changes, borrow the logic for changePlanWithRequestedDate alignment
                case :
                    return getTimedPhaseOnChange(subscription.getAlignStartDate(),
                                                 subscription.getBundleStartDate(),
                                                 lastPlanTransition.getPreviousPhase(),
                                                 lastPlanTransition.getPreviousPlan(),
                                                 lastPlanTransition.getPreviousPriceList().getName(),
                                                 lastPlanTransition.getNextPlan(),
                                                 lastPlanTransition.getNextPriceList().getName(),
                                                 requestedDate,
                                                 effectiveDate,
                                                 .);
                default:
                    throw new SubscriptionBaseError(String.format("Unexpected initial transition %s for current plan %s on subscription %s",
                                                             lastPlanTransition.getTransitionType(), subscription.getCurrentPlan(), subscription.getId()));
            }
        } catch (Exception /* SubscriptionBaseApiException, CatalogApiException */ e) {
            throw new SubscriptionBaseError(String.format("Could not compute next phase change for subscription %s"subscription.getId()), e);
        }
    }
    private List<TimedPhasegetTimedPhaseOnCreate(final DateTime subscriptionStartDate,
                                                   final DateTime bundleStartDate,
                                                   final Plan plan,
                                                   final PhaseType initialPhase,
                                                   final String priceList,
                                                   final DateTime requestedDate)
            throws CatalogApiExceptionSubscriptionBaseApiException {
        final Catalog catalog = .getFullCatalog();
        final PlanSpecifier planSpecifier = new PlanSpecifier(plan.getProduct().getName(),
                                                              plan.getProduct().getCategory(),
                                                              plan.getBillingPeriod(),
                                                              priceList);
        final DateTime planStartDate;
        final PlanAlignmentCreate alignment = catalog.planCreateAlignment(planSpecifierrequestedDate);
        switch (alignment) {
            case :
                planStartDate = subscriptionStartDate;
                break;
            case :
                planStartDate = bundleStartDate;
                break;
            default:
                throw new SubscriptionBaseError(String.format("Unknown PlanAlignmentCreate %s"alignment));
        }
        return getPhaseAlignments(planinitialPhaseplanStartDate);
    }
    private TimedPhase getTimedPhaseOnChange(final DefaultSubscriptionBase subscription,
                                             final Plan nextPlan,
                                             final String nextPriceList,
                                             final DateTime requestedDate,
                                             final DateTime effectiveDate,
                                             final WhichPhase whichthrows CatalogApiExceptionSubscriptionBaseApiException {
        return getTimedPhaseOnChange(subscription.getAlignStartDate(),
                                     subscription.getBundleStartDate(),
                                     subscription.getCurrentPhase(),
                                     subscription.getCurrentPlan(),
                                     subscription.getCurrentPriceList().getName(),
                                     nextPlan,
                                     nextPriceList,
                                     requestedDate,
                                     effectiveDate,
                                     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 whichthrows CatalogApiExceptionSubscriptionBaseApiException {
        final Catalog catalog = .getFullCatalog();
        final ProductCategory currentCategory = currentPlan.getProduct().getCategory();
        final PlanPhaseSpecifier fromPlanPhaseSpecifier = new PlanPhaseSpecifier(currentPlan.getProduct().getName(),
                                                                                 currentCategory,
                                                                                 currentPlan.getBillingPeriod(),
                                                                                 currentPriceList,
                                                                                 currentPhase.getPhaseType());
        final PlanSpecifier toPlanSpecifier = new PlanSpecifier(nextPlan.getProduct().getName(),
                                                                nextPlan.getProduct().getCategory(),
                                                                nextPlan.getBillingPeriod(),
                                                                priceList);
        final DateTime planStartDate;
        final PlanAlignmentChange alignment = catalog.planChangeAlignment(fromPlanPhaseSpecifiertoPlanSpecifierrequestedDate);
        switch (alignment) {
            case :
                planStartDate = subscriptionStartDate;
                break;
            case :
                planStartDate = bundleStartDate;
                break;
            case :
                planStartDate = effectiveDate;
                break;
            case :
                throw new SubscriptionBaseError(String.format("Not implemented yet %s"alignment));
            default:
                throw new SubscriptionBaseError(String.format("Unknown PlanAlignmentChange %s"alignment));
        }
        final List<TimedPhasetimedPhases = getPhaseAlignments(nextPlannullplanStartDate);
        return getTimedPhase(timedPhaseseffectiveDatewhich);
    }
    private List<TimedPhasegetPhaseAlignments(final Plan plan, @Nullable final PhaseType initialPhasefinal DateTime initialPhaseStartDatethrows SubscriptionBaseApiException {
        if (plan == null) {
            return Collections.emptyList();
        }
        final List<TimedPhaseresult = new LinkedList<TimedPhase>();
        DateTime curPhaseStart = (initialPhase == null) ? initialPhaseStartDate : 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) {
                if (initialPhase != cur.getPhaseType()) {
                    continue;
                }
                curPhaseStart = initialPhaseStartDate;
            }
            result.add(new TimedPhase(curcurPhaseStart));
            // STEPH check for duration null instead TimeUnit UNLIMITED
            if (cur.getPhaseType() != .) {
                final Duration curPhaseDuration = cur.getDuration();
                nextPhaseStart = addDuration(curPhaseStartcurPhaseDuration);
                if (nextPhaseStart == null) {
                    throw new SubscriptionBaseError(String.format("Unexpected non ending UNLIMITED phase for plan %s",
                                                             plan.getName()));
                }
                curPhaseStart = nextPhaseStart;
            }
        }
        if (initialPhase != null && curPhaseStart == null) {
            throw new SubscriptionBaseApiException(.initialPhase);
        }
        return result;
    }
    // STEPH check for non evergreen Plans and what happens
    private TimedPhase getTimedPhase(final List<TimedPhasetimedPhasesfinal DateTime effectiveDatefinal WhichPhase which) {
        TimedPhase cur = null;
        TimedPhase next = null;
        for (final TimedPhase phase : timedPhases) {
            if (phase.getStartPhase().isAfter(effectiveDate)) {
                next = phase;
                break;
            }
            cur = phase;
        }
        switch (which) {
            case :
                return cur;
            case :
                return next;
            default:
                throw new SubscriptionBaseError(String.format("Unexpected %s TimedPhase"which));
        }
    }
New to GrepCode? Check out our FAQ X