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);
}
}
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);
}
}
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);
}
}
}
}
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;
}
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;
}
Aggregations