Search in sources :

Example 6 with PhaseType

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

the class PlanAligner method getTimedPhaseOnChange.

private TimedPhase getTimedPhaseOnChange(final DateTime subscriptionStartDate, final DateTime bundleStartDate, final PlanPhase currentPhase, final Plan currentPlan, final Plan nextPlan, final DateTime effectiveDate, final DateTime lastOrCurrentChangeEffectiveDate, final PhaseType originalInitialPhase, @Nullable final PhaseType newPlanInitialPhaseType, final WhichPhase which, final InternalTenantContext context) throws CatalogApiException, SubscriptionBaseApiException {
    final Catalog catalog = catalogService.getFullCatalog(true, true, context);
    final PlanPhaseSpecifier fromPlanPhaseSpecifier = new PlanPhaseSpecifier(currentPlan.getName(), currentPhase.getPhaseType());
    final PlanSpecifier toPlanSpecifier = new PlanSpecifier(nextPlan.getName());
    final PhaseType initialPhase;
    final DateTime planStartDate;
    final PlanAlignmentChange alignment = catalog.planChangeAlignment(fromPlanPhaseSpecifier, toPlanSpecifier, effectiveDate);
    switch(alignment) {
        case START_OF_SUBSCRIPTION:
            planStartDate = subscriptionStartDate;
            initialPhase = newPlanInitialPhaseType != null ? newPlanInitialPhaseType : (isPlanContainPhaseType(nextPlan, originalInitialPhase) ? originalInitialPhase : null);
            break;
        case START_OF_BUNDLE:
            planStartDate = bundleStartDate;
            initialPhase = newPlanInitialPhaseType != null ? newPlanInitialPhaseType : (isPlanContainPhaseType(nextPlan, originalInitialPhase) ? originalInitialPhase : null);
            break;
        case CHANGE_OF_PLAN:
            planStartDate = lastOrCurrentChangeEffectiveDate;
            initialPhase = newPlanInitialPhaseType;
            break;
        case CHANGE_OF_PRICELIST:
            throw new SubscriptionBaseError(String.format("Not implemented yet %s", alignment));
        default:
            throw new SubscriptionBaseError(String.format("Unknown PlanAlignmentChange %s", alignment));
    }
    final List<TimedPhase> timedPhases = getPhaseAlignments(nextPlan, initialPhase, planStartDate);
    return getTimedPhase(timedPhases, effectiveDate, which);
}
Also used : PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) SubscriptionBaseError(org.killbill.billing.subscription.exceptions.SubscriptionBaseError) PlanAlignmentChange(org.killbill.billing.catalog.api.PlanAlignmentChange) PhaseType(org.killbill.billing.catalog.api.PhaseType) Catalog(org.killbill.billing.catalog.api.Catalog) DateTime(org.joda.time.DateTime) PlanSpecifier(org.killbill.billing.catalog.api.PlanSpecifier)

Example 7 with PhaseType

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

the class DefaultSubscriptionBaseApiService method doChangePlan.

private void doChangePlan(final DefaultSubscriptionBase subscription, final PlanSpecifier spec, final List<PlanPhasePriceOverride> overrides, final DateTime effectiveDate, final CallContext context) throws SubscriptionBaseApiException, CatalogApiException {
    final InternalCallContext internalCallContext = createCallContextFromBundleId(subscription.getBundleId(), context);
    final PlanPhasePriceOverridesWithCallContext overridesWithContext = new DefaultPlanPhasePriceOverridesWithCallContext(overrides, context);
    final Plan newPlan = catalogService.getFullCatalog(true, true, internalCallContext).createOrFindPlan(spec, overridesWithContext, effectiveDate, subscription.getStartDate());
    final PhaseType initialPhaseType;
    if (overrides != null && overrides.size() == 1 && overrides.get(0).getPlanPhaseSpecifier() != null && overrides.get(0).getCurrency() == null) {
        initialPhaseType = overrides.get(0).getPlanPhaseSpecifier().getPhaseType();
    } else {
        initialPhaseType = null;
    }
    if (ProductCategory.ADD_ON.toString().equalsIgnoreCase(newPlan.getProduct().getCategory().toString())) {
        if (newPlan.getPlansAllowedInBundle() != -1 && newPlan.getPlansAllowedInBundle() > 0 && addonUtils.countExistingAddOnsWithSamePlanName(dao.getSubscriptions(subscription.getBundleId(), null, internalCallContext), newPlan.getName()) >= newPlan.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, newPlan.getName());
        }
    }
    if (newPlan.getProduct().getCategory() != subscription.getCategory()) {
        throw new SubscriptionBaseApiException(ErrorCode.SUB_CHANGE_INVALID, subscription.getId());
    }
    final List<DefaultSubscriptionBase> addOnSubscriptionsToBeCancelled = new ArrayList<DefaultSubscriptionBase>();
    final List<SubscriptionBaseEvent> addOnCancelEvents = new ArrayList<SubscriptionBaseEvent>();
    final List<SubscriptionBaseEvent> changeEvents = getEventsOnChangePlan(subscription, newPlan, newPlan.getPriceListName(), effectiveDate, true, addOnSubscriptionsToBeCancelled, addOnCancelEvents, initialPhaseType, internalCallContext);
    dao.changePlan(subscription, changeEvents, addOnSubscriptionsToBeCancelled, addOnCancelEvents, internalCallContext);
    final Catalog fullCatalog = catalogService.getFullCatalog(true, true, internalCallContext);
    subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId(), internalCallContext), fullCatalog);
}
Also used : PlanPhasePriceOverridesWithCallContext(org.killbill.billing.catalog.api.PlanPhasePriceOverridesWithCallContext) DefaultPlanPhasePriceOverridesWithCallContext(org.killbill.billing.subscription.api.svcs.DefaultPlanPhasePriceOverridesWithCallContext) PhaseType(org.killbill.billing.catalog.api.PhaseType) ArrayList(java.util.ArrayList) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) Plan(org.killbill.billing.catalog.api.Plan) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent) DefaultPlanPhasePriceOverridesWithCallContext(org.killbill.billing.subscription.api.svcs.DefaultPlanPhasePriceOverridesWithCallContext) Catalog(org.killbill.billing.catalog.api.Catalog)

Example 8 with PhaseType

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

the class EventsStreamBuilder method createPlanPhaseSpecifier.

private PlanPhaseSpecifier createPlanPhaseSpecifier(final SubscriptionBase subscription) {
    final String planName;
    final PhaseType phaseType;
    if (subscription.getState() == EntitlementState.PENDING) {
        final SubscriptionBaseTransition transition = subscription.getPendingTransition();
        planName = transition.getNextPlan().getName();
        phaseType = transition.getNextPhase().getPhaseType();
    } else {
        planName = subscription.getLastActivePlan().getName();
        phaseType = subscription.getLastActivePhase().getPhaseType();
    }
    return new PlanPhaseSpecifier(planName, phaseType);
}
Also used : PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) PhaseType(org.killbill.billing.catalog.api.PhaseType) SubscriptionBaseTransition(org.killbill.billing.subscription.api.user.SubscriptionBaseTransition)

Example 9 with PhaseType

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

the class SubscriptionResourceHelpers method buildPlanPhasePriceOverride.

private static PlanPhasePriceOverride buildPlanPhasePriceOverride(final PlanSpecifier spec, final Currency currency, final PhasePriceJson input, final List<UsagePriceOverride> usagePrices) {
    if (input.getPhaseName() != null) {
        return new PlanPhasePriceOverride() {

            @Override
            public String getPhaseName() {
                return input.getPhaseName();
            }

            @Override
            public PlanPhaseSpecifier getPlanPhaseSpecifier() {
                return null;
            }

            @Override
            public Currency getCurrency() {
                return currency;
            }

            @Override
            public BigDecimal getFixedPrice() {
                return input.getFixedPrice();
            }

            @Override
            public BigDecimal getRecurringPrice() {
                return input.getRecurringPrice();
            }

            @Override
            public List<UsagePriceOverride> getUsagePriceOverrides() {
                return usagePrices;
            }
        };
    }
    final PhaseType phaseType = input.getPhaseType() != null ? PhaseType.valueOf(input.getPhaseType()) : null;
    final PlanPhaseSpecifier planPhaseSpecifier = spec.getPlanName() != null ? new PlanPhaseSpecifier(spec.getPlanName(), phaseType) : new PlanPhaseSpecifier(spec.getProductName(), spec.getBillingPeriod(), spec.getPriceListName(), phaseType);
    final Currency resolvedCurrency = input.getFixedPrice() != null || input.getRecurringPrice() != null ? currency : null;
    return new PlanPhasePriceOverride() {

        @Override
        public String getPhaseName() {
            return null;
        }

        @Override
        public PlanPhaseSpecifier getPlanPhaseSpecifier() {
            return planPhaseSpecifier;
        }

        @Override
        public Currency getCurrency() {
            return resolvedCurrency;
        }

        @Override
        public BigDecimal getFixedPrice() {
            return input.getFixedPrice();
        }

        @Override
        public BigDecimal getRecurringPrice() {
            return input.getRecurringPrice();
        }

        @Override
        public List<UsagePriceOverride> getUsagePriceOverrides() {
            return usagePrices;
        }
    };
}
Also used : PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) Currency(org.killbill.billing.catalog.api.Currency) PhaseType(org.killbill.billing.catalog.api.PhaseType) UsagePriceOverride(org.killbill.billing.catalog.api.UsagePriceOverride) PlanPhasePriceOverride(org.killbill.billing.catalog.api.PlanPhasePriceOverride)

Example 10 with PhaseType

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

the class DefaultSubscriptionBaseApiService method doChangePlan.

private void doChangePlan(final DefaultSubscriptionBase subscription, final EntitlementSpecifier spec, final DateTime effectiveDate, final CallContext context) throws SubscriptionBaseApiException, CatalogApiException {
    final InternalCallContext internalCallContext = createCallContextFromBundleId(subscription.getBundleId(), context);
    final PlanPhasePriceOverridesWithCallContext overridesWithContext = new DefaultPlanPhasePriceOverridesWithCallContext(spec.getOverrides(), context);
    final SubscriptionCatalog catalog = subscriptionCatalogApi.getFullCatalog(internalCallContext);
    final PlanPhaseSpecifier planPhaseSpecifier = spec.getPlanPhaseSpecifier();
    final StaticCatalog versionCatalog = catalog.versionForDate(effectiveDate);
    final Plan newPlan = versionCatalog.createOrFindPlan(planPhaseSpecifier, overridesWithContext);
    final PhaseType initialPhaseType = planPhaseSpecifier.getPhaseType();
    if (ProductCategory.ADD_ON.toString().equalsIgnoreCase(newPlan.getProduct().getCategory().toString())) {
        if (newPlan.getPlansAllowedInBundle() != -1 && newPlan.getPlansAllowedInBundle() > 0 && addonUtils.countExistingAddOnsWithSamePlanName(dao.getSubscriptions(subscription.getBundleId(), null, catalog, internalCallContext), newPlan.getName()) >= newPlan.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, newPlan.getName());
        }
    }
    if (newPlan.getProduct().getCategory() != subscription.getCategory()) {
        throw new SubscriptionBaseApiException(ErrorCode.SUB_CHANGE_INVALID, subscription.getId());
    }
    final List<DefaultSubscriptionBase> addOnSubscriptionsToBeCancelled = new ArrayList<DefaultSubscriptionBase>();
    final List<SubscriptionBaseEvent> addOnCancelEvents = new ArrayList<SubscriptionBaseEvent>();
    final List<SubscriptionBaseEvent> changeEvents = getEventsOnChangePlan(subscription, newPlan, newPlan.getPriceList().getName(), effectiveDate, true, addOnSubscriptionsToBeCancelled, addOnCancelEvents, initialPhaseType, spec.getBillCycleDay(), catalog, internalCallContext);
    dao.changePlan(subscription, changeEvents, addOnSubscriptionsToBeCancelled, addOnCancelEvents, catalog, internalCallContext);
    subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId(), internalCallContext), catalog);
}
Also used : PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) ArrayList(java.util.ArrayList) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) Plan(org.killbill.billing.catalog.api.Plan) SubscriptionCatalog(org.killbill.billing.subscription.catalog.SubscriptionCatalog) StaticCatalog(org.killbill.billing.catalog.api.StaticCatalog) DefaultPlanPhasePriceOverridesWithCallContext(org.killbill.billing.subscription.api.svcs.DefaultPlanPhasePriceOverridesWithCallContext) PlanPhasePriceOverridesWithCallContext(org.killbill.billing.catalog.api.PlanPhasePriceOverridesWithCallContext) DefaultPlanPhasePriceOverridesWithCallContext(org.killbill.billing.subscription.api.svcs.DefaultPlanPhasePriceOverridesWithCallContext) PhaseType(org.killbill.billing.catalog.api.PhaseType) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent)

Aggregations

PhaseType (org.killbill.billing.catalog.api.PhaseType)13 PlanPhaseSpecifier (org.killbill.billing.catalog.api.PlanPhaseSpecifier)9 DateTime (org.joda.time.DateTime)6 Plan (org.killbill.billing.catalog.api.Plan)5 SubscriptionBaseEvent (org.killbill.billing.subscription.events.SubscriptionBaseEvent)4 PlanPhasePriceOverride (org.killbill.billing.catalog.api.PlanPhasePriceOverride)3 ArrayList (java.util.ArrayList)2 LinkedList (java.util.LinkedList)2 UUID (java.util.UUID)2 InternalCallContext (org.killbill.billing.callcontext.InternalCallContext)2 Catalog (org.killbill.billing.catalog.api.Catalog)2 Currency (org.killbill.billing.catalog.api.Currency)2 PlanAlignmentChange (org.killbill.billing.catalog.api.PlanAlignmentChange)2 PlanPhasePriceOverridesWithCallContext (org.killbill.billing.catalog.api.PlanPhasePriceOverridesWithCallContext)2 PlanSpecifier (org.killbill.billing.catalog.api.PlanSpecifier)2 ProductCategory (org.killbill.billing.catalog.api.ProductCategory)2 SubscriptionBaseTransitionType (org.killbill.billing.subscription.api.SubscriptionBaseTransitionType)2 DefaultPlanPhasePriceOverridesWithCallContext (org.killbill.billing.subscription.api.svcs.DefaultPlanPhasePriceOverridesWithCallContext)2 DefaultSubscriptionBase (org.killbill.billing.subscription.api.user.DefaultSubscriptionBase)2 BCDEvent (org.killbill.billing.subscription.events.bcd.BCDEvent)2