@Override public boolean apply(final SubscriptionBase input) { return ProductCategory.BASE.equals(input.getCategory()); } });
@Override public boolean apply(final Entitlement entitlement) { return !ProductCategory.ADD_ON.equals(entitlement.getLastActiveProductCategory()); } });
@Override public boolean apply(final SubscriptionBase input) { return ProductCategory.BASE.equals(input.getLastActiveProduct().getCategory()); } }).orNull();
@Override public boolean apply(final SubscriptionBase input) { return ProductCategory.BASE.equals(input.getLastActiveProduct().getCategory()); } }).orNull(); // null for standalone subscriptions
return false; if (productCategory != null ? !productCategory.equals(that.productCategory) : that.productCategory != null) { return false;
final InternalTenantContext context) throws EntitlementApiException { if (!ProductCategory.ADD_ON.equals(subscription.getCategory())) {
private Collection<BlockingState> computeAddonsBlockingStatesForSubscriptionBaseEvent(@Nullable final Product baseTransitionTriggerNextProduct, final DateTime blockingStateEffectiveDate) { if (baseSubscription == null || baseSubscription.getLastActivePlan() == null || !ProductCategory.BASE.equals(baseSubscription.getLastActivePlan().getProduct().getCategory())) { return ImmutableList.<BlockingState>of();
@Override public boolean apply(final SubscriptionBase subscription) { return ProductCategory.ADD_ON.equals(subscription.getCategory()) && // Check the entitlement for that add-on hasn't been cancelled yet getEntitlementCancellationEvent(subscription.getId()) == null && ( // Base subscription cancelled baseTransitionTriggerNextProduct == null || ( // Change plan - check which add-ons to cancel includedAddonsForProduct.contains(subscription.getLastActivePlan().getProduct().getName()) || !availableAddonsForProduct.contains(subscription.getLastActivePlan().getProduct().getName()) ) ); } });
@Override public Collection<BlockingState> computeAddonsBlockingStatesForFutureSubscriptionBaseEvents() { if (!ProductCategory.BASE.equals(subscription.getCategory())) { // Only base subscriptions have add-ons return ImmutableList.of(); } // We need to find the first "trigger" transition, from which we will create the add-ons cancellation events. // This can either be a future entitlement cancel... if (isEntitlementFutureCancelled()) { // Note that in theory we could always only look subscription base as we assume entitlement cancel means subscription base cancel // but we want to use the effective date of the entitlement cancel event to create the add-on cancel event final BlockingState futureEntitlementCancelEvent = getEntitlementCancellationEvent(subscription.getId()); return computeAddonsBlockingStatesForNextSubscriptionBaseEvent(futureEntitlementCancelEvent.getEffectiveDate(), false); } else if (isEntitlementFutureChanged()) { // ...or a subscription change (i.e. a change plan where the new plan has an impact on the existing add-on). // We need to go back to subscription base as entitlement doesn't know about these return computeAddonsBlockingStatesForNextSubscriptionBaseEvent(utcNow, true); } else { return ImmutableList.of(); } }
@Override public List<Listing> getAvailableBasePlanListings() { final List<Listing> availBasePlans = new ArrayList<Listing>(); for (Plan plan : getCurrentPlans()) { if (plan.getProduct().getCategory().equals(ProductCategory.BASE)) { for (PriceList priceList : getPriceLists().getAllPriceLists()) { for (Plan priceListPlan : priceList.getPlans()) { if (priceListPlan.getName().equals(plan.getName()) && priceListPlan.getProduct().getName().equals(plan.getProduct().getName())) { availBasePlans.add(new DefaultListing(priceListPlan, priceList)); } } } } } return availBasePlans; } }
public T getResult(final PlanPhaseSpecifier from, final PlanSpecifier to, final StandaloneCatalog catalog) throws CatalogApiException { if ( (phaseType == null || from.getPhaseType() == phaseType) && (fromProduct == null || fromProduct.equals(catalog.findCurrentProduct(from.getProductName()))) && (fromProductCategory == null || fromProductCategory.equals(from.getProductCategory())) && (fromBillingPeriod == null || fromBillingPeriod.equals(from.getBillingPeriod())) && (toProduct == null || toProduct.equals(catalog.findCurrentProduct(to.getProductName()))) && (toProductCategory == null || toProductCategory.equals(to.getProductCategory())) && (toBillingPeriod == null || toBillingPeriod.equals(to.getBillingPeriod())) && (fromPriceList == null || fromPriceList.equals(catalog.findCurrentPriceList(from.getPriceListName()))) && (toPriceList == null || toPriceList.equals(catalog.findCurrentPriceList(to.getPriceListName()))) ) { return getResult(); } return null; }
protected boolean satisfiesCase(final PlanSpecifier planPhase, final StandaloneCatalog c) throws CatalogApiException { return (getProduct() == null || getProduct().equals(c.findCurrentProduct(planPhase.getProductName()))) && (getProductCategory() == null || getProductCategory().equals(planPhase.getProductCategory())) && (getBillingPeriod() == null || getBillingPeriod().equals(planPhase.getBillingPeriod())) && (getPriceList() == null || getPriceList().equals(c.findCurrentPriceList(planPhase.getPriceListName()))); }
public void blockAddOnsIfRequired(final DateTime effectiveDate, final TenantContext context, final InternalCallContext internalCallContext) throws EntitlementApiException { // Optimization - bail early if (!ProductCategory.BASE.equals(getSubscriptionBase().getCategory())) { // Only base subscriptions have add-ons return; } // Get the latest state from disk (we just got cancelled or changed plan) refresh(context); // If cancellation/change occurs in the future, do nothing for now but add a notification entry. // This is to distinguish whether a future cancellation was requested by the user, or was a side effect // (e.g. base plan cancellation): future entitlement cancellations for add-ons on disk always reflect // an explicit cancellation. This trick lets us determine what to do when un-cancelling. // This mirror the behavior in subscription base (see DefaultSubscriptionBaseApiService). final DateTime now = clock.getUTCNow(); if (effectiveDate.compareTo(now) > 0) { // Note that usually we record the notification from the DAO. We cannot do it here because not all calls // go through the DAO (e.g. change) final boolean isBaseEntitlementCancelled = eventsStream.isEntitlementCancelled(); final NotificationEvent notificationEvent = new EntitlementNotificationKey(getId(), getBundleId(), isBaseEntitlementCancelled ? EntitlementNotificationKeyAction.CANCEL : EntitlementNotificationKeyAction.CHANGE, effectiveDate); recordFutureNotification(effectiveDate, notificationEvent, internalCallContext); return; } final Collection<BlockingState> addOnsBlockingStates = eventsStream.computeAddonsBlockingStatesForNextSubscriptionBaseEvent(effectiveDate); for (final BlockingState addOnBlockingState : addOnsBlockingStates) { entitlementUtils.setBlockingStateAndPostBlockingTransitionEvent(addOnBlockingState, internalCallContext); } }