use of org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier in project killbill by killbill.
the class TestUserApiChangePlan method testChangePlanOnPendingSubscription.
@Test(groups = "slow")
public void testChangePlanOnPendingSubscription() throws SubscriptionBaseApiException {
final String baseProduct = "Shotgun";
final BillingPeriod baseTerm = BillingPeriod.MONTHLY;
final String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
final LocalDate startDate = clock.getUTCToday().plusDays(5);
final DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, baseProduct, baseTerm, basePriceList, startDate);
assertEquals(subscription.getState(), Entitlement.EntitlementState.PENDING);
assertEquals(subscription.getStartDate().compareTo(startDate.toDateTime(accountData.getReferenceTime())), 0);
final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier("Pistol", baseTerm, basePriceList);
final EntitlementSpecifier spec = new DefaultEntitlementSpecifier(planPhaseSpecifier, null, null, null);
// First try with default api (no date -> IMM) => Call should fail because subscription is PENDING
final DryRunArguments dryRunArguments1 = testUtil.createDryRunArguments(subscription.getId(), subscription.getBundleId(), spec, null, SubscriptionEventType.CHANGE, null);
final List<SubscriptionBase> result1 = subscriptionInternalApi.getSubscriptionsForBundle(subscription.getBundleId(), dryRunArguments1, internalCallContext);
// Check we are seeing the right PENDING transition (pistol-monthly), not the START but the CHANGE on the same date
assertEquals(((DefaultSubscriptionBase) result1.get(0)).getCurrentOrPendingPlan().getName(), "pistol-monthly");
assertEquals(((DefaultSubscriptionBase) result1.get(0)).getPendingTransition().getTransitionType(), SubscriptionBaseTransitionType.CREATE);
// Second try with date prior to startDate => Call should fail because subscription is PENDING
try {
final DryRunArguments dryRunArguments2 = testUtil.createDryRunArguments(subscription.getId(), subscription.getBundleId(), spec, startDate.minusDays(1), SubscriptionEventType.CHANGE, null);
subscriptionInternalApi.getSubscriptionsForBundle(subscription.getBundleId(), dryRunArguments2, internalCallContext);
fail("Change plan should have failed : subscription PENDING");
} catch (final SubscriptionBaseApiException e) {
assertEquals(e.getCode(), ErrorCode.SUB_CHANGE_NON_ACTIVE.getCode());
}
try {
subscription.changePlanWithDate(spec, subscription.getStartDate().minusDays(1), callContext);
fail("Change plan should have failed : subscription PENDING");
} catch (final SubscriptionBaseApiException e) {
assertEquals(e.getCode(), ErrorCode.SUB_INVALID_REQUESTED_DATE.getCode());
}
// Third try with date equals to startDate Call should succeed, but no event because action in future
final DryRunArguments dryRunArguments3 = testUtil.createDryRunArguments(subscription.getId(), subscription.getBundleId(), spec, startDate, SubscriptionEventType.CHANGE, null);
final List<SubscriptionBase> result2 = subscriptionInternalApi.getSubscriptionsForBundle(subscription.getBundleId(), dryRunArguments3, internalCallContext);
// Check we are seeing the right PENDING transition (pistol-monthly), not the START but the CHANGE on the same date
assertEquals(((DefaultSubscriptionBase) result2.get(0)).getCurrentOrPendingPlan().getName(), "pistol-monthly");
subscription.changePlanWithDate(spec, subscription.getStartDate(), callContext);
assertListenerStatus();
// Move clock to startDate
testListener.pushExpectedEvents(NextEvent.CREATE);
clock.addDays(5);
assertListenerStatus();
final DefaultSubscriptionBase subscription2 = (DefaultSubscriptionBase) subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext);
assertEquals(subscription2.getStartDate().compareTo(subscription.getStartDate()), 0);
assertEquals(subscription2.getState(), Entitlement.EntitlementState.ACTIVE);
assertEquals(subscription2.getCurrentPlan().getProduct().getName(), "Pistol");
// Same original # active events
assertEquals(subscription2.getEvents().size(), subscription.getEvents().size());
}
use of org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier in project killbill by killbill.
the class TestUserApiChangePlan method testChangePlanBundleAlignEOTWithChargeThroughDate.
private void testChangePlanBundleAlignEOTWithChargeThroughDate(final String fromProd, final BillingPeriod fromTerm, final String fromPlanSet, final String toProd, final BillingPeriod toTerm, final String toPlanSet) throws SubscriptionBillingApiException, SubscriptionBaseApiException {
// CREATE
DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, fromProd, fromTerm, fromPlanSet);
final PlanPhase trialPhase = subscription.getCurrentPhase();
final DateTime expectedPhaseTrialChange = TestSubscriptionHelper.addDuration(subscription.getStartDate(), trialPhase.getDuration());
assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
// MOVE TO NEXT PHASE
testListener.pushExpectedEvent(NextEvent.PHASE);
Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
clock.addDeltaFromReality(it.toDurationMillis());
assertListenerStatus();
PlanPhase currentPhase = subscription.getCurrentPhase();
assertEquals(currentPhase.getPhaseType(), PhaseType.DISCOUNT);
// SET CTD
final Duration ctd = testUtil.getDurationMonth(1);
final DateTime newChargedThroughDate = TestSubscriptionHelper.addDuration(expectedPhaseTrialChange, ctd);
setChargedThroughDate(subscription.getId(), newChargedThroughDate, internalCallContext);
// RE READ SUBSCRIPTION + CHANGE PLAN
subscription = (DefaultSubscriptionBase) subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext);
final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier(toProd, toTerm, toPlanSet);
subscription.changePlan(new DefaultEntitlementSpecifier(planPhaseSpecifier), callContext);
assertListenerStatus();
// CHECK CHANGE PLAN
currentPhase = subscription.getCurrentPhase();
checkChangePlan(subscription, fromProd, ProductCategory.BASE, fromTerm, PhaseType.DISCOUNT);
// NEXT PHASE
final DateTime nextExpectedPhaseChange = TestSubscriptionHelper.addDuration(expectedPhaseTrialChange, currentPhase.getDuration());
testUtil.checkNextPhaseChange(subscription, 2, nextExpectedPhaseChange);
// ALSO VERIFY PENDING CHANGE EVENT
final List<SubscriptionBaseEvent> events = dao.getPendingEventsForSubscription(subscription.getId(), internalCallContext);
assertTrue(events.get(0) instanceof ApiEvent);
// MOVE TO EOT
testListener.pushExpectedEvent(NextEvent.CHANGE);
it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(1));
clock.addDeltaFromReality(it.toDurationMillis());
assertListenerStatus();
subscription = (DefaultSubscriptionBase) subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext);
currentPhase = subscription.getCurrentPhase();
checkChangePlan(subscription, toProd, ProductCategory.BASE, toTerm, PhaseType.DISCOUNT);
assertListenerStatus();
}
use of org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier in project killbill by killbill.
the class TestUserApiChangePlan method testChangePlanOnCreate.
@Test(groups = "slow")
public void testChangePlanOnCreate() throws SubscriptionBaseApiException {
final DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, "Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
// CHANGE PLAN IMMEDIATELY: the CHANGE event will be transformed into a CREATE
testListener.pushExpectedEvent(NextEvent.CREATE);
final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
subscription.changePlanWithDate(new DefaultEntitlementSpecifier(planPhaseSpecifier), subscription.getStartDate(), callContext);
assertListenerStatus();
checkChangePlan(subscription, "Pistol", ProductCategory.BASE, BillingPeriod.MONTHLY, PhaseType.TRIAL);
final SubscriptionBase refreshedSubscription = subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext);
assertEquals(refreshedSubscription.getAllTransitions().size(), 2);
assertEquals(refreshedSubscription.getAllTransitions().get(0).getTransitionType(), SubscriptionBaseTransitionType.CREATE);
assertEquals(refreshedSubscription.getAllTransitions().get(1).getTransitionType(), SubscriptionBaseTransitionType.PHASE);
}
use of org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier in project killbill by killbill.
the class TestUserApiChangePlan method testChangePlanWithBCD.
@Test(groups = "slow")
public void testChangePlanWithBCD() throws SubscriptionBillingApiException, SubscriptionBaseApiException {
final DateTime init = clock.getUTCNow();
final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(bundle.getAccountId(), ObjectType.ACCOUNT, this.internalCallContext.getUpdatedBy(), this.internalCallContext.getCallOrigin(), this.internalCallContext.getContextUserType(), this.internalCallContext.getUserToken(), this.internalCallContext.getTenantRecordId());
DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, "Assault-Rifle", BillingPeriod.MONTHLY, "gunclubDiscount");
final PlanPhase trialPhase = subscription.getCurrentPhase();
assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
// MOVE TO NEXT PHASE
testListener.pushExpectedEvent(NextEvent.PHASE);
final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
clock.addDeltaFromReality(it.toDurationMillis());
assertListenerStatus();
// SET CTD
final List<Duration> durationList = new ArrayList<Duration>();
durationList.add(trialPhase.getDuration());
// durationList.add(subscription.getCurrentPhase().getDuration());
final DateTime startDiscountPhase = TestSubscriptionHelper.addDuration(subscription.getStartDate(), durationList);
final Duration ctd = testUtil.getDurationMonth(1);
final DateTime newChargedThroughDate = TestSubscriptionHelper.addDuration(startDiscountPhase, ctd);
setChargedThroughDate(subscription.getId(), newChargedThroughDate, internalCallContext);
subscription = (DefaultSubscriptionBase) subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext);
final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, "gunclubDiscount");
testListener.pushExpectedEvents(NextEvent.CHANGE, NextEvent.BCD_CHANGE);
subscription.changePlanWithDate(new DefaultEntitlementSpecifier(planPhaseSpecifier, 18, null, null), clock.getUTCNow(), callContext);
assertListenerStatus();
subscription = (DefaultSubscriptionBase) subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext);
assertNotNull(subscription.getBillCycleDayLocal());
assertEquals(subscription.getBillCycleDayLocal().intValue(), 18);
}
use of org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier in project killbill by killbill.
the class TestUserApiChangePlan method tChangePlanBundleAlignEOTWithNoChargeThroughDate.
private void tChangePlanBundleAlignEOTWithNoChargeThroughDate(final String fromProd, final BillingPeriod fromTerm, final String fromPlanSet, final String toProd, final BillingPeriod toTerm, final String toPlanSet) {
try {
// CREATE
final DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, fromProd, fromTerm, fromPlanSet);
// MOVE TO NEXT PHASE
PlanPhase currentPhase = subscription.getCurrentPhase();
testListener.pushExpectedEvent(NextEvent.PHASE);
final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
clock.addDeltaFromReality(it.toDurationMillis());
final DateTime futureNow = clock.getUTCNow();
final DateTime nextExpectedPhaseChange = TestSubscriptionHelper.addDuration(subscription.getStartDate(), currentPhase.getDuration());
assertTrue(futureNow.isAfter(nextExpectedPhaseChange));
assertListenerStatus();
// CHANGE PLAN
testListener.pushExpectedEvent(NextEvent.CHANGE);
final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier(toProd, toTerm, toPlanSet);
subscription.changePlan(new DefaultEntitlementSpecifier(planPhaseSpecifier), callContext);
assertListenerStatus();
// CHECK CHANGE PLAN
currentPhase = subscription.getCurrentPhase();
checkChangePlan(subscription, toProd, ProductCategory.BASE, toTerm, PhaseType.EVERGREEN);
assertListenerStatus();
} catch (SubscriptionBaseApiException e) {
Assert.fail(e.getMessage());
}
}
Aggregations