Search in sources :

Example 1 with SubscriptionSpecifier

use of org.killbill.billing.subscription.api.user.SubscriptionSpecifier in project killbill by killbill.

the class DefaultSubscriptionInternalApi method verifyAndBuildSubscriptionSpecifiers.

private List<SubscriptionSpecifier> verifyAndBuildSubscriptionSpecifiers(final UUID bundleId, final String externalKey, final Iterable<EntitlementSpecifier> entitlements, final boolean isMigrated, final InternalCallContext context, final DateTime now, final DateTime effectiveDate, final Catalog catalog, final CallContext callContext) throws SubscriptionBaseApiException, CatalogApiException {
    final List<SubscriptionSpecifier> subscriptions = new ArrayList<SubscriptionSpecifier>();
    boolean first = true;
    final List<SubscriptionBase> subscriptionsForBundle = getSubscriptionsForBundle(bundleId, null, context);
    for (final EntitlementSpecifier entitlement : entitlements) {
        final PlanPhaseSpecifier spec = entitlement.getPlanPhaseSpecifier();
        final PlanPhasePriceOverridesWithCallContext overridesWithContext = new DefaultPlanPhasePriceOverridesWithCallContext(entitlement.getOverrides(), callContext);
        final Plan plan = catalog.createOrFindPlan(spec, overridesWithContext, effectiveDate);
        final PlanPhase phase = plan.getAllPhases()[0];
        if (phase == null) {
            throw new SubscriptionBaseError(String.format("No initial PlanPhase for Product %s, term %s and set %s does not exist in the catalog", spec.getProductName(), spec.getBillingPeriod().toString(), plan.getPriceListName()));
        }
        if (first) {
            first = false;
            if (plan.getProduct().getCategory() != ProductCategory.BASE) {
                throw new SubscriptionBaseApiException(new IllegalArgumentException(), ErrorCode.SUB_CREATE_NO_BP.getCode(), "Missing Base Subscription.");
            }
        }
        // verify the number of subscriptions (of the same kind) allowed per bundle and the existing ones
        if (ProductCategory.ADD_ON.toString().equalsIgnoreCase(plan.getProduct().getCategory().toString())) {
            if (plan.getPlansAllowedInBundle() != -1 && plan.getPlansAllowedInBundle() > 0) {
                final int existingAddOnsWithSamePlanName = addonUtils.countExistingAddOnsWithSamePlanName(subscriptionsForBundle, plan.getName());
                final int currentAddOnsWithSamePlanName = countCurrentAddOnsWithSamePlanName(entitlements, catalog, plan.getName(), effectiveDate, callContext);
                if ((existingAddOnsWithSamePlanName + currentAddOnsWithSamePlanName) > plan.getPlansAllowedInBundle()) {
                    // a new ADD_ON subscription of the same plan can't be added because it has reached its limit by bundle
                    throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_AO_MAX_PLAN_ALLOWED_BY_BUNDLE, plan.getName());
                }
            }
        }
        final SubscriptionSpecifier subscription = new SubscriptionSpecifier();
        subscription.setRealPriceList(plan.getPriceListName());
        subscription.setEffectiveDate(effectiveDate);
        subscription.setProcessedDate(now);
        subscription.setPlan(plan);
        subscription.setInitialPhase(spec.getPhaseType());
        subscription.setBuilder(new SubscriptionBuilder().setId(UUIDs.randomUUID()).setBundleId(bundleId).setBundleExternalKey(externalKey).setCategory(plan.getProduct().getCategory()).setBundleStartDate(effectiveDate).setAlignStartDate(effectiveDate).setMigrated(isMigrated));
        subscriptions.add(subscription);
    }
    return subscriptions;
}
Also used : SubscriptionSpecifier(org.killbill.billing.subscription.api.user.SubscriptionSpecifier) PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) ArrayList(java.util.ArrayList) SubscriptionBuilder(org.killbill.billing.subscription.api.user.SubscriptionBuilder) Plan(org.killbill.billing.catalog.api.Plan) SubscriptionBase(org.killbill.billing.subscription.api.SubscriptionBase) DefaultSubscriptionBase(org.killbill.billing.subscription.api.user.DefaultSubscriptionBase) EntitlementSpecifier(org.killbill.billing.entitlement.api.EntitlementSpecifier) PlanPhasePriceOverridesWithCallContext(org.killbill.billing.catalog.api.PlanPhasePriceOverridesWithCallContext) SubscriptionBaseError(org.killbill.billing.subscription.exceptions.SubscriptionBaseError) PlanPhase(org.killbill.billing.catalog.api.PlanPhase) SubscriptionBaseApiException(org.killbill.billing.subscription.api.user.SubscriptionBaseApiException)

Example 2 with SubscriptionSpecifier

use of org.killbill.billing.subscription.api.user.SubscriptionSpecifier in project killbill by killbill.

the class DefaultSubscriptionBaseCreateApi method prepareSubscriptionAndAddOnsSpecifier.

private void prepareSubscriptionAndAddOnsSpecifier(final Collection<SubscriptionAndAddOnsSpecifier> subscriptionAndAddOns, final SubscriptionBaseWithAddOnsSpecifier subscriptionBaseWithAddOnsSpecifier, final boolean renameCancelledBundleIfExist, final SubscriptionCatalog catalog, final AddonUtils addonUtils, final CacheController<UUID, UUID> accountIdCacheController, final CallContext callContext, final InternalCallContext context) throws SubscriptionBaseApiException, CatalogApiException {
    SubscriptionBaseBundle bundle = getBundleWithSanity(subscriptionBaseWithAddOnsSpecifier, catalog, callContext, context);
    final DateTime billingRequestedDateRaw = (subscriptionBaseWithAddOnsSpecifier.getBillingEffectiveDate() != null) ? context.toUTCDateTime(subscriptionBaseWithAddOnsSpecifier.getBillingEffectiveDate()) : context.getCreatedDate();
    final SubscriptionBase baseSubscription;
    final DateTime billingRequestedDate;
    if (bundle != null) {
        baseSubscription = dao.getBaseSubscription(bundle.getId(), catalog, context);
        billingRequestedDate = computeActualBillingRequestedDate(bundle, billingRequestedDateRaw, baseSubscription, catalog, context);
    } else {
        baseSubscription = null;
        billingRequestedDate = billingRequestedDateRaw;
    }
    final List<EntitlementSpecifier> reorderedSpecifiers = new ArrayList<EntitlementSpecifier>();
    final List<Plan> createdOrRetrievedPlans = new ArrayList<Plan>();
    final boolean hasBaseOrStandalonePlanSpecifier = createPlansIfNeededAndReorderBPOrStandaloneSpecFirstWithSanity(subscriptionBaseWithAddOnsSpecifier, catalog, billingRequestedDate, reorderedSpecifiers, createdOrRetrievedPlans, callContext);
    if (hasBaseOrStandalonePlanSpecifier && baseSubscription != null) {
        throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_BP_EXISTS, bundle.getExternalKey());
    }
    if (bundle == null && hasBaseOrStandalonePlanSpecifier) {
        bundle = createBundleForAccount(callContext.getAccountId(), subscriptionBaseWithAddOnsSpecifier.getBundleExternalKey(), renameCancelledBundleIfExist, catalog, accountIdCacheController, context);
    } else if (bundle == null) {
        log.warn("Invalid specifier: {}", subscriptionBaseWithAddOnsSpecifier);
        throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_NO_BP, subscriptionBaseWithAddOnsSpecifier.getBundleExternalKey());
    }
    final List<SubscriptionSpecifier> subscriptionSpecifiers = verifyAndBuildSubscriptionSpecifiers(bundle, hasBaseOrStandalonePlanSpecifier, reorderedSpecifiers, createdOrRetrievedPlans, subscriptionBaseWithAddOnsSpecifier.isMigrated(), billingRequestedDate, catalog, addonUtils, callContext, context);
    final SubscriptionAndAddOnsSpecifier subscriptionAndAddOnsSpecifier = new SubscriptionAndAddOnsSpecifier(bundle, billingRequestedDate, subscriptionSpecifiers);
    subscriptionAndAddOns.add(subscriptionAndAddOnsSpecifier);
}
Also used : SubscriptionSpecifier(org.killbill.billing.subscription.api.user.SubscriptionSpecifier) ArrayList(java.util.ArrayList) SubscriptionAndAddOnsSpecifier(org.killbill.billing.subscription.api.user.SubscriptionAndAddOnsSpecifier) Plan(org.killbill.billing.catalog.api.Plan) DateTime(org.joda.time.DateTime) SubscriptionBase(org.killbill.billing.subscription.api.SubscriptionBase) DefaultSubscriptionBase(org.killbill.billing.subscription.api.user.DefaultSubscriptionBase) EntitlementSpecifier(org.killbill.billing.entitlement.api.EntitlementSpecifier) SubscriptionBaseBundle(org.killbill.billing.subscription.api.user.SubscriptionBaseBundle) SubscriptionBaseApiException(org.killbill.billing.subscription.api.user.SubscriptionBaseApiException)

Example 3 with SubscriptionSpecifier

use of org.killbill.billing.subscription.api.user.SubscriptionSpecifier in project killbill by killbill.

the class DefaultSubscriptionBaseCreateApi method verifyAndBuildSubscriptionSpecifiers.

private List<SubscriptionSpecifier> verifyAndBuildSubscriptionSpecifiers(final SubscriptionBaseBundle bundle, final boolean hasBaseOrStandalonePlanSpecifier, final List<EntitlementSpecifier> entitlements, final List<Plan> entitlementsPlans, final boolean isMigrated, final DateTime effectiveDate, final SubscriptionCatalog catalog, final AddonUtils addonUtils, final TenantContext callContext, final InternalCallContext context) throws SubscriptionBaseApiException, CatalogApiException {
    final List<SubscriptionSpecifier> subscriptions = new ArrayList<SubscriptionSpecifier>();
    for (int i = 0; i < entitlements.size(); i++) {
        final EntitlementSpecifier entitlement = entitlements.get(i);
        final PlanPhaseSpecifier spec = entitlement.getPlanPhaseSpecifier();
        if (spec == null) {
            // BP already exists
            continue;
        }
        final Plan plan = entitlementsPlans.get(i);
        final PlanPhase phase = plan.getAllPhases()[0];
        if (phase == null) {
            throw new SubscriptionBaseError(String.format("No initial PlanPhase for Product %s, term %s and set %s does not exist in the catalog", spec.getProductName(), spec.getBillingPeriod().toString(), plan.getPriceList()));
        }
        // verify the number of subscriptions (of the same kind) allowed per bundle and the existing ones
        if (ProductCategory.ADD_ON.toString().equalsIgnoreCase(plan.getProduct().getCategory().toString())) {
            if (plan.getPlansAllowedInBundle() != -1 && plan.getPlansAllowedInBundle() > 0) {
                // TODO We should also look to the specifiers being created for validation
                final List<DefaultSubscriptionBase> subscriptionsForBundle = getSubscriptionsForBundle(bundle.getId(), null, catalog, addonUtils, callContext, context);
                final int existingAddOnsWithSamePlanName = addonUtils.countExistingAddOnsWithSamePlanName(subscriptionsForBundle, plan.getName());
                final int currentAddOnsWithSamePlanName = countCurrentAddOnsWithSamePlanName(entitlementsPlans, plan);
                if ((existingAddOnsWithSamePlanName + currentAddOnsWithSamePlanName) > plan.getPlansAllowedInBundle()) {
                    // a new ADD_ON subscription of the same plan can't be added because it has reached its limit by bundle
                    throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_AO_MAX_PLAN_ALLOWED_BY_BUNDLE, plan.getName());
                }
            }
        }
        final DateTime bundleStartDate;
        if (hasBaseOrStandalonePlanSpecifier) {
            bundleStartDate = effectiveDate;
        } else {
            final SubscriptionBase baseSubscription = dao.getBaseSubscription(bundle.getId(), catalog, context);
            bundleStartDate = getBundleStartDateWithSanity(bundle.getId(), baseSubscription, plan, effectiveDate, addonUtils, context);
        }
        final SubscriptionSpecifier subscription = new SubscriptionSpecifier();
        subscription.setRealPriceList(plan.getPriceList().getName());
        subscription.setEffectiveDate(effectiveDate);
        subscription.setProcessedDate(context.getCreatedDate());
        subscription.setPlan(plan);
        subscription.setInitialPhase(spec.getPhaseType());
        subscription.setBuilder(new SubscriptionBuilder().setId(UUIDs.randomUUID()).setBundleId(bundle.getId()).setExternalKey(entitlement.getExternalKey()).setBundleExternalKey(bundle.getExternalKey()).setCategory(plan.getProduct().getCategory()).setBundleStartDate(bundleStartDate).setAlignStartDate(effectiveDate).setMigrated(isMigrated).setSubscriptionBCD(entitlement.getBillCycleDay()));
        subscriptions.add(subscription);
    }
    return subscriptions;
}
Also used : SubscriptionSpecifier(org.killbill.billing.subscription.api.user.SubscriptionSpecifier) PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) ArrayList(java.util.ArrayList) SubscriptionBuilder(org.killbill.billing.subscription.api.user.SubscriptionBuilder) Plan(org.killbill.billing.catalog.api.Plan) DateTime(org.joda.time.DateTime) EntitlementSpecifier(org.killbill.billing.entitlement.api.EntitlementSpecifier) SubscriptionBase(org.killbill.billing.subscription.api.SubscriptionBase) DefaultSubscriptionBase(org.killbill.billing.subscription.api.user.DefaultSubscriptionBase) SubscriptionBaseError(org.killbill.billing.subscription.exceptions.SubscriptionBaseError) PlanPhase(org.killbill.billing.catalog.api.PlanPhase) DefaultSubscriptionBase(org.killbill.billing.subscription.api.user.DefaultSubscriptionBase) SubscriptionBaseApiException(org.killbill.billing.subscription.api.user.SubscriptionBaseApiException)

Aggregations

ArrayList (java.util.ArrayList)3 Plan (org.killbill.billing.catalog.api.Plan)3 EntitlementSpecifier (org.killbill.billing.entitlement.api.EntitlementSpecifier)3 SubscriptionBase (org.killbill.billing.subscription.api.SubscriptionBase)3 DefaultSubscriptionBase (org.killbill.billing.subscription.api.user.DefaultSubscriptionBase)3 SubscriptionBaseApiException (org.killbill.billing.subscription.api.user.SubscriptionBaseApiException)3 SubscriptionSpecifier (org.killbill.billing.subscription.api.user.SubscriptionSpecifier)3 DateTime (org.joda.time.DateTime)2 PlanPhase (org.killbill.billing.catalog.api.PlanPhase)2 PlanPhaseSpecifier (org.killbill.billing.catalog.api.PlanPhaseSpecifier)2 SubscriptionBuilder (org.killbill.billing.subscription.api.user.SubscriptionBuilder)2 SubscriptionBaseError (org.killbill.billing.subscription.exceptions.SubscriptionBaseError)2 PlanPhasePriceOverridesWithCallContext (org.killbill.billing.catalog.api.PlanPhasePriceOverridesWithCallContext)1 SubscriptionAndAddOnsSpecifier (org.killbill.billing.subscription.api.user.SubscriptionAndAddOnsSpecifier)1 SubscriptionBaseBundle (org.killbill.billing.subscription.api.user.SubscriptionBaseBundle)1