use of org.killbill.billing.catalog.api.Product in project killbill by killbill.
the class DefaultEventsStream method computeAddonsBlockingStatesForNextSubscriptionBaseEvent.
private Collection<BlockingState> computeAddonsBlockingStatesForNextSubscriptionBaseEvent(final DateTime effectiveDate, final boolean useBillingEffectiveDate) {
SubscriptionBaseTransition subscriptionBaseTransitionTrigger = null;
if (!isEntitlementFutureCancelled()) {
// Compute the transition trigger (either subscription cancel or change)
final Iterable<SubscriptionBaseTransition> pendingSubscriptionBaseTransitions = getPendingSubscriptionEvents(effectiveDate, SubscriptionBaseTransitionType.CHANGE, SubscriptionBaseTransitionType.CANCEL);
if (!pendingSubscriptionBaseTransitions.iterator().hasNext()) {
return ImmutableList.<BlockingState>of();
}
subscriptionBaseTransitionTrigger = pendingSubscriptionBaseTransitions.iterator().next();
}
final Product baseTransitionTriggerNextProduct;
final DateTime blockingStateEffectiveDate;
if (subscriptionBaseTransitionTrigger == null) {
baseTransitionTriggerNextProduct = null;
blockingStateEffectiveDate = effectiveDate;
} else {
baseTransitionTriggerNextProduct = (EntitlementState.CANCELLED.equals(subscriptionBaseTransitionTrigger.getNextState()) ? null : subscriptionBaseTransitionTrigger.getNextPlan().getProduct());
blockingStateEffectiveDate = useBillingEffectiveDate ? subscriptionBaseTransitionTrigger.getEffectiveTransitionTime() : effectiveDate;
}
return computeAddonsBlockingStatesForSubscriptionBaseEvent(baseTransitionTriggerNextProduct, blockingStateEffectiveDate);
}
use of org.killbill.billing.catalog.api.Product in project killbill by killbill.
the class DefaultEventsStream method computeAddonsBlockingStatesForSubscriptionBaseEvent.
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();
}
// Compute included and available addons for the new product
final Collection<String> includedAddonsForProduct;
final Collection<String> availableAddonsForProduct;
if (baseTransitionTriggerNextProduct == null) {
includedAddonsForProduct = ImmutableList.<String>of();
availableAddonsForProduct = ImmutableList.<String>of();
} else {
includedAddonsForProduct = Collections2.<Product, String>transform(ImmutableSet.<Product>copyOf(baseTransitionTriggerNextProduct.getIncluded()), new Function<Product, String>() {
@Override
public String apply(final Product product) {
return product.getName();
}
});
availableAddonsForProduct = Collections2.<Product, String>transform(ImmutableSet.<Product>copyOf(baseTransitionTriggerNextProduct.getAvailable()), new Function<Product, String>() {
@Override
public String apply(final Product product) {
return product.getName();
}
});
}
// Retrieve all add-ons to block for that base subscription
final Collection<SubscriptionBase> futureBlockedAddons = Collections2.<SubscriptionBase>filter(allSubscriptionsForBundle, new Predicate<SubscriptionBase>() {
@Override
public boolean apply(final SubscriptionBase subscription) {
final Plan lastActivePlan = subscription.getLastActivePlan();
final boolean result = ProductCategory.ADD_ON.equals(subscription.getCategory()) && // Check the subscription started, if not we don't want it, and that way we avoid doing NPE a few lines below.
lastActivePlan != null && // 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(lastActivePlan.getProduct().getName()) || !availableAddonsForProduct.contains(subscription.getLastActivePlan().getProduct().getName())));
return result;
}
});
// Create the blocking states
return Collections2.<SubscriptionBase, BlockingState>transform(futureBlockedAddons, new Function<SubscriptionBase, BlockingState>() {
@Override
public BlockingState apply(final SubscriptionBase input) {
return new DefaultBlockingState(input.getId(), BlockingStateType.SUBSCRIPTION, DefaultEntitlementApi.ENT_STATE_CANCELLED, EntitlementService.ENTITLEMENT_SERVICE_NAME, true, true, false, blockingStateEffectiveDate);
}
});
}
use of org.killbill.billing.catalog.api.Product in project killbill by killbill.
the class EventsStreamBuilder method createPlanPhaseSpecifier.
private PlanPhaseSpecifier createPlanPhaseSpecifier(final SubscriptionBase subscription) {
final String lastActiveProductName;
final BillingPeriod billingPeriod;
final ProductCategory productCategory;
final String priceListName;
final PhaseType phaseType;
if (subscription.getState() == EntitlementState.PENDING) {
final SubscriptionBaseTransition transition = subscription.getPendingTransition();
final Product pendingProduct = transition.getNextPlan().getProduct();
lastActiveProductName = pendingProduct.getName();
productCategory = pendingProduct.getCategory();
final PlanPhase pendingPlanPhase = transition.getNextPhase();
billingPeriod = pendingPlanPhase.getRecurring() != null ? pendingPlanPhase.getRecurring().getBillingPeriod() : BillingPeriod.NO_BILLING_PERIOD;
priceListName = transition.getNextPriceList().getName();
phaseType = transition.getNextPhase().getPhaseType();
} else {
final Product lastActiveProduct = subscription.getLastActiveProduct();
lastActiveProductName = lastActiveProduct.getName();
productCategory = lastActiveProduct.getCategory();
final PlanPhase lastActivePlanPhase = subscription.getLastActivePhase();
billingPeriod = lastActivePlanPhase.getRecurring() != null ? lastActivePlanPhase.getRecurring().getBillingPeriod() : BillingPeriod.NO_BILLING_PERIOD;
priceListName = subscription.getLastActivePlan().getPriceListName();
phaseType = subscription.getLastActivePhase().getPhaseType();
}
return new PlanPhaseSpecifier(lastActiveProductName, billingPeriod, priceListName, phaseType);
}
use of org.killbill.billing.catalog.api.Product in project killbill by killbill.
the class AddonUtils method isAddonAvailableFromPlanName.
public boolean isAddonAvailableFromPlanName(final String basePlanName, final Plan targetAddOnPlan, final DateTime requestedDate, final InternalTenantContext context) {
try {
final Plan plan = catalogService.getFullCatalog(true, true, context).findPlan(basePlanName, requestedDate);
final Product product = plan.getProduct();
return isAddonAvailable(product, targetAddOnPlan);
} catch (CatalogApiException e) {
throw new SubscriptionBaseError(e);
}
}
use of org.killbill.billing.catalog.api.Product in project killbill by killbill.
the class AddonUtils method checkAddonCreationRights.
public void checkAddonCreationRights(final DefaultSubscriptionBase baseSubscription, final Plan targetAddOnPlan, final DateTime requestedDate, final InternalTenantContext context) throws SubscriptionBaseApiException, CatalogApiException {
if (baseSubscription.getState() == EntitlementState.CANCELLED || (baseSubscription.getState() == EntitlementState.PENDING && context.toLocalDate(baseSubscription.getStartDate()).compareTo(context.toLocalDate(requestedDate)) < 0)) {
throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_AO_BP_NON_ACTIVE, targetAddOnPlan.getName());
}
final Plan currentOrPendingPlan = baseSubscription.getCurrentOrPendingPlan();
final Product baseProduct = catalogService.getFullCatalog(true, true, context).findProduct(currentOrPendingPlan.getProduct().getName(), requestedDate);
if (isAddonIncluded(baseProduct, targetAddOnPlan)) {
throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_AO_ALREADY_INCLUDED, targetAddOnPlan.getName(), currentOrPendingPlan.getProduct().getName());
}
if (!isAddonAvailable(baseProduct, targetAddOnPlan)) {
throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_AO_NOT_AVAILABLE, targetAddOnPlan.getName(), currentOrPendingPlan.getProduct().getName());
}
}
Aggregations