use of org.killbill.billing.entitlement.api.Entitlement in project killbill by killbill.
the class TestEntitlementUtils method testCancelAddonsWhenBaseEntitlementIsCancelled.
@Test(groups = "slow", description = "Verify add-ons are not active after base entitlement is cancelled")
public void testCancelAddonsWhenBaseEntitlementIsCancelled() throws Exception {
// Add a second ADD_ON
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.PHASE);
final PlanPhaseSpecifier addOn2Spec = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
final UUID addOn2EntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), new DefaultEntitlementSpecifier(addOn2Spec), initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement addOn2Entitlement = entitlementApi.getEntitlementForId(addOn2EntitlementId, callContext);
// Date prior to the base cancellation date to verify it is not impacted by the base cancellation (in contrary to the second add-on)
final LocalDate addOn1CancellationDate = new LocalDate(2013, 9, 9);
addOnEntitlement.cancelEntitlementWithDate(addOn1CancellationDate, true, ImmutableList.<PluginProperty>of(), callContext);
final LocalDate addOn2CancellationDate = new LocalDate(2013, 11, 11);
addOn2Entitlement.cancelEntitlementWithDate(addOn2CancellationDate, true, ImmutableList.<PluginProperty>of(), callContext);
// Before the base entitlement is cancelled, respect the specified cancellation date
Assert.assertEquals(entitlementApi.getEntitlementForId(addOn2Entitlement.getId(), callContext).getEffectiveEndDate(), addOn2CancellationDate);
final LocalDate baseCancellationDate = new LocalDate(2013, 10, 10);
baseEntitlement.cancelEntitlementWithDate(baseCancellationDate, true, ImmutableList.<PluginProperty>of(), callContext);
// After the base entitlement is cancelled, verify the date is overridden
Assert.assertEquals(entitlementApi.getEntitlementForId(addOn2Entitlement.getId(), callContext).getEffectiveEndDate(), baseCancellationDate);
// No further event yet
assertListenerStatus();
// Verify the cancellation dates
Assert.assertEquals(entitlementApi.getEntitlementForId(baseEntitlement.getId(), callContext).getEffectiveEndDate(), baseCancellationDate);
Assert.assertEquals(entitlementApi.getEntitlementForId(addOnEntitlement.getId(), callContext).getEffectiveEndDate(), addOn1CancellationDate);
Assert.assertEquals(entitlementApi.getEntitlementForId(addOn2Entitlement.getId(), callContext).getEffectiveEndDate(), baseCancellationDate);
// Move to addOn1CancellationDate
testListener.pushExpectedEvents(NextEvent.CANCEL, NextEvent.BLOCK);
clock.setDay(new LocalDate(2013, 9, 9));
assertListenerStatus();
testListener.pushExpectedEvents(NextEvent.CANCEL, NextEvent.CANCEL, NextEvent.BLOCK, NextEvent.BLOCK);
clock.setDay(new LocalDate(2013, 10, 10));
assertListenerStatus();
// Verify the cancellation dates
Assert.assertEquals(entitlementApi.getEntitlementForId(baseEntitlement.getId(), callContext).getEffectiveEndDate(), baseCancellationDate);
Assert.assertEquals(entitlementApi.getEntitlementForId(addOnEntitlement.getId(), callContext).getEffectiveEndDate(), addOn1CancellationDate);
Assert.assertEquals(entitlementApi.getEntitlementForId(addOn2Entitlement.getId(), callContext).getEffectiveEndDate(), baseCancellationDate);
}
use of org.killbill.billing.entitlement.api.Entitlement in project killbill by killbill.
the class TestMigrationSubscriptions method testSimpleMigrationBP.
//
// Scenario: On 2016-1-1, we decide to migrate a subscription with a cutOverDate of 2016-1-10 (10 days in the future) and a billing date of 2016-1-31
// (note that 2016-1-31 + 30 days trial = 2016-03-01, which aligns well with the BCD=1 we set on our test account)
//
//
@Test(groups = "slow")
public void testSimpleMigrationBP() throws Exception {
clock.setDay(new LocalDate(2016, 1, 1));
final AccountData accountData = getAccountData(1);
final Account account = createAccountWithNonOsgiPaymentMethod(accountData);
accountChecker.checkAccount(account.getId(), accountData, callContext);
final List<ExpectedInvoiceItemCheck> expectedInvoices = new ArrayList<ExpectedInvoiceItemCheck>();
// We set both entitlement and billing date with desired value
final LocalDate entitlementMigrationDate = new LocalDate(2016, 1, 10);
final LocalDate billingMigrationDate = new LocalDate(2016, 1, 31);
// Entitlement wil be created in PENDING state
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "bundleKey", entitlementMigrationDate, billingMigrationDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
Assert.assertEquals(entitlement.getState(), EntitlementState.PENDING);
// Move clock to entitlementMigrationDate (migration cutOverDate), and expect the associated event
busHandler.pushExpectedEvents(NextEvent.BLOCK);
clock.addDays(10);
assertListenerStatus();
final Entitlement activeEntitlement = entitlementApi.getEntitlementForId(entitlement.getId(), callContext);
Assert.assertEquals(activeEntitlement.getState(), EntitlementState.ACTIVE);
// Move clock to billingMigrationDate and expect the CREATE event along a $0 invoice for the trial
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.INVOICE);
clock.addDays(21);
assertListenerStatus();
expectedInvoices.add(new ExpectedInvoiceItemCheck(billingMigrationDate, null, InvoiceItemType.FIXED, new BigDecimal("0")));
invoiceChecker.checkInvoice(account.getId(), 1, callContext, expectedInvoices);
expectedInvoices.clear();
// Move clock next month for first RECURRING invoice
busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
assertListenerStatus();
final LocalDate startDate = billingMigrationDate.plusDays(30);
final LocalDate endDate = startDate.plusMonths(1);
expectedInvoices.add(new ExpectedInvoiceItemCheck(startDate, endDate, InvoiceItemType.RECURRING, new BigDecimal("249.95")));
invoiceChecker.checkInvoice(account.getId(), 2, callContext, expectedInvoices);
expectedInvoices.clear();
}
use of org.killbill.billing.entitlement.api.Entitlement in project killbill by killbill.
the class TestMigrationSubscriptions method testSimpleMigrationBundle.
//
// Scenario: On 2016-1-1, we decide to migrate a bundle (one BP and one AO). We migrate straight to EVERGREEN phase. The scenario is very similar to previous one
// but with an additional AO (by using the createBaseEntitlementWithAddOns api).
//
// Note that while convenient to migrate a bundle at once (BP + AOS), one could do several calls for each subscription. The advantage of the later approach is that
// the granularity in terms of alignments for when things start and which phase are skipped can be better controlled.
//
@Test(groups = "slow")
public void testSimpleMigrationBundle() throws Exception {
clock.setDay(new LocalDate(2016, 1, 1));
final AccountData accountData = getAccountData(1);
final Account account = createAccountWithNonOsgiPaymentMethod(accountData);
accountChecker.checkAccount(account.getId(), accountData, callContext);
// We set both entitlement and billing date with desired value
final LocalDate entitlementMigrationDate = new LocalDate(2015, 12, 20);
final LocalDate billingMigrationDate = new LocalDate(2016, 2, 1);
final PlanPhaseSpecifier baseSpec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
final PlanPhaseSpecifier addOnSpec1 = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
final String externalKey = "baseExternalKey";
EntitlementSpecifier baseEntitlementSpecifier = new DefaultEntitlementSpecifier(baseSpec);
EntitlementSpecifier addOnEntitlementSpecifier1 = new DefaultEntitlementSpecifier(addOnSpec1);
final List<EntitlementSpecifier> specifierList = new ArrayList<EntitlementSpecifier>();
specifierList.add(baseEntitlementSpecifier);
specifierList.add(addOnEntitlementSpecifier1);
busHandler.pushExpectedEvents(NextEvent.BLOCK, NextEvent.BLOCK);
BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = buildBaseEntitlementWithAddOnsSpecifier(entitlementMigrationDate, billingMigrationDate, externalKey, specifierList);
List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
final List<UUID> baseEntitlements = entitlementApi.createBaseEntitlementsWithAddOns(account.getId(), baseEntitlementWithAddOnsSpecifierList, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(baseEntitlements.get(0), callContext);
Assert.assertEquals(entitlement.getState(), EntitlementState.ACTIVE);
// Billing starts straight on EVERGREEN
clock.addMonths(1);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.CREATE, NextEvent.INVOICE, NextEvent.NULL_INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
assertListenerStatus();
}
use of org.killbill.billing.entitlement.api.Entitlement in project killbill by killbill.
the class TestWithInvoiceOptimization method testRecurringInArrear2.
@Test(groups = "slow")
public void testRecurringInArrear2() throws Exception {
invoiceConfig.setMaxInvoiceLimit(new Period("P1m"));
clock.setTime(new DateTime("2020-01-01T3:56:02"));
final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(1));
assertNotNull(account);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.NULL_INVOICE);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("blowdart-in-arrear-monthly-notrial");
final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "Something", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// 2020-02-01
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
assertListenerStatus();
invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2020, 1, 1), new LocalDate(2020, 2, 1), InvoiceItemType.RECURRING, new BigDecimal("100.00")));
// Cancel in the past (previous period)
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
busHandler.pushExpectedEvents(NextEvent.CANCEL, NextEvent.BLOCK, NextEvent.INVOICE);
entitlement.cancelEntitlementWithDate(new LocalDate(2020, 1, 28), true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// Verify the system does not generate anything (subscription was canceled)
// 2020-03-01
busHandler.pushExpectedEvents(NextEvent.NULL_INVOICE);
clock.addMonths(1);
assertListenerStatus();
checkNothingToInvoice(account.getId(), new LocalDate(2020, 3, 1), false);
}
use of org.killbill.billing.entitlement.api.Entitlement in project killbill by killbill.
the class TestWithInvoiceOptimization method testRecurringInAdvance2.
// Used to demonstrate what happens when maxInvoiceLimit = 0 and we do billing IN_ADVANCE
@Test(groups = "slow")
public void testRecurringInAdvance2() throws Exception {
// Never fetch any existing invoices from disk during invoicing process
invoiceConfig.setMaxInvoiceLimit(new Period("P0m"));
clock.setTime(new DateTime("2020-01-01T3:56:02"));
final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(1));
assertNotNull(account);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Blowdart", BillingPeriod.MONTHLY, "notrial", null);
final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "Something", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2020, 1, 1), new LocalDate(2020, 2, 1), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
final PlanPhaseSpecifier spec2 = new PlanPhaseSpecifier("pistol-monthly-notrial");
// 2020-01-16
clock.addDays(15);
// Do a change one day in the past => Nothing will be generated
// - System does not fetch any existing invoices as cutoffDt= 2020-01-16 and there are no invoices whose targetDt >= cutoffDt
// - Proposed items correctly generate the 2 expected items but both are filtered because their startDt < cutoffDt
busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.NULL_INVOICE);
entitlement.changePlanWithDate(new DefaultEntitlementSpecifier(spec2, null, null, null), clock.getUTCToday().minusDays(1), ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// Do a change today => Only new item 2020-01-16 - 2020-02-01 gets generated
// - System does not fetch any existing invoices as cutoffDt= 2020-01-16 and there are no invoices whose targetDt >= cutoffDt
// - Proposed items correctly generate the 2 expected items but the first one is filtered because its start date 2020-01-15 < cutoffDt
busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
entitlement.changePlanWithDate(new DefaultEntitlementSpecifier(spec2, null, null, null), clock.getUTCToday(), ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// Double invoicing due to bad config! (no REPAIR)
invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2020, 1, 16), new LocalDate(2020, 2, 1), InvoiceItemType.RECURRING, new BigDecimal("10.30")));
}
Aggregations