Search in sources :

Example 66 with PlanPhase

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

the class TestUserApiChangePlan method testCorrectPhaseAlignmentOnChange.

@Test(groups = "slow")
public void testCorrectPhaseAlignmentOnChange() throws SubscriptionBaseApiException {
    DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, "Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
    PlanPhase trialPhase = subscription.getCurrentPhase();
    assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
    // MOVE 2 DAYS AHEAD
    Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(2));
    clock.addDeltaFromReality(it.toDurationMillis());
    // CHANGE IMMEDIATE TO A 3 PHASES PLAN
    testListener.pushExpectedEvent(NextEvent.CHANGE);
    subscription.changePlan(new PlanSpecifier("Assault-Rifle", BillingPeriod.ANNUAL, "gunclubDiscount"), null, callContext);
    assertListenerStatus();
    // CHECK EVERYTHING LOOKS CORRECT
    final Plan currentPlan = subscription.getCurrentPlan();
    assertNotNull(currentPlan);
    assertEquals(currentPlan.getProduct().getName(), "Assault-Rifle");
    assertEquals(currentPlan.getProduct().getCategory(), ProductCategory.BASE);
    assertEquals(currentPlan.getRecurringBillingPeriod(), BillingPeriod.ANNUAL);
    trialPhase = subscription.getCurrentPhase();
    assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
    // MOVE AFTER TRIAL PERIOD -> DISCOUNT
    testListener.pushExpectedEvent(NextEvent.PHASE);
    it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(30));
    clock.addDeltaFromReality(it.toDurationMillis());
    assertListenerStatus();
    trialPhase = subscription.getCurrentPhase();
    assertEquals(trialPhase.getPhaseType(), PhaseType.DISCOUNT);
    subscription = (DefaultSubscriptionBase) subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext);
    final DateTime expectedNextPhaseDate = subscription.getStartDate().plusDays(30).plusMonths(6);
    final SubscriptionBaseTransition nextPhase = subscription.getPendingTransition();
    final DateTime nextPhaseEffectiveDate = nextPhase.getEffectiveTransitionTime();
    assertEquals(nextPhaseEffectiveDate, expectedNextPhaseDate);
    assertListenerStatus();
}
Also used : PlanPhase(org.killbill.billing.catalog.api.PlanPhase) Plan(org.killbill.billing.catalog.api.Plan) DateTime(org.joda.time.DateTime) Interval(org.joda.time.Interval) PlanSpecifier(org.killbill.billing.catalog.api.PlanSpecifier) Test(org.testng.annotations.Test)

Example 67 with PlanPhase

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

the class TestUserApiChangePlan method checkChangePlan.

private void checkChangePlan(final DefaultSubscriptionBase subscription, final String expProduct, final ProductCategory expCategory, final BillingPeriod expBillingPeriod, final PhaseType expPhase) {
    final Plan currentPlan = subscription.getCurrentPlan();
    assertNotNull(currentPlan);
    assertEquals(currentPlan.getProduct().getName(), expProduct);
    assertEquals(currentPlan.getProduct().getCategory(), expCategory);
    assertEquals(currentPlan.getRecurringBillingPeriod(), expBillingPeriod);
    final PlanPhase currentPhase = subscription.getCurrentPhase();
    assertNotNull(currentPhase);
    assertEquals(currentPhase.getPhaseType(), expPhase);
}
Also used : PlanPhase(org.killbill.billing.catalog.api.PlanPhase) Plan(org.killbill.billing.catalog.api.Plan)

Example 68 with PlanPhase

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

the class TestUserApiError method testChangeSubscriptionFutureCancelled.

@Test(groups = "fast")
public void testChangeSubscriptionFutureCancelled() throws SubscriptionBaseApiException {
    SubscriptionBase subscription = testUtil.createSubscription(bundle, "Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
    final PlanPhase trialPhase = subscription.getCurrentPhase();
    // MOVE TO NEXT PHASE
    final PlanPhase currentPhase = subscription.getCurrentPhase();
    testListener.pushExpectedEvent(NextEvent.PHASE);
    final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
    clock.addDeltaFromReality(it.toDurationMillis());
    assertListenerStatus();
    // SET CTD TO CANCEL IN FUTURE
    final DateTime expectedPhaseTrialChange = TestSubscriptionHelper.addDuration(subscription.getStartDate(), trialPhase.getDuration());
    final Duration ctd = testUtil.getDurationMonth(1);
    final DateTime newChargedThroughDate = TestSubscriptionHelper.addDuration(expectedPhaseTrialChange, ctd);
    subscriptionInternalApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate, internalCallContext);
    subscription = subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext);
    subscription.cancelWithPolicy(BillingActionPolicy.END_OF_TERM, null, -1, callContext);
    try {
        subscription.changePlanWithDate(new PlanSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), null, clock.getUTCNow(), callContext);
    } catch (final SubscriptionBaseApiException e) {
        assertEquals(e.getCode(), ErrorCode.SUB_CHANGE_FUTURE_CANCELLED.getCode());
    }
    assertListenerStatus();
}
Also used : SubscriptionBase(org.killbill.billing.subscription.api.SubscriptionBase) PlanPhase(org.killbill.billing.catalog.api.PlanPhase) Duration(org.killbill.billing.catalog.api.Duration) DateTime(org.joda.time.DateTime) Interval(org.joda.time.Interval) PlanSpecifier(org.killbill.billing.catalog.api.PlanSpecifier) Test(org.testng.annotations.Test)

Example 69 with PlanPhase

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

the class BlockingStateOrdering method toSubscriptionEvent.

private SubscriptionEvent toSubscriptionEvent(@Nullable final SubscriptionEvent prev, @Nullable final SubscriptionEvent next, final UUID entitlementId, final BlockingState in, final SubscriptionEventType eventType, final InternalTenantContext internalTenantContext) {
    final Product prevProduct;
    final Plan prevPlan;
    final PlanPhase prevPlanPhase;
    final PriceList prevPriceList;
    final BillingPeriod prevBillingPeriod;
    // Enforce prev = null for start events
    if (prev == null || SubscriptionEventType.START_ENTITLEMENT.equals(eventType) || SubscriptionEventType.START_BILLING.equals(eventType)) {
        prevProduct = null;
        prevPlan = null;
        prevPlanPhase = null;
        prevPriceList = null;
        prevBillingPeriod = null;
    } else {
        // We look for the next for the 'prev' meaning we we are headed to, but if this is null -- for example on cancellation we get the prev which gives the correct state.
        prevProduct = (prev.getNextProduct() != null ? prev.getNextProduct() : prev.getPrevProduct());
        prevPlan = (prev.getNextPlan() != null ? prev.getNextPlan() : prev.getPrevPlan());
        prevPlanPhase = (prev.getNextPhase() != null ? prev.getNextPhase() : prev.getPrevPhase());
        prevPriceList = (prev.getNextPriceList() != null ? prev.getNextPriceList() : prev.getPrevPriceList());
        prevBillingPeriod = (prev.getNextBillingPeriod() != null ? prev.getNextBillingPeriod() : prev.getPrevBillingPeriod());
    }
    final Product nextProduct;
    final Plan nextPlan;
    final PlanPhase nextPlanPhase;
    final PriceList nextPriceList;
    final BillingPeriod nextBillingPeriod;
    if (SubscriptionEventType.PAUSE_ENTITLEMENT.equals(eventType) || SubscriptionEventType.PAUSE_BILLING.equals(eventType) || SubscriptionEventType.RESUME_ENTITLEMENT.equals(eventType) || SubscriptionEventType.RESUME_BILLING.equals(eventType) || (SubscriptionEventType.SERVICE_STATE_CHANGE.equals(eventType) && (prev == null || (!SubscriptionEventType.STOP_ENTITLEMENT.equals(prev.getSubscriptionEventType()) && !SubscriptionEventType.STOP_BILLING.equals(prev.getSubscriptionEventType()))))) {
        // Enforce next = prev for pause/resume events as well as service changes
        nextProduct = prevProduct;
        nextPlan = prevPlan;
        nextPlanPhase = prevPlanPhase;
        nextPriceList = prevPriceList;
        nextBillingPeriod = prevBillingPeriod;
    } else if (next == null) {
        // Enforce next = null for stop events
        if (prev == null || SubscriptionEventType.STOP_ENTITLEMENT.equals(eventType) || SubscriptionEventType.STOP_BILLING.equals(eventType)) {
            nextProduct = null;
            nextPlan = null;
            nextPlanPhase = null;
            nextPriceList = null;
            nextBillingPeriod = null;
        } else {
            nextProduct = prev.getNextProduct();
            nextPlan = prev.getNextPlan();
            nextPlanPhase = prev.getNextPhase();
            nextPriceList = prev.getNextPriceList();
            nextBillingPeriod = prev.getNextBillingPeriod();
        }
    } else if (prev != null && (SubscriptionEventType.START_ENTITLEMENT.equals(eventType) || SubscriptionEventType.START_BILLING.equals(eventType))) {
        // For start events, next is actually the prev (e.g. the trial, not the phase)
        nextProduct = prev.getNextProduct();
        nextPlan = prev.getNextPlan();
        nextPlanPhase = prev.getNextPhase();
        nextPriceList = prev.getNextPriceList();
        nextBillingPeriod = prev.getNextBillingPeriod();
    } else {
        nextProduct = next.getNextProduct();
        nextPlan = next.getNextPlan();
        nextPlanPhase = next.getNextPhase();
        nextPriceList = next.getNextPriceList();
        nextBillingPeriod = next.getNextBillingPeriod();
    }
    // See https://github.com/killbill/killbill/issues/135
    final String serviceName = getRealServiceNameForEntitlementOrExternalServiceName(in.getService(), eventType);
    return new DefaultSubscriptionEvent(in.getId(), entitlementId, in.getEffectiveDate(), eventType, in.isBlockEntitlement(), in.isBlockBilling(), serviceName, in.getStateName(), prevProduct, prevPlan, prevPlanPhase, prevPriceList, prevBillingPeriod, nextProduct, nextPlan, nextPlanPhase, nextPriceList, nextBillingPeriod, in.getCreatedDate(), internalTenantContext);
}
Also used : BillingPeriod(org.killbill.billing.catalog.api.BillingPeriod) Product(org.killbill.billing.catalog.api.Product) PlanPhase(org.killbill.billing.catalog.api.PlanPhase) Plan(org.killbill.billing.catalog.api.Plan) PriceList(org.killbill.billing.catalog.api.PriceList)

Example 70 with PlanPhase

use of org.killbill.billing.catalog.api.PlanPhase 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);
}
Also used : PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) BillingPeriod(org.killbill.billing.catalog.api.BillingPeriod) ProductCategory(org.killbill.billing.catalog.api.ProductCategory) PhaseType(org.killbill.billing.catalog.api.PhaseType) Product(org.killbill.billing.catalog.api.Product) PlanPhase(org.killbill.billing.catalog.api.PlanPhase) SubscriptionBaseTransition(org.killbill.billing.subscription.api.user.SubscriptionBaseTransition)

Aggregations

PlanPhase (org.killbill.billing.catalog.api.PlanPhase)98 Plan (org.killbill.billing.catalog.api.Plan)77 Test (org.testng.annotations.Test)71 MockPlan (org.killbill.billing.catalog.MockPlan)50 MockPlanPhase (org.killbill.billing.catalog.MockPlanPhase)49 LocalDate (org.joda.time.LocalDate)47 DateTime (org.joda.time.DateTime)43 BillingEventSet (org.killbill.billing.junction.BillingEventSet)43 BigDecimal (java.math.BigDecimal)42 BillingEvent (org.killbill.billing.junction.BillingEvent)41 MockBillingEventSet (org.killbill.billing.invoice.MockBillingEventSet)40 Invoice (org.killbill.billing.invoice.api.Invoice)39 DefaultInvoice (org.killbill.billing.invoice.model.DefaultInvoice)36 UUID (java.util.UUID)34 DefaultPrice (org.killbill.billing.catalog.DefaultPrice)22 MockInternationalPrice (org.killbill.billing.catalog.MockInternationalPrice)22 RecurringInvoiceItem (org.killbill.billing.invoice.model.RecurringInvoiceItem)22 SubscriptionBase (org.killbill.billing.subscription.api.SubscriptionBase)22 InvoiceItem (org.killbill.billing.invoice.api.InvoiceItem)21 FixedPriceInvoiceItem (org.killbill.billing.invoice.model.FixedPriceInvoiceItem)21