use of org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier in project killbill by killbill.
the class TestCatalogRetireElements method testRetirePlanWithUncancel.
@Test(groups = "slow")
public void testRetirePlanWithUncancel() throws Exception {
// Catalog v1 starts in 2011-01-01
// Catalog v2 starts in 2015-12-01
final LocalDate today = new LocalDate(2015, 10, 5);
// Set clock to the initial start date - we implicitly assume here that the account timezone is UTC
clock.setDay(today);
final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(1));
final String productName = "Pistol";
final BillingPeriod term = BillingPeriod.MONTHLY;
Entitlement bpEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey", productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
assertNotNull(bpEntitlement);
assertEquals(invoiceUserApi.getInvoicesByAccount(account.getId(), false, false, callContext).size(), 1);
assertEquals(bpEntitlement.getState(), EntitlementState.ACTIVE);
// Move out a month.
busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
assertListenerStatus();
// Cancel entitlement
bpEntitlement = bpEntitlement.cancelEntitlementWithDate(new LocalDate("2016-05-01"), true, ImmutableList.<PluginProperty>of(), callContext);
assertEquals(bpEntitlement.getState(), EntitlementState.ACTIVE);
assertListenerStatus();
// Move out a month.
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
assertListenerStatus();
// Catalog v2 should start now.
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, term, PriceListSet.DEFAULT_PRICELIST_NAME, null);
try {
entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "externalKey2", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
// force to fail is there is not an exception
fail();
} catch (final EntitlementApiException e) {
assertEquals(e.getCode(), ErrorCode.CAT_PLAN_NOT_FOUND.getCode());
}
// Uncancel entitlement
busHandler.pushExpectedEvents(NextEvent.UNCANCEL);
bpEntitlement.uncancelEntitlement(ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// Move out a month and verify 'Pistol' plan continue working as expected.
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
assertListenerStatus();
final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, false, callContext);
assertEquals(invoices.size(), 4);
for (final Invoice invoice : invoices) {
assertEquals(invoice.getInvoiceItems().get(0).getPlanName(), "pistol-monthly");
}
}
use of org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier in project killbill by killbill.
the class TestCatalogRetireElements method testRetirePriceList.
@Test(groups = "slow")
public void testRetirePriceList() throws Exception {
// Catalog v1 starts in 2011-01-01
// Catalog v2 starts in 2015-12-01
// Catalog v3 starts in 2016-01-01
final LocalDate today = new LocalDate(2015, 11, 1);
// Set clock to the initial start date - we implicitly assume here that the account timezone is UTC
clock.setDay(today);
final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(1));
// accountUserApi.createAccount(getAccountData(1), callContext);
final String productName = "Pistol";
final BillingPeriod term = BillingPeriod.MONTHLY;
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, term, "SpecialDiscount", null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
final UUID bpEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "externalKey", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement bpEntitlement = entitlementApi.getEntitlementForId(bpEntitlementId, callContext);
assertNotNull(bpEntitlement);
assertEquals(invoiceUserApi.getInvoicesByAccount(account.getId(), false, false, callContext).size(), 1);
// Move out a month.
busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
assertListenerStatus();
// Move out a month.
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
assertListenerStatus();
try {
entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "externalKey2", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
// force to fail is there is not an exception
fail();
} catch (final EntitlementApiException e) {
assertTrue(e.getLocalizedMessage().startsWith("Could not find any product named 'Pistol'"));
}
// Move out a month and verify 'Pistol' plan continue working as expected.
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
assertListenerStatus();
// Move out a month.
busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.NULL_INVOICE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
assertListenerStatus();
final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, false, callContext);
assertEquals(invoices.size(), 5);
assertTrue(invoices.get(0).getInvoiceItems().get(0).getPhaseName().equals("discount-pistol-monthly-trial"));
assertTrue(invoices.get(1).getInvoiceItems().get(0).getPhaseName().equals("discount-pistol-monthly-discount"));
assertTrue(invoices.get(2).getInvoiceItems().get(0).getPhaseName().equals("discount-pistol-monthly-discount"));
assertTrue(invoices.get(3).getInvoiceItems().get(0).getPhaseName().equals("discount-pistol-monthly-discount"));
assertTrue(invoices.get(4).getInvoiceItems().get(0).getPhaseName().equals("discount-pistol-monthly-evergreen"));
}
use of org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier in project killbill by killbill.
the class TestCatalogRetireElements method testRetirePlanWithUncancelAfterChange.
@Test(groups = "slow")
public void testRetirePlanWithUncancelAfterChange() throws Exception {
// Catalog v1 starts in 2011-01-01
// Catalog v3 starts in 2016-01-01
final LocalDate today = new LocalDate(2015, 7, 5);
// Set clock to the initial start date - we implicitly assume here that the account timezone is UTC
clock.setDay(today);
final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(null));
final String productName = "Pistol";
final BillingPeriod term = BillingPeriod.MONTHLY;
final PlanPhaseSpecifier spec1 = new PlanPhaseSpecifier(productName, term, "DEFAULT", null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
final UUID bpEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec1), "externalKey", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
Entitlement bpEntitlement = entitlementApi.getEntitlementForId(bpEntitlementId, callContext);
assertNotNull(bpEntitlement);
assertEquals(bpEntitlement.getLastActivePhase().getPhaseType(), PhaseType.TRIAL);
assertEquals(invoiceUserApi.getInvoicesByAccount(account.getId(), false, false, callContext).size(), 1);
// Move out after trial (2015-08-04)
busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addDays(30);
assertListenerStatus();
assertEquals(entitlementApi.getEntitlementForId(bpEntitlement.getId(), callContext).getLastActivePhase().getPhaseType(), PhaseType.EVERGREEN);
assertEquals(invoiceUserApi.getInvoicesByAccount(account.getId(), false, false, callContext).size(), 2);
// 2015-08-05
clock.addDays(1);
assertListenerStatus();
// Change to discount phase in SpecialDiscount pricelist (CBA generated, no payment)
// Note that we need to trigger a CHANGE outside a TRIAL phase to generate a CHANGE event (otherwise, a CREATE is generated)
final PlanPhaseSpecifier spec2 = new PlanPhaseSpecifier(productName, term, "SpecialDiscount", null);
busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE);
bpEntitlement = bpEntitlement.changePlanWithDate(new DefaultEntitlementSpecifier(spec2), clock.getUTCToday(), ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
assertEquals(entitlementApi.getEntitlementForId(bpEntitlement.getId(), callContext).getLastActivePhase().getPhaseType(), PhaseType.DISCOUNT);
assertEquals(invoiceUserApi.getInvoicesByAccount(account.getId(), false, false, callContext).size(), 3);
// Cancel entitlement
bpEntitlement = bpEntitlement.cancelEntitlementWithDate(new LocalDate("2016-05-01"), true, ImmutableList.<PluginProperty>of(), callContext);
assertEquals(bpEntitlement.getState(), EntitlementState.ACTIVE);
assertListenerStatus();
// Move out after discount phase (happens on 2015-11-04)
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
// 2015-09-05
clock.addMonths(1);
assertListenerStatus();
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
// 2015-10-05
clock.addMonths(1);
assertListenerStatus();
busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.NULL_INVOICE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
// 2015-11-05
clock.addMonths(1);
// This verifies the PlanAligner.getNextTimedPhase codepath with a CHANGE transition type
assertListenerStatus();
assertEquals(entitlementApi.getEntitlementForId(bpEntitlement.getId(), callContext).getLastActivePhase().getPhaseType(), PhaseType.EVERGREEN);
// Move out a month (2015-12-05)
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
assertListenerStatus();
// Uncancel entitlement
busHandler.pushExpectedEvents(NextEvent.UNCANCEL);
bpEntitlement.uncancelEntitlement(ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// Move out a month (2016-01-01)
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
assertListenerStatus();
try {
entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec2), "externalKey2", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
// force to fail is there is not an exception
fail();
} catch (final EntitlementApiException e) {
assertEquals(e.getCode(), ErrorCode.CAT_NO_SUCH_PRODUCT.getCode());
}
// Move out a month and verify 'Pistol' discounted plan continues working as expected.
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
assertListenerStatus();
final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, false, callContext);
assertEquals(invoices.size(), 9);
}
use of org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier in project killbill by killbill.
the class TestCatalogWithDryRun method testDryRunWithChangePlanOnNewCatalog.
@Test(groups = "slow")
public void testDryRunWithChangePlanOnNewCatalog() throws Exception {
// Start with an initialDate such that: catalog V1=2020-09-16T10:34:25 < initialDate < catalog V2=2020-10-18T11:19:01
final LocalDate initialDate = new LocalDate(2020, 10, 1);
clock.setDay(initialDate);
final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(null));
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("pistol-monthly", null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec, null, null, null), UUID.randomUUID().toString(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
final Entitlement createdEntitlement = entitlementApi.getEntitlementForId(createdEntitlementId, callContext);
assertListenerStatus();
final LocalDate futureDate = new LocalDate(2020, 10, 21);
final DryRunArguments dryRunSubscriptionActionArg = new TestDryRunArguments(DryRunType.SUBSCRIPTION_ACTION, "Pistol", ProductCategory.BASE, BillingPeriod.MONTHLY, "discount", null, SubscriptionEventType.CHANGE, createdEntitlement.getId(), createdEntitlement.getBundleId(), futureDate, BillingActionPolicy.IMMEDIATE);
final Invoice dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(createdEntitlement.getAccountId(), futureDate, dryRunSubscriptionActionArg, callContext);
final List<ExpectedInvoiceItemCheck> expectedInvoices = new ArrayList<ExpectedInvoiceItemCheck>();
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2020, 10, 21), null, InvoiceItemType.FIXED, new BigDecimal("80.00")));
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2020, 10, 21), new LocalDate(2020, 11, 1), InvoiceItemType.RECURRING, new BigDecimal("7.08")));
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2020, 10, 21), new LocalDate(2020, 11, 1), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-17.72")));
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
}
use of org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier in project killbill by killbill.
the class TestCatalogWithDryRun method testDryRunWithChangePlanWithOverridesOnSamePlan.
@Test(groups = "slow")
public void testDryRunWithChangePlanWithOverridesOnSamePlan() throws Exception {
final VersionedCatalog catalog = catalogUserApi.getCatalog("WeaponsHireSmall", callContext);
// Start with an initialDate such that: catalog V1=2020-09-16T10:34:25 < initialDate < catalog V2=2020-10-18T11:19:01
final LocalDate initialDate = new LocalDate(2020, 10, 1);
clock.setDay(initialDate);
final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(null));
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("pistol-monthly", null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec, null, null, null), UUID.randomUUID().toString(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
final Entitlement bpEntitlement = entitlementApi.getEntitlementForId(createdEntitlementId, callContext);
assertListenerStatus();
Invoice curInvoice = invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2020, 10, 1), null, InvoiceItemType.FIXED, new BigDecimal("100")), new ExpectedInvoiceItemCheck(new LocalDate(2020, 10, 1), new LocalDate(2020, 11, 1), InvoiceItemType.RECURRING, new BigDecimal("49.95")));
Assert.assertEquals(curInvoice.getInvoiceItems().get(0).getCatalogEffectiveDate().toDate().compareTo(catalog.getVersions().get(0).getEffectiveDate()), 0);
Assert.assertEquals(curInvoice.getInvoiceItems().get(1).getCatalogEffectiveDate().toDate().compareTo(catalog.getVersions().get(0).getEffectiveDate()), 0);
clock.setDay(new LocalDate(2020, 10, 19));
assertListenerStatus();
// Future change
final LocalDate changeDate = new LocalDate(2020, 10, 20);
final PlanPhaseSpecifier spec1 = new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, "discount", null);
bpEntitlement.changePlanWithDate(new DefaultEntitlementSpecifier(spec1), changeDate, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// Generate the invoice
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
invoiceUserApi.triggerInvoiceGeneration(bpEntitlement.getAccountId(), changeDate, callContext);
assertListenerStatus();
curInvoice = invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2020, 10, 1), null, InvoiceItemType.FIXED, new BigDecimal("100")), new ExpectedInvoiceItemCheck(new LocalDate(2020, 10, 1), new LocalDate(2020, 11, 1), InvoiceItemType.RECURRING, new BigDecimal("49.95")));
Assert.assertEquals(curInvoice.getInvoiceItems().get(0).getCatalogEffectiveDate().toDate().compareTo(catalog.getVersions().get(0).getEffectiveDate()), 0);
Assert.assertEquals(curInvoice.getInvoiceItems().get(1).getCatalogEffectiveDate().toDate().compareTo(catalog.getVersions().get(0).getEffectiveDate()), 0);
curInvoice = invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2020, 10, 20), null, InvoiceItemType.FIXED, new BigDecimal("80")), new ExpectedInvoiceItemCheck(new LocalDate(2020, 10, 20), new LocalDate(2020, 11, 1), InvoiceItemType.RECURRING, new BigDecimal("7.72")), new ExpectedInvoiceItemCheck(new LocalDate(2020, 10, 20), new LocalDate(2020, 11, 1), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-19.34")));
Assert.assertEquals(curInvoice.getInvoiceItems().get(0).getCatalogEffectiveDate().toDate().compareTo(catalog.getVersions().get(1).getEffectiveDate()), 0);
Assert.assertEquals(curInvoice.getInvoiceItems().get(1).getCatalogEffectiveDate().toDate().compareTo(catalog.getVersions().get(1).getEffectiveDate()), 0);
// Future dry-run change on the same plan with all prices overriden
final PlanPhasePriceOverride override = new DefaultPlanPhasePriceOverride("pistol-monthly-discount-evergreen", account.getCurrency(), new BigDecimal("70.00"), new BigDecimal("28.90"), ImmutableList.<UsagePriceOverride>of());
final List<PlanPhasePriceOverride> overrides = ImmutableList.<PlanPhasePriceOverride>of(override);
final DryRunArguments dryRunSubscriptionActionArg = new TestDryRunArguments(DryRunType.SUBSCRIPTION_ACTION, "Pistol", ProductCategory.BASE, BillingPeriod.MONTHLY, "discount", PhaseType.EVERGREEN, SubscriptionEventType.CHANGE, bpEntitlement.getId(), bpEntitlement.getBundleId(), null, BillingActionPolicy.END_OF_TERM, overrides);
final LocalDate targetDate = new LocalDate(2020, 11, 1);
final Invoice dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(bpEntitlement.getAccountId(), targetDate, dryRunSubscriptionActionArg, callContext);
final List<ExpectedInvoiceItemCheck> expectedInvoices = new ArrayList<ExpectedInvoiceItemCheck>();
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2020, 11, 1), null, InvoiceItemType.FIXED, new BigDecimal("70.00")));
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2020, 11, 1), new LocalDate(2020, 12, 1), InvoiceItemType.RECURRING, new BigDecimal("28.90")));
// Future dry-run change on the same plan with only the recuring price overriden
final PlanPhasePriceOverride override2 = new DefaultPlanPhasePriceOverride("pistol-monthly-discount-evergreen", account.getCurrency(), null, new BigDecimal("32.65"), ImmutableList.<UsagePriceOverride>of());
final List<PlanPhasePriceOverride> override2s = ImmutableList.<PlanPhasePriceOverride>of(override2);
final DryRunArguments dryRunSubscriptionActionArg2 = new TestDryRunArguments(DryRunType.SUBSCRIPTION_ACTION, "Pistol", ProductCategory.BASE, BillingPeriod.MONTHLY, "discount", PhaseType.EVERGREEN, SubscriptionEventType.CHANGE, bpEntitlement.getId(), bpEntitlement.getBundleId(), null, BillingActionPolicy.END_OF_TERM, override2s);
final Invoice dryRunInvoice2 = invoiceUserApi.triggerDryRunInvoiceGeneration(bpEntitlement.getAccountId(), targetDate, dryRunSubscriptionActionArg2, callContext);
final List<ExpectedInvoiceItemCheck> expectedInvoices2 = new ArrayList<ExpectedInvoiceItemCheck>();
expectedInvoices2.add(new ExpectedInvoiceItemCheck(new LocalDate(2020, 11, 1), null, InvoiceItemType.FIXED, new BigDecimal("80.00")));
expectedInvoices2.add(new ExpectedInvoiceItemCheck(new LocalDate(2020, 11, 1), new LocalDate(2020, 12, 1), InvoiceItemType.RECURRING, new BigDecimal("32.65")));
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice2, expectedInvoices2);
}
Aggregations