Search in sources :

Example 11 with SubscriptionBaseEvent

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

the class DefaultSubscriptionBaseApiService method createPlansWithAddOns.

@Override
public List<SubscriptionBaseWithAddOns> createPlansWithAddOns(final UUID accountId, final Iterable<SubscriptionAndAddOnsSpecifier> subscriptionsAndAddOns, final SubscriptionCatalog kbCatalog, final CallContext context) throws SubscriptionBaseApiException {
    final Map<UUID, List<SubscriptionBaseEvent>> eventsMap = new HashMap<UUID, List<SubscriptionBaseEvent>>();
    final Collection<List<SubscriptionBase>> subscriptionBaseAndAddOnsList = new ArrayList<List<SubscriptionBase>>();
    final InternalCallContext internalCallContext = createCallContextFromAccountId(accountId, context);
    try {
        final List<SubscriptionBaseWithAddOns> allSubscriptions = new ArrayList<SubscriptionBaseWithAddOns>();
        for (final SubscriptionAndAddOnsSpecifier subscriptionAndAddOns : subscriptionsAndAddOns) {
            final List<SubscriptionBase> subscriptionBaseList = new ArrayList<SubscriptionBase>();
            createEvents(subscriptionAndAddOns.getSubscriptionSpecifiers(), context, eventsMap, subscriptionBaseList, kbCatalog);
            subscriptionBaseAndAddOnsList.add(subscriptionBaseList);
            final SubscriptionBaseWithAddOns subscriptionBaseWithAddOns = new DefaultSubscriptionBaseWithAddOns(subscriptionAndAddOns.getBundle(), subscriptionBaseList);
            allSubscriptions.add(subscriptionBaseWithAddOns);
        }
        final List<SubscriptionBaseEvent> events = dao.createSubscriptionsWithAddOns(allSubscriptions, eventsMap, kbCatalog, internalCallContext);
        final ListMultimap<UUID, SubscriptionBaseEvent> eventsBySubscription = ArrayListMultimap.<UUID, SubscriptionBaseEvent>create();
        for (final SubscriptionBaseEvent event : events) {
            eventsBySubscription.put(event.getSubscriptionId(), event);
        }
        for (final List<SubscriptionBase> subscriptions : subscriptionBaseAndAddOnsList) {
            for (final SubscriptionBase input : subscriptions) {
                ((DefaultSubscriptionBase) input).rebuildTransitions(eventsBySubscription.get(input.getId()), kbCatalog);
            }
        }
        return allSubscriptions;
    } catch (final CatalogApiException e) {
        throw new SubscriptionBaseApiException(e);
    }
}
Also used : SubscriptionBaseWithAddOns(org.killbill.billing.subscription.api.SubscriptionBaseWithAddOns) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) SubscriptionBase(org.killbill.billing.subscription.api.SubscriptionBase) CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) LinkedList(java.util.LinkedList) UUID(java.util.UUID) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent)

Example 12 with SubscriptionBaseEvent

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

the class DefaultSubscriptionBaseTransferApi method transferBundle.

@Override
public SubscriptionBaseBundle transferBundle(final UUID sourceAccountId, final UUID destAccountId, final String bundleKey, final DateTime transferDate, final boolean transferAddOn, final boolean cancelImmediately, final CallContext context) throws SubscriptionBaseTransferApiException {
    final InternalCallContext fromInternalCallContext = internalCallContextFactory.createInternalCallContext(sourceAccountId, context);
    final InternalCallContext toInternalCallContext = internalCallContextFactory.createInternalCallContext(destAccountId, context);
    try {
        final SubscriptionCatalog catalog = subscriptionCatalogApi.getFullCatalog(fromInternalCallContext);
        final DateTime effectiveTransferDate = transferDate == null ? context.getCreatedDate() : transferDate;
        if (effectiveTransferDate.isAfter(context.getCreatedDate())) {
            // (subscription always expects the first event to be in the past)
            throw new SubscriptionBaseTransferApiException(ErrorCode.SUB_TRANSFER_INVALID_EFF_DATE, effectiveTransferDate);
        }
        final SubscriptionBaseBundle bundle = subscriptionBaseInternalApi.getActiveBundleForKey(catalog.getCatalog(), bundleKey, fromInternalCallContext);
        if (bundle == null) {
            throw new SubscriptionBaseTransferApiException(ErrorCode.SUB_CREATE_NO_BUNDLE, bundleKey);
        }
        // Get the bundle timeline for the old account
        final BundleBaseTimeline bundleBaseTimeline = timelineApi.getBundleTimeline(bundle, context);
        final DefaultSubscriptionBaseBundle subscriptionBundleData = new DefaultSubscriptionBaseBundle(bundleKey, destAccountId, effectiveTransferDate, bundle.getOriginalCreatedDate(), context.getCreatedDate(), context.getCreatedDate());
        final List<SubscriptionTransferData> subscriptionTransferDataList = new LinkedList<SubscriptionTransferData>();
        final List<TransferCancelData> transferCancelDataList = new LinkedList<TransferCancelData>();
        DateTime bundleStartdate = null;
        for (final SubscriptionBaseTimeline cur : bundleBaseTimeline.getSubscriptions()) {
            final DefaultSubscriptionBase oldSubscription = (DefaultSubscriptionBase) dao.getSubscriptionFromId(cur.getId(), catalog, fromInternalCallContext);
            // Skip already cancelled subscriptions
            if (oldSubscription.getState() == EntitlementState.CANCELLED) {
                continue;
            }
            final List<ExistingEvent> existingEvents = cur.getExistingEvents();
            final ProductCategory productCategory = existingEvents.get(0).getProductCategory();
            // on base plan cancellations, even though we don't support un-transfer today)
            if (productCategory != ProductCategory.ADD_ON || cancelImmediately) {
                // Create the cancelWithRequestedDate event on effectiveCancelDate
                final DateTime effectiveCancelDate = !cancelImmediately && oldSubscription.getChargedThroughDate() != null && effectiveTransferDate.isBefore(oldSubscription.getChargedThroughDate()) ? oldSubscription.getChargedThroughDate() : effectiveTransferDate;
                final SubscriptionBaseEvent cancelEvent = new ApiEventCancel(new ApiEventBuilder().setSubscriptionId(cur.getId()).setEffectiveDate(effectiveCancelDate).setFromDisk(true));
                final TransferCancelData cancelData = new TransferCancelData(oldSubscription, cancelEvent);
                transferCancelDataList.add(cancelData);
            }
            if (productCategory == ProductCategory.ADD_ON && !transferAddOn) {
                continue;
            }
            // We Align with the original subscription
            final DateTime subscriptionAlignStartDate = oldSubscription.getAlignStartDate();
            if (bundleStartdate == null) {
                bundleStartdate = oldSubscription.getStartDate();
            }
            // Create the new subscription for the new bundle on the new account
            final DefaultSubscriptionBase defaultSubscriptionBase = createSubscriptionForApiUse(new SubscriptionBuilder().setId(UUIDs.randomUUID()).setBundleId(subscriptionBundleData.getId()).setBundleExternalKey(subscriptionBundleData.getExternalKey()).setCategory(productCategory).setBundleStartDate(effectiveTransferDate).setAlignStartDate(subscriptionAlignStartDate), ImmutableList.<SubscriptionBaseEvent>of(), catalog, fromInternalCallContext);
            final List<SubscriptionBaseEvent> events = toEvents(existingEvents, defaultSubscriptionBase, effectiveTransferDate, fromInternalCallContext);
            final SubscriptionTransferData curData = new SubscriptionTransferData(defaultSubscriptionBase, events, null);
            subscriptionTransferDataList.add(curData);
        }
        final BundleTransferData bundleTransferData = new BundleTransferData(subscriptionBundleData, subscriptionTransferDataList);
        // Atomically cancelWithRequestedDate all subscription on old account and create new bundle, subscriptions, events for new account
        dao.transfer(sourceAccountId, destAccountId, bundleTransferData, transferCancelDataList, catalog, fromInternalCallContext, toInternalCallContext);
        return bundleTransferData.getData();
    } catch (SubscriptionBaseRepairException e) {
        throw new SubscriptionBaseTransferApiException(e);
    } catch (CatalogApiException e) {
        throw new SubscriptionBaseTransferApiException(e);
    }
}
Also used : InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) SubscriptionBaseTimeline(org.killbill.billing.subscription.api.timeline.SubscriptionBaseTimeline) SubscriptionCatalog(org.killbill.billing.subscription.catalog.SubscriptionCatalog) DateTime(org.joda.time.DateTime) ApiEventBuilder(org.killbill.billing.subscription.events.user.ApiEventBuilder) SubscriptionBaseBundle(org.killbill.billing.subscription.api.user.SubscriptionBaseBundle) DefaultSubscriptionBaseBundle(org.killbill.billing.subscription.api.user.DefaultSubscriptionBaseBundle) DefaultSubscriptionBase(org.killbill.billing.subscription.api.user.DefaultSubscriptionBase) ExistingEvent(org.killbill.billing.subscription.api.timeline.SubscriptionBaseTimeline.ExistingEvent) BundleBaseTimeline(org.killbill.billing.subscription.api.timeline.BundleBaseTimeline) SubscriptionBaseRepairException(org.killbill.billing.subscription.api.timeline.SubscriptionBaseRepairException) DefaultSubscriptionBaseBundle(org.killbill.billing.subscription.api.user.DefaultSubscriptionBaseBundle) ApiEventCancel(org.killbill.billing.subscription.events.user.ApiEventCancel) SubscriptionBuilder(org.killbill.billing.subscription.api.user.SubscriptionBuilder) LinkedList(java.util.LinkedList) CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) ProductCategory(org.killbill.billing.catalog.api.ProductCategory) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent)

Example 13 with SubscriptionBaseEvent

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

the class MockSubscriptionDaoMemory method undoPendingOperation.

private void undoPendingOperation(final DefaultSubscriptionBase subscription, final List<SubscriptionBaseEvent> inputEvents, final ApiEventType targetType, final InternalCallContext context) {
    synchronized (events) {
        boolean foundEvent = false;
        final Iterator<SubscriptionBaseEvent> it = events.descendingIterator();
        while (it.hasNext()) {
            final SubscriptionBaseEvent cur = it.next();
            if (cur.getSubscriptionId() != subscription.getId()) {
                continue;
            }
            if (cur.getType() == EventType.API_USER && ((ApiEvent) cur).getApiEventType() == targetType) {
                it.remove();
                foundEvent = true;
                break;
            }
        }
        if (foundEvent) {
            for (final SubscriptionBaseEvent cur : inputEvents) {
                insertEvent(cur, context);
            }
        }
    }
}
Also used : ApiEvent(org.killbill.billing.subscription.events.user.ApiEvent) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent)

Example 14 with SubscriptionBaseEvent

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

the class MockSubscriptionDaoMemory method createSubscriptionsWithAddOns.

@Override
public List<SubscriptionBaseEvent> createSubscriptionsWithAddOns(final List<SubscriptionBaseWithAddOns> subscriptions, final Map<UUID, List<SubscriptionBaseEvent>> initialEventsMap, final SubscriptionCatalog catalog, final InternalCallContext context) {
    final List<SubscriptionBaseEvent> createdEvents = new LinkedList<SubscriptionBaseEvent>();
    synchronized (events) {
        for (final SubscriptionBaseWithAddOns subscription : subscriptions) {
            for (final SubscriptionBase subscriptionBase : subscription.getSubscriptionBaseList()) {
                final List<SubscriptionBaseEvent> initialEvents = initialEventsMap.get(subscriptionBase.getId());
                events.addAll(initialEvents);
                for (final SubscriptionBaseEvent cur : initialEvents) {
                    recordFutureNotificationFromTransaction(null, cur.getEffectiveDate(), new SubscriptionNotificationKey(cur.getId()), context);
                }
                final DefaultSubscriptionBase updatedSubscription = buildSubscription((DefaultSubscriptionBase) subscriptionBase, context);
                this.subscriptions.add(updatedSubscription);
                mockNonEntityDao.addTenantRecordIdMapping(updatedSubscription.getId(), context);
                createdEvents.addAll(initialEvents);
            }
        }
    }
    return createdEvents;
}
Also used : SubscriptionBase(org.killbill.billing.subscription.api.SubscriptionBase) DefaultSubscriptionBase(org.killbill.billing.subscription.api.user.DefaultSubscriptionBase) SubscriptionNotificationKey(org.killbill.billing.subscription.engine.core.SubscriptionNotificationKey) SubscriptionBaseWithAddOns(org.killbill.billing.subscription.api.SubscriptionBaseWithAddOns) DefaultSubscriptionBase(org.killbill.billing.subscription.api.user.DefaultSubscriptionBase) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent) LinkedList(java.util.LinkedList)

Example 15 with SubscriptionBaseEvent

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

the class TestSubscriptionDao method createSubscription.

private List<SubscriptionBaseEvent> createSubscription(final SubscriptionBaseBundle bundle, final String externalKey, final DateTime startDate, final DateTime cancelDate) {
    final SubscriptionBuilder builder = new SubscriptionBuilder().setId(UUIDs.randomUUID()).setBundleId(bundle.getId()).setBundleExternalKey(bundle.getExternalKey()).setCategory(ProductCategory.BASE).setBundleStartDate(startDate).setAlignStartDate(startDate).setExternalKey(externalKey).setMigrated(false);
    final ApiEventBuilder createBuilder = new ApiEventBuilder().setSubscriptionId(builder.getId()).setEventPlan("shotgun-monthly").setEventPlanPhase("shotgun-monthly-trial").setEventPriceList(DefaultPriceListSet.DEFAULT_PRICELIST_NAME).setEffectiveDate(startDate).setFromDisk(true);
    final SubscriptionBaseEvent creationEvent = new ApiEventCreate(createBuilder);
    final ApiEventBuilder cancelBuilder = cancelDate != null ? new ApiEventBuilder().setSubscriptionId(builder.getId()).setEffectiveDate(cancelDate).setFromDisk(true) : null;
    final SubscriptionBaseEvent cancelEvent = cancelBuilder != null ? new ApiEventCancel(cancelBuilder) : null;
    final DefaultSubscriptionBase subscription = new DefaultSubscriptionBase(builder);
    final SubscriptionBaseWithAddOns subscriptionBaseWithAddOns = new DefaultSubscriptionBaseWithAddOns(bundle, ImmutableList.<SubscriptionBase>of(subscription));
    testListener.pushExpectedEvents(NextEvent.CREATE);
    final ImmutableList<SubscriptionBaseEvent> events = cancelEvent != null ? ImmutableList.<SubscriptionBaseEvent>of(creationEvent, cancelEvent) : ImmutableList.<SubscriptionBaseEvent>of(creationEvent);
    final List<SubscriptionBaseEvent> result = dao.createSubscriptionsWithAddOns(ImmutableList.<SubscriptionBaseWithAddOns>of(subscriptionBaseWithAddOns), ImmutableMap.<UUID, List<SubscriptionBaseEvent>>of(subscription.getId(), events), catalog, internalCallContext);
    assertListenerStatus();
    return result;
}
Also used : ApiEventCreate(org.killbill.billing.subscription.events.user.ApiEventCreate) DefaultSubscriptionBaseWithAddOns(org.killbill.billing.subscription.api.user.DefaultSubscriptionBaseWithAddOns) SubscriptionBaseWithAddOns(org.killbill.billing.subscription.api.SubscriptionBaseWithAddOns) ApiEventBuilder(org.killbill.billing.subscription.events.user.ApiEventBuilder) SubscriptionBuilder(org.killbill.billing.subscription.api.user.SubscriptionBuilder) ApiEventCancel(org.killbill.billing.subscription.events.user.ApiEventCancel) DefaultSubscriptionBase(org.killbill.billing.subscription.api.user.DefaultSubscriptionBase) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent) DefaultSubscriptionBaseWithAddOns(org.killbill.billing.subscription.api.user.DefaultSubscriptionBaseWithAddOns)

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