Search in sources :

Example 51 with SubscriptionBaseEvent

use of org.killbill.billing.subscription.events.SubscriptionBaseEvent in project killbill by killbill.

the class DefaultSubscriptionBaseApiService method doCancelPlan.

private boolean doCancelPlan(final Map<DefaultSubscriptionBase, DateTime> subscriptions, final SubscriptionCatalog catalog, final InternalCallContext internalCallContext) throws SubscriptionBaseApiException {
    final List<DefaultSubscriptionBase> subscriptionsToBeCancelled = new LinkedList<DefaultSubscriptionBase>();
    final List<SubscriptionBaseEvent> cancelEvents = new LinkedList<SubscriptionBaseEvent>();
    try {
        for (final DefaultSubscriptionBase subscription : subscriptions.keySet()) {
            final EntitlementState currentState = subscription.getState();
            if (currentState == EntitlementState.CANCELLED) {
                throw new SubscriptionBaseApiException(ErrorCode.SUB_CANCEL_BAD_STATE, subscription.getId(), currentState);
            }
            final DateTime effectiveDate = subscriptions.get(subscription);
            // If subscription was future cancelled at an earlier date we disallow the operation -- i.e,
            // user should first uncancel prior trying to cancel again.
            // However, note that in case a future cancellation already exists with a greater or equal effectiveDate,
            // the operation is allowed, but such existing cancellation would become invalidated (is_active=0)
            final SubscriptionBaseTransition pendingTransition = subscription.getPendingTransition();
            if (pendingTransition != null && pendingTransition.getTransitionType() == SubscriptionBaseTransitionType.CANCEL && pendingTransition.getEffectiveTransitionTime().compareTo(effectiveDate) < 0) {
                throw new SubscriptionBaseApiException(ErrorCode.SUB_CANCEL_BAD_STATE, subscription.getId(), "PENDING CANCELLED");
            }
            validateEffectiveDate(subscription, effectiveDate);
            subscriptionsToBeCancelled.add(subscription);
            cancelEvents.addAll(getEventsOnCancelPlan(subscription, effectiveDate, false, catalog, internalCallContext));
            if (subscription.getCategory() == ProductCategory.BASE) {
                subscriptionsToBeCancelled.addAll(computeAddOnsToCancel(cancelEvents, null, subscription.getBundleId(), effectiveDate, catalog, internalCallContext));
            }
        }
        dao.cancelSubscriptions(subscriptionsToBeCancelled, cancelEvents, catalog, internalCallContext);
        boolean allSubscriptionsCancelled = true;
        for (final DefaultSubscriptionBase subscription : subscriptions.keySet()) {
            subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId(), internalCallContext), catalog);
            allSubscriptionsCancelled = allSubscriptionsCancelled && (subscription.getState() == EntitlementState.CANCELLED);
        }
        return allSubscriptionsCancelled;
    } catch (final CatalogApiException e) {
        throw new SubscriptionBaseApiException(e);
    }
}
Also used : CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent) LinkedList(java.util.LinkedList) EntitlementState(org.killbill.billing.entitlement.api.Entitlement.EntitlementState) DateTime(org.joda.time.DateTime)

Example 52 with SubscriptionBaseEvent

use of org.killbill.billing.subscription.events.SubscriptionBaseEvent in project killbill by killbill.

the class DefaultSubscriptionBaseApiService method getEventsOnChangePlan.

private List<SubscriptionBaseEvent> getEventsOnChangePlan(final DefaultSubscriptionBase subscription, final Plan newPlan, final String newPriceList, final DateTime effectiveDate, final boolean addCancellationAddOnForEventsIfRequired, final Collection<DefaultSubscriptionBase> addOnSubscriptionsToBeCancelled, final Collection<SubscriptionBaseEvent> addOnCancelEvents, final PhaseType initialPhaseType, final Integer bcd, final SubscriptionCatalog catalog, final InternalTenantContext internalTenantContext) throws CatalogApiException, SubscriptionBaseApiException {
    final TimedPhase currentTimedPhase = planAligner.getCurrentTimedPhaseOnChange(subscription, newPlan, effectiveDate, initialPhaseType, catalog, internalTenantContext);
    validateSubscriptionStateForChangePlan(subscription, effectiveDate);
    final SubscriptionBaseEvent changeEvent = new ApiEventChange(new ApiEventBuilder().setSubscriptionId(subscription.getId()).setEventPlan(newPlan.getName()).setEventPlanPhase(currentTimedPhase.getPhase().getName()).setEventPriceList(newPriceList).setEffectiveDate(effectiveDate).setFromDisk(true));
    final TimedPhase nextTimedPhase = planAligner.getNextTimedPhaseOnChange(subscription, newPlan, effectiveDate, initialPhaseType, catalog, internalTenantContext);
    final PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ? PhaseEventData.createNextPhaseEvent(subscription.getId(), nextTimedPhase.getPhase().getName(), nextTimedPhase.getStartPhase()) : null;
    final List<SubscriptionBaseEvent> changeEvents = new ArrayList<SubscriptionBaseEvent>();
    // Only add the PHASE if it does not coincide with the CHANGE, if not this is 'just' a CHANGE.
    changeEvents.add(changeEvent);
    if (bcd != null) {
        final SubscriptionBaseEvent bcdEvent = new BCDEventData(new BCDEventBuilder().setSubscriptionId(subscription.getId()).setEffectiveDate(effectiveDate).setActive(true).setBillCycleDayLocal(bcd));
        changeEvents.add(bcdEvent);
    }
    if (nextPhaseEvent != null && !nextPhaseEvent.getEffectiveDate().equals(changeEvent.getEffectiveDate())) {
        changeEvents.add(nextPhaseEvent);
    }
    if (subscription.getCategory() == ProductCategory.BASE && addCancellationAddOnForEventsIfRequired) {
        final Product currentBaseProduct = changeEvent.getEffectiveDate().compareTo(clock.getUTCNow()) <= 0 ? newPlan.getProduct() : subscription.getCurrentOrPendingPlan().getProduct();
        addOnSubscriptionsToBeCancelled.addAll(addCancellationAddOnForEventsIfRequired(addOnCancelEvents, currentBaseProduct, subscription.getBundleId(), effectiveDate, catalog, internalTenantContext));
    }
    return changeEvents;
}
Also used : BCDEventData(org.killbill.billing.subscription.events.bcd.BCDEventData) PhaseEvent(org.killbill.billing.subscription.events.phase.PhaseEvent) ApiEventBuilder(org.killbill.billing.subscription.events.user.ApiEventBuilder) TimedPhase(org.killbill.billing.subscription.alignment.TimedPhase) ArrayList(java.util.ArrayList) BCDEventBuilder(org.killbill.billing.subscription.events.bcd.BCDEventBuilder) Product(org.killbill.billing.catalog.api.Product) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent) ApiEventChange(org.killbill.billing.subscription.events.user.ApiEventChange)

Example 53 with SubscriptionBaseEvent

use of org.killbill.billing.subscription.events.SubscriptionBaseEvent in project killbill by killbill.

the class DefaultSubscriptionBaseApiService method getEventsOnCancelPlan.

@Override
public List<SubscriptionBaseEvent> getEventsOnCancelPlan(final DefaultSubscriptionBase subscription, final DateTime effectiveDate, final boolean addCancellationAddOnForEventsIfRequired, final SubscriptionCatalog fullCatalog, final InternalTenantContext internalTenantContext) throws CatalogApiException {
    final List<SubscriptionBaseEvent> cancelEvents = new ArrayList<SubscriptionBaseEvent>();
    final SubscriptionBaseEvent cancelEvent = new ApiEventCancel(new ApiEventBuilder().setSubscriptionId(subscription.getId()).setEffectiveDate(effectiveDate).setFromDisk(true));
    cancelEvents.add(cancelEvent);
    if (subscription.getCategory() == ProductCategory.BASE && addCancellationAddOnForEventsIfRequired) {
        final Product currentBaseProduct = cancelEvent.getEffectiveDate().compareTo(clock.getUTCNow()) <= 0 ? null : subscription.getCurrentPlan().getProduct();
        addCancellationAddOnForEventsIfRequired(cancelEvents, currentBaseProduct, subscription.getBundleId(), effectiveDate, fullCatalog, internalTenantContext);
    }
    return cancelEvents;
}
Also used : ApiEventBuilder(org.killbill.billing.subscription.events.user.ApiEventBuilder) ArrayList(java.util.ArrayList) Product(org.killbill.billing.catalog.api.Product) ApiEventCancel(org.killbill.billing.subscription.events.user.ApiEventCancel) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent)

Example 54 with SubscriptionBaseEvent

use of org.killbill.billing.subscription.events.SubscriptionBaseEvent in project killbill by killbill.

the class DefaultSubscriptionBaseApiService method handleBasePlanEvent.

@Override
public int handleBasePlanEvent(final DefaultSubscriptionBase subscription, final SubscriptionBaseEvent event, final SubscriptionCatalog catalog, final CallContext context) throws CatalogApiException {
    final InternalCallContext internalCallContext = createCallContextFromBundleId(subscription.getBundleId(), context);
    if (((ApiEvent) event).getApiEventType() == ApiEventType.CANCEL || ((ApiEvent) event).getApiEventType() == ApiEventType.CHANGE) {
        final Product baseProduct = (subscription.getState() == EntitlementState.CANCELLED) ? null : subscription.getCurrentPlan().getProduct();
        final List<SubscriptionBaseEvent> cancelEvents = new LinkedList<SubscriptionBaseEvent>();
        final List<DefaultSubscriptionBase> subscriptionsToBeCancelled = computeAddOnsToCancel(cancelEvents, baseProduct, subscription.getBundleId(), event.getEffectiveDate(), catalog, internalCallContext);
        dao.cancelSubscriptionsOnBasePlanEvent(subscription, event, subscriptionsToBeCancelled, cancelEvents, catalog, internalCallContext);
        return subscriptionsToBeCancelled.size();
    } else {
        dao.notifyOnBasePlanEvent(subscription, event, catalog, internalCallContext);
        return 0;
    }
}
Also used : ApiEvent(org.killbill.billing.subscription.events.user.ApiEvent) Product(org.killbill.billing.catalog.api.Product) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent) LinkedList(java.util.LinkedList)

Example 55 with SubscriptionBaseEvent

use of org.killbill.billing.subscription.events.SubscriptionBaseEvent in project killbill by killbill.

the class DefaultSubscriptionBaseApiService method createEvents.

private void createEvents(final Iterable<SubscriptionSpecifier> subscriptions, final CallContext context, final Map<UUID, List<SubscriptionBaseEvent>> eventsMap, final Collection<SubscriptionBase> subscriptionBaseList, final SubscriptionCatalog catalog) throws SubscriptionBaseApiException {
    for (final SubscriptionSpecifier subscription : subscriptions) {
        try {
            final DefaultSubscriptionBase subscriptionBase = new DefaultSubscriptionBase(subscription.getBuilder(), this, clock);
            final InternalCallContext internalCallContext = createCallContextFromBundleId(subscriptionBase.getBundleId(), context);
            final List<SubscriptionBaseEvent> events = getEventsOnCreation(subscriptionBase.getId(), subscriptionBase.getAlignStartDate(), subscriptionBase.getBundleStartDate(), subscription.getPlan(), subscription.getInitialPhase(), subscription.getRealPriceList(), subscription.getEffectiveDate(), subscription.getBuilder().getSubscriptionBCD(), catalog, internalCallContext);
            eventsMap.put(subscriptionBase.getId(), events);
            subscriptionBaseList.add(subscriptionBase);
        } catch (final CatalogApiException e) {
            throw new SubscriptionBaseApiException(e);
        }
    }
}
Also used : CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent)

Aggregations

SubscriptionBaseEvent (org.killbill.billing.subscription.events.SubscriptionBaseEvent)75 DateTime (org.joda.time.DateTime)31 ApiEventBuilder (org.killbill.billing.subscription.events.user.ApiEventBuilder)26 LinkedList (java.util.LinkedList)25 ArrayList (java.util.ArrayList)23 UUID (java.util.UUID)22 DefaultSubscriptionBase (org.killbill.billing.subscription.api.user.DefaultSubscriptionBase)21 InternalCallContext (org.killbill.billing.callcontext.InternalCallContext)16 CatalogApiException (org.killbill.billing.catalog.api.CatalogApiException)14 Test (org.testng.annotations.Test)14 Plan (org.killbill.billing.catalog.api.Plan)13 PhaseEvent (org.killbill.billing.subscription.events.phase.PhaseEvent)13 ApiEvent (org.killbill.billing.subscription.events.user.ApiEvent)13 ApiEventCancel (org.killbill.billing.subscription.events.user.ApiEventCancel)12 ApiEventCreate (org.killbill.billing.subscription.events.user.ApiEventCreate)11 SubscriptionBase (org.killbill.billing.subscription.api.SubscriptionBase)10 SubscriptionBuilder (org.killbill.billing.subscription.api.user.SubscriptionBuilder)9 SubscriptionNotificationKey (org.killbill.billing.subscription.engine.core.SubscriptionNotificationKey)8 ApiEventChange (org.killbill.billing.subscription.events.user.ApiEventChange)8 ImmutableList (com.google.common.collect.ImmutableList)7