use of org.killbill.billing.subscription.api.SubscriptionBase in project killbill by killbill.
the class DefaultEntitlementInternalApi method cancel.
@Override
public void cancel(final Iterable<Entitlement> entitlements, @Nullable final LocalDate effectiveDate, final BillingActionPolicy billingPolicy, final Iterable<PluginProperty> properties, final InternalCallContext internalCallContext) throws EntitlementApiException {
if (!entitlements.iterator().hasNext()) {
return;
}
final CallContext callContext = internalCallContextFactory.createCallContext(internalCallContext);
final ImmutableMap.Builder<BlockingState, Optional<UUID>> blockingStates = new ImmutableMap.Builder<BlockingState, Optional<UUID>>();
final Map<DateTime, Collection<NotificationEvent>> notificationEvents = new HashMap<DateTime, Collection<NotificationEvent>>();
final Collection<EntitlementContext> pluginContexts = new LinkedList<EntitlementContext>();
final List<WithEntitlementPlugin> callbacks = new LinkedList<WithEntitlementPlugin>();
final List<SubscriptionBase> subscriptions = new LinkedList<SubscriptionBase>();
for (final Entitlement entitlement : entitlements) {
if (entitlement.getState() == EntitlementState.CANCELLED) {
// If subscription has already been cancelled, we ignore and carry on
continue;
}
final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(entitlement.getBundleId(), entitlement.getBundleExternalKey(), null, effectiveDate, null, false);
final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.CANCEL_SUBSCRIPTION, entitlement.getAccountId(), null, baseEntitlementWithAddOnsSpecifierList, billingPolicy, properties, callContext);
pluginContexts.add(pluginContext);
final WithEntitlementPlugin<Entitlement> cancelEntitlementWithPlugin = new WithDateOverrideBillingPolicyEntitlementCanceler((DefaultEntitlement) entitlement, blockingStates, notificationEvents, callContext, internalCallContext);
callbacks.add(cancelEntitlementWithPlugin);
subscriptions.add(((DefaultEntitlement) entitlement).getSubscriptionBase());
}
final Callable<Void> preCallbacksCallback = new BulkSubscriptionBaseCancellation(subscriptions, billingPolicy, internalCallContext);
pluginExecution.executeWithPlugin(preCallbacksCallback, callbacks, pluginContexts);
// Record the new states first, then insert the notifications to avoid race conditions
blockingStateDao.setBlockingStatesAndPostBlockingTransitionEvent(blockingStates.build(), internalCallContext);
for (final DateTime effectiveDateForNotification : notificationEvents.keySet()) {
for (final NotificationEvent notificationEvent : notificationEvents.get(effectiveDateForNotification)) {
recordFutureNotification(effectiveDateForNotification, notificationEvent, internalCallContext);
}
}
}
use of org.killbill.billing.subscription.api.SubscriptionBase in project killbill by killbill.
the class ProxyBlockingStateDao method addBlockingStatesNotOnDisk.
// Special signature for OptimizedProxyBlockingStateDao
protected List<BlockingState> addBlockingStatesNotOnDisk(@Nullable final UUID blockableId, @Nullable final BlockingStateType blockingStateType, final Collection<BlockingState> blockingStatesOnDiskCopy, final Iterable<SubscriptionBase> baseSubscriptionsToConsider, final Iterable<EventsStream> eventsStreams) {
final Map<UUID, EventsStream> baseSubscriptionIdToEventsStream = new HashMap<UUID, EventsStream>();
for (final EventsStream eventsStream : eventsStreams) {
baseSubscriptionIdToEventsStream.put(eventsStream.getSubscriptionBase().getId(), eventsStream);
}
// Compute the blocking states not on disk for all base subscriptions
final DateTime now = clock.getUTCNow();
for (final SubscriptionBase baseSubscription : baseSubscriptionsToConsider) {
final EventsStream eventsStream = baseSubscriptionIdToEventsStream.get(baseSubscription.getId());
// First, check to see if the base entitlement is cancelled
final Collection<BlockingState> blockingStatesNotOnDisk = eventsStream.computeAddonsBlockingStatesForFutureSubscriptionBaseEvents();
// Inject the extra blocking states into the stream if needed
for (final BlockingState blockingState : blockingStatesNotOnDisk) {
// If this entitlement is actually already cancelled, add the cancellation event we computed
// only if it's prior to the blocking state on disk (e.g. add-on future cancelled but base plan cancelled earlier).
BlockingState cancellationBlockingStateOnDisk = null;
boolean overrideCancellationBlockingStateOnDisk = false;
if (isEntitlementCancellationBlockingState(blockingState)) {
cancellationBlockingStateOnDisk = findEntitlementCancellationBlockingState(blockingState.getBlockedId(), blockingStatesOnDiskCopy);
overrideCancellationBlockingStateOnDisk = cancellationBlockingStateOnDisk != null && blockingState.getEffectiveDate().isBefore(cancellationBlockingStateOnDisk.getEffectiveDate());
}
if ((blockingStateType == null || // blocking states for other add-ons on that base subscription
(BlockingStateType.SUBSCRIPTION.equals(blockingStateType) && blockingState.getBlockedId().equals(blockableId))) && (cancellationBlockingStateOnDisk == null || overrideCancellationBlockingStateOnDisk)) {
final BlockingStateModelDao blockingStateModelDao = new BlockingStateModelDao(blockingState, now, now);
blockingStatesOnDiskCopy.add(BlockingStateModelDao.toBlockingState(blockingStateModelDao));
if (overrideCancellationBlockingStateOnDisk) {
blockingStatesOnDiskCopy.remove(cancellationBlockingStateOnDisk);
}
}
}
}
// Return the sorted list
return sortedCopy(blockingStatesOnDiskCopy);
}
use of org.killbill.billing.subscription.api.SubscriptionBase in project killbill by killbill.
the class TestUsageInArrearBase method createMockBillingEvent.
protected BillingEvent createMockBillingEvent(final int bcd, final DateTime effectiveDate, final BillingPeriod billingPeriod, final List<Usage> usages, final DateTime catalogEffectiveDate, SubscriptionBaseTransitionType beType) throws Exception {
final BillingEvent result = Mockito.mock(BillingEvent.class);
Mockito.when(result.getCurrency()).thenReturn(currency);
Mockito.when(result.getBillCycleDayLocal()).thenReturn(bcd);
Mockito.when(result.getEffectiveDate()).thenReturn(effectiveDate);
Mockito.when(result.getBillingPeriod()).thenReturn(billingPeriod);
Mockito.when(result.getSubscriptionId()).thenReturn(subscriptionId);
Mockito.when(result.getBundleId()).thenReturn(bundleId);
Mockito.when(result.getCatalogEffectiveDate()).thenReturn(catalogEffectiveDate);
Mockito.when(result.getTransitionType()).thenReturn(beType);
final Account account = Mockito.mock(Account.class);
Mockito.when(account.getId()).thenReturn(accountId);
final SubscriptionBase subscription = Mockito.mock(SubscriptionBase.class);
Mockito.when(subscription.getId()).thenReturn(subscriptionId);
Mockito.when(subscription.getBundleId()).thenReturn(bundleId);
final Product product = Mockito.mock(Product.class);
Mockito.when(product.getName()).thenReturn(productName);
final Plan plan = Mockito.mock(Plan.class);
Mockito.when(plan.getName()).thenReturn(planName);
Mockito.when(plan.getProduct()).thenReturn(product);
Mockito.when(result.getPlan()).thenReturn(plan);
final PlanPhase phase = Mockito.mock(PlanPhase.class);
Mockito.when(phase.getName()).thenReturn(phaseName);
Mockito.when(result.getPlanPhase()).thenReturn(phase);
Mockito.when(result.getUsages()).thenReturn(usages);
return result;
}
use of org.killbill.billing.subscription.api.SubscriptionBase in project killbill by killbill.
the class DefaultSubscriptionInternalApi method cancelBaseSubscriptions.
@Override
public void cancelBaseSubscriptions(final Iterable<SubscriptionBase> subscriptions, final BillingActionPolicy policy, final InternalCallContext context) throws SubscriptionBaseApiException {
try {
final SubscriptionCatalog catalog = subscriptionCatalogApi.getFullCatalog(context);
apiService.cancelWithPolicyNoValidationAndCatalog(Iterables.<SubscriptionBase, DefaultSubscriptionBase>transform(subscriptions, new Function<SubscriptionBase, DefaultSubscriptionBase>() {
@Override
public DefaultSubscriptionBase apply(final SubscriptionBase subscriptionBase) {
try {
return getDefaultSubscriptionBase(subscriptionBase, catalog, context);
} catch (final CatalogApiException e) {
throw new RuntimeException(e);
}
}
}), policy, catalog, context);
} catch (CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
}
use of org.killbill.billing.subscription.api.SubscriptionBase in project killbill by killbill.
the class DefaultSubscriptionInternalApi method getSubscriptionFromId.
@Override
public SubscriptionBase getSubscriptionFromId(final UUID id, final InternalTenantContext context) throws SubscriptionBaseApiException {
try {
final SubscriptionCatalog catalog = subscriptionCatalogApi.getFullCatalog(context);
final SubscriptionBase result = dao.getSubscriptionFromId(id, catalog, context);
if (result == null) {
throw new SubscriptionBaseApiException(ErrorCode.SUB_INVALID_SUBSCRIPTION_ID, id);
}
return createSubscriptionForApiUse(result);
} catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
}
Aggregations