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.api.user;
 
 import java.util.List;
 import java.util.UUID;
 
 
 
 
 
     private final Clock clock;
     private final SubscriptionDao dao;
     private final CatalogService catalogService;
     private final PlanAligner planAligner;
     private final AddonUtils addonUtils;
 
     @Inject
     public DefaultSubscriptionBaseApiService(final Clock clockfinal SubscriptionDao daofinal CatalogService catalogService,
                                              final PlanAligner planAlignerfinal AddonUtils addonUtils,
                                              final InternalCallContextFactory internalCallContextFactory) {
         this. = clock;
         this. = catalogService;
         this. = planAligner;
         this. = dao;
         this. = addonUtils;
         this. = internalCallContextFactory;
     }
 
     @Override
     public DefaultSubscriptionBase createPlan(final SubscriptionBuilder builderfinal Plan planfinal PhaseType initialPhase,
                                               final String realPriceListfinal DateTime requestedDatefinal DateTime effectiveDatefinal DateTime processedDate,
                                               final CallContext contextthrows SubscriptionBaseApiException {
         final DefaultSubscriptionBase subscription = new DefaultSubscriptionBase(builderthis);
 
         createFromSubscription(subscriptionplaninitialPhaserealPriceListrequestedDateeffectiveDateprocessedDatefalsecontext);
         return subscription;
     }
 
     @Deprecated
    @Override
    public boolean recreatePlan(final DefaultSubscriptionBase subscriptionfinal PlanPhaseSpecifier specfinal DateTime requestedDateWithMsfinal CallContext context)
            throws SubscriptionBaseApiException {
        final EntitlementState currentState = subscription.getState();
        if (currentState != null && currentState != .) {
            throw new SubscriptionBaseApiException(.subscription.getId(), currentState);
        }
        final DateTime now = .getUTCNow();
        final DateTime effectiveDate = (requestedDateWithMs != null) ? DefaultClock.truncateMs(requestedDateWithMs) : now;
        validateEffectiveDate(subscriptioneffectiveDate);
        try {
            final String realPriceList = (spec.getPriceListName() == null) ? . : spec.getPriceListName();
            final Plan plan = .getFullCatalog().findPlan(spec.getProductName(), spec.getBillingPeriod(), realPriceListeffectiveDate);
            final PlanPhase phase = plan.getAllPhases()[0];
            if (phase == null) {
                throw new SubscriptionBaseError(String.format("No initial PlanPhase for Product %s, term %s and set %s does not exist in the catalog",
                                                              spec.getProductName(), spec.getBillingPeriod().toString(), realPriceList));
            }
            final DateTime processedDate = now;
            createFromSubscription(subscriptionplanspec.getPhaseType(), realPriceListnoweffectiveDateprocessedDatetruecontext);
            return true;
        } catch (CatalogApiException e) {
            throw new SubscriptionBaseApiException(e);
        }
    }
    private void createFromSubscription(final DefaultSubscriptionBase subscriptionfinal Plan planfinal PhaseType initialPhase,
                                        final String realPriceListfinal DateTime requestedDatefinal DateTime effectiveDatefinal DateTime processedDate,
                                        final boolean reCreatefinal CallContext contextthrows SubscriptionBaseApiException {
        final InternalCallContext internalCallContext = createCallContextFromBundleId(subscription.getBundleId(), context);
        try {
            final TimedPhase[] curAndNextPhases = .getCurrentAndNextTimedPhaseOnCreate(subscriptionplaninitialPhaserealPriceListrequestedDateeffectiveDate);
            final ApiEventBuilder createBuilder = new ApiEventBuilder()
                    .setSubscriptionId(subscription.getId())
                    .setEventPlan(plan.getName())
                    .setEventPlanPhase(curAndNextPhases[0].getPhase().getName())
                    .setEventPriceList(realPriceList)
                    .setActiveVersion(subscription.getActiveVersion())
                    .setProcessedDate(processedDate)
                    .setEffectiveDate(effectiveDate)
                    .setRequestedDate(requestedDate)
                    .setFromDisk(true);
            final ApiEvent creationEvent = (reCreate) ? new ApiEventReCreate(createBuilder) : new ApiEventCreate(createBuilder);
            final TimedPhase nextTimedPhase = curAndNextPhases[1];
            final PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ?
                                              PhaseEventData.createNextPhaseEvent(nextTimedPhase.getPhase().getName(), subscriptionprocessedDatenextTimedPhase.getStartPhase()) :
                                              null;
            final List<SubscriptionBaseEventevents = new ArrayList<SubscriptionBaseEvent>();
            events.add(creationEvent);
            if (nextPhaseEvent != null) {
                events.add(nextPhaseEvent);
            }
            if (reCreate) {
                .recreateSubscription(subscriptioneventsinternalCallContext);
            } else {
                .createSubscription(subscriptioneventsinternalCallContext);
            }
            subscription.rebuildTransitions(.getEventsForSubscription(subscription.getId(), internalCallContext), .getFullCatalog());
        } catch (CatalogApiException e) {
            throw new SubscriptionBaseApiException(e);
        }
    }
    @Override
    public boolean cancel(final DefaultSubscriptionBase subscriptionfinal CallContext contextthrows SubscriptionBaseApiException {
        final EntitlementState currentState = subscription.getState();
        if (currentState != .) {
            throw new SubscriptionBaseApiException(.subscription.getId(), currentState);
        }
        final DateTime now = .getUTCNow();
        final Plan currentPlan = subscription.getCurrentPlan();
        final PlanPhaseSpecifier planPhase = new PlanPhaseSpecifier(currentPlan.getProduct().getName(),
                                                                    currentPlan.getProduct().getCategory(),
                                                                    subscription.getCurrentPlan().getBillingPeriod(),
                                                                    subscription.getCurrentPriceList().getName(),
                                                                    subscription.getCurrentPhase().getPhaseType());
        try {
            final BillingActionPolicy policy = .getFullCatalog().planCancelPolicy(planPhasenow);
            final DateTime effectiveDate = subscription.getPlanChangeEffectiveDate(policy);
            return doCancelPlan(subscriptionnoweffectiveDatecontext);
        } catch (CatalogApiException e) {
            throw new SubscriptionBaseApiException(e);
        }
    }
    @Override
    public boolean cancelWithRequestedDate(final DefaultSubscriptionBase subscriptionfinal DateTime requestedDateWithMsfinal CallContext contextthrows SubscriptionBaseApiException {
        final EntitlementState currentState = subscription.getState();
        if (currentState != .) {
            throw new SubscriptionBaseApiException(.subscription.getId(), currentState);
        }
        final DateTime now = .getUTCNow();
        final DateTime effectiveDate = (requestedDateWithMs != null) ? DefaultClock.truncateMs(requestedDateWithMs) : now;
        return doCancelPlan(subscriptionnoweffectiveDatecontext);
    }
    @Override
    public boolean cancelWithPolicy(final DefaultSubscriptionBase subscriptionfinal BillingActionPolicy policyfinal CallContext contextthrows SubscriptionBaseApiException {
        final EntitlementState currentState = subscription.getState();
        if (currentState != .) {
            throw new SubscriptionBaseApiException(.subscription.getId(), currentState);
        }
        final DateTime now = .getUTCNow();
        final DateTime effectiveDate = subscription.getPlanChangeEffectiveDate(policy);
        return doCancelPlan(subscriptionnoweffectiveDatecontext);
    }
    private boolean doCancelPlan(final DefaultSubscriptionBase subscriptionfinal DateTime nowfinal DateTime effectiveDatefinal CallContext contextthrows SubscriptionBaseApiException {
        validateEffectiveDate(subscriptioneffectiveDate);
        final SubscriptionBaseEvent cancelEvent = new ApiEventCancel(new ApiEventBuilder()
                                                                             .setSubscriptionId(subscription.getId())
                                                                             .setActiveVersion(subscription.getActiveVersion())
                                                                             .setProcessedDate(now)
                                                                             .setEffectiveDate(effectiveDate)
                                                                             .setRequestedDate(now)
                                                                             .setFromDisk(true));
        final InternalCallContext internalCallContext = createCallContextFromBundleId(subscription.getBundleId(), context);
        .cancelSubscription(subscriptioncancelEventinternalCallContext, 0);
        subscription.rebuildTransitions(.getEventsForSubscription(subscription.getId(), internalCallContext), .getFullCatalog());
        if (subscription.getCategory() == .) {
            cancelAddOnsIfRequired(subscriptioneffectiveDateinternalCallContext);
        }
        final boolean isImmediate = subscription.getState() == .;
        return isImmediate;
    }
    @Override
    public boolean uncancel(final DefaultSubscriptionBase subscriptionfinal CallContext contextthrows SubscriptionBaseApiException {
        if (!subscription.isSubscriptionFutureCancelled()) {
            throw new SubscriptionBaseApiException(.subscription.getId().toString());
        }
        final DateTime now = .getUTCNow();
        final SubscriptionBaseEvent uncancelEvent = new ApiEventUncancel(new ApiEventBuilder()
                                                                                 .setSubscriptionId(subscription.getId())
                                                                                 .setActiveVersion(subscription.getActiveVersion())
                                                                                 .setProcessedDate(now)
                                                                                 .setRequestedDate(now)
                                                                                 .setEffectiveDate(now)
                                                                                 .setFromDisk(true));
        final List<SubscriptionBaseEventuncancelEvents = new ArrayList<SubscriptionBaseEvent>();
        uncancelEvents.add(uncancelEvent);
        final TimedPhase nextTimedPhase = .getNextTimedPhase(subscriptionnownow);
        final PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ?
                                          PhaseEventData.createNextPhaseEvent(nextTimedPhase.getPhase().getName(), subscriptionnownextTimedPhase.getStartPhase()) :
                                          null;
        if (nextPhaseEvent != null) {
            uncancelEvents.add(nextPhaseEvent);
        }
        final InternalCallContext internalCallContext = createCallContextFromBundleId(subscription.getBundleId(), context);
        .uncancelSubscription(subscriptionuncancelEventsinternalCallContext);
        subscription.rebuildTransitions(.getEventsForSubscription(subscription.getId(), internalCallContext), .getFullCatalog());
        return true;
    }
    @Override
    public DateTime changePlan(final DefaultSubscriptionBase subscriptionfinal String productNamefinal BillingPeriod term,
                               final String priceListfinal CallContext contextthrows SubscriptionBaseApiException {
        final DateTime now = .getUTCNow();
        validateEntitlementState(subscription);
        final PlanChangeResult planChangeResult = getPlanChangeResult(subscriptionproductNametermpriceListnow);
        final DateTime effectiveDate = subscription.getPlanChangeEffectiveDate(planChangeResult.getPolicy());
        validateEffectiveDate(subscriptioneffectiveDate);
        try {
            return doChangePlan(subscriptionproductNametermplanChangeResult.getNewPriceList().getName(), noweffectiveDatecontext);
        } catch (CatalogApiException e) {
            throw new SubscriptionBaseApiException(e);
        }
    }
    @Override
    public DateTime changePlanWithRequestedDate(final DefaultSubscriptionBase subscriptionfinal String productNamefinal BillingPeriod term,
                                                final String priceListfinal DateTime requestedDateWithMsfinal CallContext contextthrows SubscriptionBaseApiException {
        final DateTime now = .getUTCNow();
        final DateTime effectiveDate = (requestedDateWithMs != null) ? DefaultClock.truncateMs(requestedDateWithMs) : now;
        validateEffectiveDate(subscriptioneffectiveDate);
        validateEntitlementState(subscription);
        try {
            return doChangePlan(subscriptionproductNametermpriceListnoweffectiveDatecontext);
        } catch (CatalogApiException e) {
            throw new SubscriptionBaseApiException(e);
        }
    }
    @Override
    public DateTime changePlanWithPolicy(final DefaultSubscriptionBase subscriptionfinal String productNamefinal BillingPeriod term,
                                         final String priceListfinal BillingActionPolicy policyfinal CallContext context)
            throws SubscriptionBaseApiException {
        final DateTime now = .getUTCNow();
        validateEntitlementState(subscription);
        final DateTime effectiveDate = subscription.getPlanChangeEffectiveDate(policy);
        try {
            return doChangePlan(subscriptionproductNametermpriceListnoweffectiveDatecontext);
        } catch (CatalogApiException e) {
            throw new SubscriptionBaseApiException(e);
        }
    }
    private PlanChangeResult getPlanChangeResult(final DefaultSubscriptionBase subscriptionfinal String productName,
                                                 final BillingPeriod termfinal String priceListfinal DateTime effectiveDatethrows SubscriptionBaseApiException {
        final PlanChangeResult planChangeResult;
        try {
            final Product destProduct = .getFullCatalog().findProduct(productNameeffectiveDate);
            final Plan currentPlan = subscription.getCurrentPlan();
            final PriceList currentPriceList = subscription.getCurrentPriceList();
            final PlanPhaseSpecifier fromPlanPhase = new PlanPhaseSpecifier(currentPlan.getProduct().getName(),
                                                                            currentPlan.getProduct().getCategory(),
                                                                            currentPlan.getBillingPeriod(),
                                                                            currentPriceList.getName(),
                                                                            subscription.getCurrentPhase().getPhaseType());
            final PlanSpecifier toPlanPhase = new PlanSpecifier(productName,
                                                                destProduct.getCategory(),
                                                                term,
                                                                priceList);
            planChangeResult = .getFullCatalog().planChange(fromPlanPhasetoPlanPhaseeffectiveDate);
        } catch (CatalogApiException e) {
            throw new SubscriptionBaseApiException(e);
        }
        return planChangeResult;
    }
    private DateTime doChangePlan(final DefaultSubscriptionBase subscription,
                                  final String newProductName,
                                  final BillingPeriod newBillingPeriod,
                                  final String newPriceList,
                                  final DateTime now,
                                  final DateTime effectiveDate,
                                  final CallContext contextthrows SubscriptionBaseApiExceptionCatalogApiException {
        final Plan newPlan = .getFullCatalog().findPlan(newProductNamenewBillingPeriodnewPriceListeffectiveDatesubscription.getStartDate());
        final TimedPhase currentTimedPhase = .getCurrentTimedPhaseOnChange(subscriptionnewPlannewPriceListnoweffectiveDate);
        final SubscriptionBaseEvent changeEvent = new ApiEventChange(new ApiEventBuilder()
                                                                             .setSubscriptionId(subscription.getId())
                                                                             .setEventPlan(newPlan.getName())
                                                                             .setEventPlanPhase(currentTimedPhase.getPhase().getName())
                                                                             .setEventPriceList(newPriceList)
                                                                             .setActiveVersion(subscription.getActiveVersion())
                                                                             .setProcessedDate(now)
                                                                             .setEffectiveDate(effectiveDate)
                                                                             .setRequestedDate(now)
                                                                             .setFromDisk(true));
        final TimedPhase nextTimedPhase = .getNextTimedPhaseOnChange(subscriptionnewPlannewPriceListnoweffectiveDate);
        final PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ?
                                          PhaseEventData.createNextPhaseEvent(nextTimedPhase.getPhase().getName(), subscriptionnownextTimedPhase.getStartPhase()) :
                                          null;
        final List<SubscriptionBaseEventchangeEvents = new ArrayList<SubscriptionBaseEvent>();
        // 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);
        final InternalCallContext internalCallContext = createCallContextFromBundleId(subscription.getBundleId(), context);
        .changePlan(subscriptionchangeEventsinternalCallContext);
        subscription.rebuildTransitions(.getEventsForSubscription(subscription.getId(), internalCallContext), .getFullCatalog());
        if (subscription.getCategory() == .) {
            cancelAddOnsIfRequired(subscriptioneffectiveDateinternalCallContext);
        }
        final boolean isChangeImmediate = subscription.getCurrentPlan().getProduct().getName().equals(newProductName) &&
                                          subscription.getCurrentPlan().getBillingPeriod() == newBillingPeriod;
        return effectiveDate;
    }
    public int cancelAddOnsIfRequired(final DefaultSubscriptionBase baseSubscriptionfinal DateTime effectiveDatefinal InternalCallContext context) {
        // If cancellation/change occur in the future, there is nothing to do
        final DateTime now = .getUTCNow();
        if (effectiveDate.compareTo(now) > 0) {
            return 0;
        }
        final Product baseProduct = (baseSubscription.getState() == .) ? null : baseSubscription.getCurrentPlan().getProduct();
        final List<SubscriptionBasesubscriptions = .getSubscriptions(baseSubscription.getBundleId(), context);
        final List<DefaultSubscriptionBasesubscriptionsToBeCancelled = new LinkedList<DefaultSubscriptionBase>();
        final List<SubscriptionBaseEventcancelEvents = new LinkedList<SubscriptionBaseEvent>();
        for (final SubscriptionBase subscription : subscriptions) {
            final DefaultSubscriptionBase cur = (DefaultSubscriptionBasesubscription;
            if (cur.getState() == . ||
                cur.getCategory() != .) {
                continue;
            }
            final Plan addonCurrentPlan = cur.getCurrentPlan();
            if (baseProduct == null ||
                .isAddonIncluded(baseProductaddonCurrentPlan) ||
                !.isAddonAvailable(baseProductaddonCurrentPlan)) {
                //
                // Perform AO cancellation using the effectiveDate of the BP
                //
                final SubscriptionBaseEvent cancelEvent = new ApiEventCancel(new ApiEventBuilder()
                                                                                     .setSubscriptionId(cur.getId())
                                                                                     .setActiveVersion(cur.getActiveVersion())
                                                                                     .setProcessedDate(now)
                                                                                     .setEffectiveDate(effectiveDate)
                                                                                     .setRequestedDate(now)
                                                                                     .setFromDisk(true));
                subscriptionsToBeCancelled.add(cur);
                cancelEvents.add(cancelEvent);
            }
        }
        .cancelSubscriptions(subscriptionsToBeCancelledcancelEventscontext);
        return subscriptionsToBeCancelled.size();
    }
    private void validateEffectiveDate(final DefaultSubscriptionBase subscriptionfinal DateTime effectiveDatethrows SubscriptionBaseApiException {
        final SubscriptionBaseTransition previousTransition = subscription.getPreviousTransition();
        if (previousTransition != null && previousTransition.getEffectiveTransitionTime().isAfter(effectiveDate)) {
                                                   effectiveDate.toString(), previousTransition.getEffectiveTransitionTime());
        }
    }
    private void validateEntitlementState(final DefaultSubscriptionBase subscriptionthrows SubscriptionBaseApiException {
        final EntitlementState currentState = subscription.getState();
        if (currentState != .) {
            throw new SubscriptionBaseApiException(.subscription.getId(), currentState);
        }
        if (subscription.isSubscriptionFutureCancelled()) {
            throw new SubscriptionBaseApiException(.subscription.getId());
        }
    }
    private InternalCallContext createCallContextFromBundleId(final UUID bundleIdfinal CallContext context) {
        return .createInternalCallContext(bundleId.context);
    }
New to GrepCode? Check out our FAQ X