Search in sources :

Example 1 with Catalog

use of org.killbill.billing.catalog.api.Catalog in project killbill by killbill.

the class DefaultSubscriptionInternalApi method getDefaultBillCycleDayLocal.

@Override
public int getDefaultBillCycleDayLocal(final Map<UUID, Integer> bcdCache, final SubscriptionBase subscription, final SubscriptionBase baseSubscription, final PlanPhaseSpecifier planPhaseSpecifier, final DateTimeZone accountTimeZone, final int accountBillCycleDayLocal, final DateTime effectiveDate, final InternalTenantContext context) throws SubscriptionBaseApiException {
    try {
        final Catalog catalog = catalogService.getFullCatalog(true, true, context);
        final BillingAlignment alignment = catalog.billingAlignment(planPhaseSpecifier, effectiveDate);
        return BillCycleDayCalculator.calculateBcdForAlignment(bcdCache, subscription, baseSubscription, alignment, accountTimeZone, accountBillCycleDayLocal);
    } catch (final CatalogApiException e) {
        throw new SubscriptionBaseApiException(e);
    }
}
Also used : CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) BillingAlignment(org.killbill.billing.catalog.api.BillingAlignment) Catalog(org.killbill.billing.catalog.api.Catalog) SubscriptionBaseApiException(org.killbill.billing.subscription.api.user.SubscriptionBaseApiException) PlanPhasePriceOverride(org.killbill.billing.catalog.api.PlanPhasePriceOverride)

Example 2 with Catalog

use of org.killbill.billing.catalog.api.Catalog in project killbill by killbill.

the class DefaultSubscriptionInternalApi method createBaseSubscriptionsWithAddOns.

@Override
public List<SubscriptionBaseWithAddOns> createBaseSubscriptionsWithAddOns(final UUID accountId, final Iterable<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifier, final InternalCallContext context) throws SubscriptionBaseApiException {
    try {
        final Catalog catalog = catalogService.getFullCatalog(true, true, context);
        final CallContext callContext = internalCallContextFactory.createCallContext(context);
        final DateTime now = clock.getUTCNow();
        final Collection<SubscriptionAndAddOnsSpecifier> subscriptionAndAddOns = new ArrayList<SubscriptionAndAddOnsSpecifier>();
        for (final BaseEntitlementWithAddOnsSpecifier entitlementWithAddOnsSpecifier : baseEntitlementWithAddOnsSpecifier) {
            final DateTime effectiveDate = (entitlementWithAddOnsSpecifier.getBillingEffectiveDate() != null) ? DefaultClock.truncateMs(entitlementWithAddOnsSpecifier.getBillingEffectiveDate().toDateTimeAtStartOfDay()) : now;
            final SubscriptionBaseBundle bundle = createBundleForAccount(accountId, entitlementWithAddOnsSpecifier.getExternalKey(), context);
            final SubscriptionAndAddOnsSpecifier subscriptionAndAddOnsSpecifier = new SubscriptionAndAddOnsSpecifier(bundle.getId(), effectiveDate, verifyAndBuildSubscriptionSpecifiers(bundle.getId(), bundle.getExternalKey(), entitlementWithAddOnsSpecifier.getEntitlementSpecifier(), entitlementWithAddOnsSpecifier.isMigrated(), context, now, effectiveDate, catalog, callContext));
            subscriptionAndAddOns.add(subscriptionAndAddOnsSpecifier);
        }
        return apiService.createPlansWithAddOns(accountId, subscriptionAndAddOns, callContext);
    } catch (final CatalogApiException e) {
        throw new SubscriptionBaseApiException(e);
    }
}
Also used : CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) ArrayList(java.util.ArrayList) SubscriptionAndAddOnsSpecifier(org.killbill.billing.subscription.api.user.SubscriptionAndAddOnsSpecifier) SubscriptionBaseBundle(org.killbill.billing.subscription.api.user.SubscriptionBaseBundle) DefaultSubscriptionBaseBundle(org.killbill.billing.subscription.api.user.DefaultSubscriptionBaseBundle) BaseEntitlementWithAddOnsSpecifier(org.killbill.billing.entitlement.api.BaseEntitlementWithAddOnsSpecifier) PlanPhasePriceOverridesWithCallContext(org.killbill.billing.catalog.api.PlanPhasePriceOverridesWithCallContext) CallContext(org.killbill.billing.util.callcontext.CallContext) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) Catalog(org.killbill.billing.catalog.api.Catalog) DateTime(org.joda.time.DateTime) SubscriptionBaseApiException(org.killbill.billing.subscription.api.user.SubscriptionBaseApiException) PlanPhasePriceOverride(org.killbill.billing.catalog.api.PlanPhasePriceOverride)

Example 3 with Catalog

use of org.killbill.billing.catalog.api.Catalog in project killbill by killbill.

the class DefaultSubscriptionInternalApi method getDryRunChangePlanEffectiveDate.

@Override
public DateTime getDryRunChangePlanEffectiveDate(final SubscriptionBase subscription, final PlanSpecifier spec, final DateTime requestedDateWithMs, final BillingActionPolicy requestedPolicy, final List<PlanPhasePriceOverride> overrides, final InternalCallContext context) throws SubscriptionBaseApiException, CatalogApiException {
    final TenantContext tenantContext = internalCallContextFactory.createTenantContext(context);
    final CallContext callContext = internalCallContextFactory.createCallContext(context);
    // verify the number of subscriptions (of the same kind) allowed per bundle
    final Catalog catalog = catalogService.getFullCatalog(true, true, context);
    final DateTime now = clock.getUTCNow();
    final DateTime effectiveDate = (requestedDateWithMs != null) ? DefaultClock.truncateMs(requestedDateWithMs) : now;
    final PlanPhasePriceOverridesWithCallContext overridesWithContext = new DefaultPlanPhasePriceOverridesWithCallContext(overrides, callContext);
    final Plan plan = catalog.createOrFindPlan(spec, overridesWithContext, effectiveDate);
    if (ProductCategory.ADD_ON.toString().equalsIgnoreCase(plan.getProduct().getCategory().toString())) {
        if (plan.getPlansAllowedInBundle() != -1 && plan.getPlansAllowedInBundle() > 0 && addonUtils.countExistingAddOnsWithSamePlanName(getSubscriptionsForBundle(subscription.getBundleId(), null, context), plan.getName()) >= plan.getPlansAllowedInBundle()) {
            // the plan can be changed to the new value, because it has reached its limit by bundle
            throw new SubscriptionBaseApiException(ErrorCode.SUB_CHANGE_AO_MAX_PLAN_ALLOWED_BY_BUNDLE, plan.getName());
        }
    }
    return apiService.dryRunChangePlan((DefaultSubscriptionBase) subscription, spec, requestedDateWithMs, requestedPolicy, tenantContext);
}
Also used : PlanPhasePriceOverridesWithCallContext(org.killbill.billing.catalog.api.PlanPhasePriceOverridesWithCallContext) InternalTenantContext(org.killbill.billing.callcontext.InternalTenantContext) TenantContext(org.killbill.billing.util.callcontext.TenantContext) Plan(org.killbill.billing.catalog.api.Plan) PlanPhasePriceOverridesWithCallContext(org.killbill.billing.catalog.api.PlanPhasePriceOverridesWithCallContext) CallContext(org.killbill.billing.util.callcontext.CallContext) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) Catalog(org.killbill.billing.catalog.api.Catalog) DateTime(org.joda.time.DateTime) SubscriptionBaseApiException(org.killbill.billing.subscription.api.user.SubscriptionBaseApiException) PlanPhasePriceOverride(org.killbill.billing.catalog.api.PlanPhasePriceOverride)

Example 4 with Catalog

use of org.killbill.billing.catalog.api.Catalog in project killbill by killbill.

the class DefaultSubscriptionDao method createSubscriptionForInternalUse.

private SubscriptionBase createSubscriptionForInternalUse(final SubscriptionBase shellSubscription, final List<SubscriptionBaseEvent> events, final InternalTenantContext context) throws CatalogApiException {
    final DefaultSubscriptionBase result = new DefaultSubscriptionBase(new SubscriptionBuilder(((DefaultSubscriptionBase) shellSubscription)), null, clock);
    if (!events.isEmpty()) {
        final Catalog fullCatalog = catalogService.getFullCatalog(true, true, context);
        result.rebuildTransitions(events, fullCatalog);
    }
    return result;
}
Also used : DefaultSubscriptionBase(org.killbill.billing.subscription.api.user.DefaultSubscriptionBase) SubscriptionBuilder(org.killbill.billing.subscription.api.user.SubscriptionBuilder) Catalog(org.killbill.billing.catalog.api.Catalog)

Example 5 with Catalog

use of org.killbill.billing.catalog.api.Catalog in project killbill by killbill.

the class DefaultInternalBillingApi method addBillingEventsForSubscription.

private void addBillingEventsForSubscription(final ImmutableAccountData account, final List<SubscriptionBase> subscriptions, final SubscriptionBase baseSubscription, final boolean dryRunMode, final InternalCallContext context, final DefaultBillingEventSet result, final Set<UUID> skipSubscriptionsSet) throws AccountApiException, CatalogApiException, SubscriptionBaseApiException {
    // If dryRun is specified, we don't want to to update the account BCD value, so we initialize the flag updatedAccountBCD to true
    boolean updatedAccountBCD = dryRunMode;
    final Map<UUID, Integer> bcdCache = new HashMap<UUID, Integer>();
    int currentAccountBCD = accountApi.getBCD(account.getId(), context);
    for (final SubscriptionBase subscription : subscriptions) {
        // The subscription did not even start, so there is nothing to do yet, we can skip and avoid some NPE down the line when calculating the BCD
        if (subscription.getState() == EntitlementState.PENDING) {
            log.info("Skipping subscription id='{}', state = EntitlementState.PENDING", subscription.getId());
            continue;
        }
        final List<EffectiveSubscriptionInternalEvent> billingTransitions = subscriptionApi.getBillingTransitions(subscription, context);
        if (billingTransitions.isEmpty() || (billingTransitions.get(0).getTransitionType() != SubscriptionBaseTransitionType.CREATE && billingTransitions.get(0).getTransitionType() != SubscriptionBaseTransitionType.TRANSFER)) {
            log.warn("Skipping billing events for subscription " + subscription.getId() + ": Does not start with a valid CREATE transition");
            skipSubscriptionsSet.add(subscription.getId());
            return;
        }
        final Catalog catalog = catalogService.getFullCatalog(true, true, context);
        Integer overridenBCD = null;
        for (final EffectiveSubscriptionInternalEvent transition : billingTransitions) {
            //
            // A BCD_CHANGE transition defines a new billCycleDayLocal for the subscription and this overrides whatever computation
            // occurs below (which is based on billing alignment policy). Also multiple of those BCD_CHANGE transitions could occur,
            // to define different intervals with different billing cycle days.
            //
            overridenBCD = transition.getNextBillCycleDayLocal() != null ? transition.getNextBillCycleDayLocal() : overridenBCD;
            final int bcdLocal = overridenBCD != null ? overridenBCD : calculateBcdForTransition(catalog, bcdCache, baseSubscription, subscription, account, currentAccountBCD, transition);
            if (currentAccountBCD == 0 && !updatedAccountBCD) {
                log.info("Setting account BCD='{}', accountId='{}'", bcdLocal, account.getId());
                accountApi.updateBCD(account.getExternalKey(), bcdLocal, context);
                updatedAccountBCD = true;
            }
            final BillingEvent event = new DefaultBillingEvent(account, transition, subscription, bcdLocal, account.getCurrency(), catalog);
            result.add(event);
        }
    }
}
Also used : SubscriptionBase(org.killbill.billing.subscription.api.SubscriptionBase) HashMap(java.util.HashMap) EffectiveSubscriptionInternalEvent(org.killbill.billing.events.EffectiveSubscriptionInternalEvent) BillingEvent(org.killbill.billing.junction.BillingEvent) UUID(java.util.UUID) StaticCatalog(org.killbill.billing.catalog.api.StaticCatalog) Catalog(org.killbill.billing.catalog.api.Catalog)

Aggregations

Catalog (org.killbill.billing.catalog.api.Catalog)12 DateTime (org.joda.time.DateTime)7 CatalogApiException (org.killbill.billing.catalog.api.CatalogApiException)5 PlanPhasePriceOverridesWithCallContext (org.killbill.billing.catalog.api.PlanPhasePriceOverridesWithCallContext)5 SubscriptionBaseApiException (org.killbill.billing.subscription.api.user.SubscriptionBaseApiException)5 InternalCallContext (org.killbill.billing.callcontext.InternalCallContext)4 Plan (org.killbill.billing.catalog.api.Plan)4 PlanPhasePriceOverride (org.killbill.billing.catalog.api.PlanPhasePriceOverride)4 DefaultSubscriptionBase (org.killbill.billing.subscription.api.user.DefaultSubscriptionBase)3 SubscriptionBuilder (org.killbill.billing.subscription.api.user.SubscriptionBuilder)3 SubscriptionBaseEvent (org.killbill.billing.subscription.events.SubscriptionBaseEvent)3 SubscriptionBaseError (org.killbill.billing.subscription.exceptions.SubscriptionBaseError)3 CallContext (org.killbill.billing.util.callcontext.CallContext)3 ArrayList (java.util.ArrayList)2 UUID (java.util.UUID)2 InternalTenantContext (org.killbill.billing.callcontext.InternalTenantContext)2 PhaseType (org.killbill.billing.catalog.api.PhaseType)2 PlanPhaseSpecifier (org.killbill.billing.catalog.api.PlanPhaseSpecifier)2 PlanSpecifier (org.killbill.billing.catalog.api.PlanSpecifier)2 BillingEvent (org.killbill.billing.junction.BillingEvent)2