use of org.killbill.billing.entitlement.api.DefaultEntitlement in project killbill by killbill.
the class TestWithBCDUpdate method testBCDChangeAfterTrialFollowOtherBCDChange.
@Test(groups = "slow")
public void testBCDChangeAfterTrialFollowOtherBCDChange() throws Exception {
final DateTime initialDate = new DateTime(2016, 4, 1, 0, 13, 42, 0, testTimeZone);
clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(0));
assertNotNull(account);
// BP creation : Will set Account BCD to the first (2016-4-1 + 30 days = 2016-5-1)
final String productName = "Shotgun";
final BillingPeriod term = BillingPeriod.MONTHLY;
final DefaultEntitlement baseEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "bundleKey", productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
// 2016-5-1 : BP out of TRIAL
busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addDays(30);
assertListenerStatus();
// Set next BCD to be the 15
subscriptionBaseInternalApi.updateBCD(baseEntitlement.getId(), 15, null, internalCallContext);
Thread.sleep(1000);
assertListenerStatus();
// 2016-5-15 : Catch BCD_CHANGE event and repair invoice accordingly
busHandler.pushExpectedEvents(NextEvent.BCD_CHANGE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addDays(14);
assertListenerStatus();
final List<ExpectedInvoiceItemCheck> expectedInvoices = new ArrayList<ExpectedInvoiceItemCheck>();
List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, callContext);
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2016, 5, 15), new LocalDate(2016, 6, 15), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2016, 5, 15), new LocalDate(2016, 6, 1), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-137.07")));
invoiceChecker.checkInvoice(invoices.get(2).getId(), callContext, expectedInvoices);
expectedInvoices.clear();
// 2016-6-01 : Original notification for 2016-6-01 (prior BCD change)
busHandler.pushExpectedEvents(NextEvent.NULL_INVOICE);
clock.addDays(17);
assertListenerStatus();
// 2016-6-15
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addDays(14);
assertListenerStatus();
invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, callContext);
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2016, 6, 15), new LocalDate(2016, 7, 15), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
invoiceChecker.checkInvoice(invoices.get(3).getId(), callContext, expectedInvoices);
expectedInvoices.clear();
// Set next BCD to be the 10
subscriptionBaseInternalApi.updateBCD(baseEntitlement.getId(), 10, null, internalCallContext);
Thread.sleep(1000);
assertListenerStatus();
// 2016-7-10
busHandler.pushExpectedEvents(NextEvent.BCD_CHANGE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addDays(25);
assertListenerStatus();
invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, callContext);
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2016, 7, 10), new LocalDate(2016, 8, 10), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2016, 7, 10), new LocalDate(2016, 7, 15), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-41.66")));
invoiceChecker.checkInvoice(invoices.get(4).getId(), callContext, expectedInvoices);
expectedInvoices.clear();
clock.addDays(3);
busHandler.pushExpectedEvents(NextEvent.CANCEL, NextEvent.BLOCK, NextEvent.INVOICE);
final Entitlement cancelledEntitlement = baseEntitlement.cancelEntitlementWithPolicyOverrideBillingPolicy(EntitlementActionPolicy.IMMEDIATE, BillingActionPolicy.START_OF_TERM, null, callContext);
assertListenerStatus();
final Subscription subscription = subscriptionApi.getSubscriptionForEntitlementId(cancelledEntitlement.getId(), callContext);
assertEquals(subscription.getEffectiveEndDate().compareTo(new LocalDate(2016, 7, 13)), 0);
assertEquals(subscription.getBillingEndDate().compareTo(new LocalDate(2016, 7, 10)), 0);
}
use of org.killbill.billing.entitlement.api.DefaultEntitlement in project killbill by killbill.
the class TestOverdueIntegration method testShouldBeInOverdueAfterRefundWithoutAdjustment.
@Test(groups = "slow", description = "Test overdue after refund with no adjustment")
public void testShouldBeInOverdueAfterRefundWithoutAdjustment() throws Exception {
// 2012-05-01T00:03:42.000Z
clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0));
setupAccount();
// Create subscription and don't fail payments
final DefaultEntitlement baseEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey", productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
bundle = subscriptionApi.getSubscriptionBundle(baseEntitlement.getBundleId(), callContext);
invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
invoiceChecker.checkChargedThroughDate(baseEntitlement.getId(), new LocalDate(2012, 5, 1), callContext);
// 2012-05-31 => DAY 30 have to get out of trial before first payment
addDaysAndCheckForCompletion(30, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
invoiceChecker.checkChargedThroughDate(baseEntitlement.getId(), new LocalDate(2012, 6, 30), callContext);
// Should still be in clear state
checkODState(OverdueWrapper.CLEAR_STATE_NAME);
// 2012-06-15 => DAY 45 - 15 days after invoice
addDaysAndCheckForCompletion(15);
// Should still be in clear state
checkODState(OverdueWrapper.CLEAR_STATE_NAME);
// 2012-07-05 => DAY 65 - 35 days after invoice
addDaysAndCheckForCompletion(20, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
invoiceChecker.checkInvoice(account.getId(), 3, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
invoiceChecker.checkChargedThroughDate(baseEntitlement.getId(), new LocalDate(2012, 7, 31), callContext);
// Should still be in clear state
checkODState(OverdueWrapper.CLEAR_STATE_NAME);
// Now, refund the second (first non-zero dollar) invoice
final Payment payment = paymentApi.getPayment(invoiceUserApi.getInvoicesByAccount(account.getId(), false, callContext).get(1).getPayments().get(0).getPaymentId(), false, false, PLUGIN_PROPERTIES, callContext);
refundPaymentAndCheckForCompletion(account, payment, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT, NextEvent.BLOCK);
// We should now be in OD1
checkODState("OD1");
checkChangePlanWithOverdueState(baseEntitlement, true, true);
}
use of org.killbill.billing.entitlement.api.DefaultEntitlement in project killbill by killbill.
the class TestOverdueWithSubscriptionCancellation method testCheckSubscriptionCancellation.
@Test(groups = "slow")
public void testCheckSubscriptionCancellation() throws Exception {
clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0));
setupAccount();
// Set next invoice to fail and create subscription
paymentPlugin.makeAllInvoicesFailWithError(true);
final DefaultEntitlement baseEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey", productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
bundle = subscriptionApi.getSubscriptionBundle(baseEntitlement.getBundleId(), callContext);
invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
invoiceChecker.checkChargedThroughDate(baseEntitlement.getId(), new LocalDate(2012, 5, 1), callContext);
final DefaultEntitlement addOn1 = addAOEntitlementAndCheckForCompletion(baseEntitlement.getBundleId(), "Holster", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
final DefaultEntitlement addOn2 = addAOEntitlementAndCheckForCompletion(baseEntitlement.getBundleId(), "Holster", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
// Cancel addOn1 one day after
clock.addDays(1);
cancelEntitlementAndCheckForCompletion(addOn1, NextEvent.BLOCK, NextEvent.CANCEL, NextEvent.NULL_INVOICE);
// DAY 30 have to get out of trial before first payment
addDaysAndCheckForCompletion(29, NextEvent.PHASE, NextEvent.PHASE, NextEvent.NULL_INVOICE, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
invoiceChecker.checkChargedThroughDate(baseEntitlement.getId(), new LocalDate(2012, 6, 30), callContext);
// Should still be in clear state
checkODState(OverdueWrapper.CLEAR_STATE_NAME);
// DAY 36 -- RIGHT AFTER OD1 (two block events, for the cancellation and the OD1 state)
// One BLOCK event is for the overdue state transition
// The 2 other BLOCK are for the entitlement blocking states for both base plan and addOn2
addDaysAndCheckForCompletion(6, NextEvent.BLOCK, NextEvent.BLOCK, NextEvent.BLOCK, NextEvent.CANCEL, NextEvent.CANCEL, NextEvent.INVOICE);
// Should be in OD1
checkODState("OD1");
final SubscriptionBase cancelledBaseSubscription = ((DefaultEntitlement) entitlementApi.getEntitlementForId(baseEntitlement.getId(), callContext)).getSubscriptionBase();
assertTrue(cancelledBaseSubscription.getState() == EntitlementState.CANCELLED);
final SubscriptionBase cancelledAddon1 = ((DefaultEntitlement) entitlementApi.getEntitlementForId(addOn1.getId(), callContext)).getSubscriptionBase();
assertTrue(cancelledAddon1.getState() == EntitlementState.CANCELLED);
}
use of org.killbill.billing.entitlement.api.DefaultEntitlement in project killbill by killbill.
the class TestIntegrationWithDifferentBillingPeriods method testChangeMonthlyToQuarterly.
@Test(groups = "slow")
public void testChangeMonthlyToQuarterly() throws Exception {
// We take april as it has 30 days (easier to play with BCD)
final LocalDate today = new LocalDate(2012, 4, 1);
final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(1));
// Set clock to the initial start date - we implicitly assume here that the account timezone is UTC
clock.setDeltaFromReality(today.toDateTimeAtCurrentTime(DateTimeZone.UTC).getMillis() - clock.getUTCNow().getMillis());
final String productName = "Pistol";
//
// CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE, NextEvent.BLOCK NextEvent.INVOICE
//
final DefaultEntitlement bpEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey", productName, ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
assertNotNull(bpEntitlement);
assertEquals(invoiceUserApi.getInvoicesByAccount(account.getId(), false, callContext).size(), 1);
assertEquals(bpEntitlement.getSubscriptionBase().getCurrentPlan().getRecurringBillingPeriod(), BillingPeriod.MONTHLY);
// Move out of trials for interesting invoices adjustments
busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addDays(31);
assertListenerStatus();
List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, callContext);
assertEquals(invoices.size(), 2);
ImmutableList<ExpectedInvoiceItemCheck> toBeChecked = ImmutableList.<ExpectedInvoiceItemCheck>of(new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), new LocalDate(2012, 6, 1), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
invoiceChecker.checkInvoice(invoices.get(1).getId(), callContext, toBeChecked);
//
// MOVE MONTHLY TO QUARTERLY
//
clock.addDays(10);
changeEntitlementAndCheckForCompletion(bpEntitlement, productName, BillingPeriod.QUARTERLY, BillingActionPolicy.IMMEDIATE, NextEvent.CHANGE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, callContext);
assertEquals(invoices.size(), 3);
toBeChecked = ImmutableList.<ExpectedInvoiceItemCheck>of(new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), new LocalDate(2012, 6, 1), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
invoiceChecker.checkInvoice(invoices.get(1).getId(), callContext, toBeChecked);
toBeChecked = ImmutableList.<ExpectedInvoiceItemCheck>of(new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 12), new LocalDate(2012, 8, 1), InvoiceItemType.RECURRING, new BigDecimal("61.59")), new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 12), new LocalDate(2012, 6, 1), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-19.32")));
invoiceChecker.checkInvoice(invoices.get(2).getId(), callContext, toBeChecked);
// Move to 1020-08-01
busHandler.pushExpectedEvents(NextEvent.NULL_INVOICE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addDays(20);
clock.addMonths(2);
assertListenerStatus();
invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, callContext);
assertEquals(invoices.size(), 4);
toBeChecked = ImmutableList.<ExpectedInvoiceItemCheck>of(new ExpectedInvoiceItemCheck(new LocalDate(2012, 8, 1), new LocalDate(2012, 11, 1), InvoiceItemType.RECURRING, new BigDecimal("69.95")));
invoiceChecker.checkInvoice(invoices.get(3).getId(), callContext, toBeChecked);
checkNoMoreInvoiceToGenerate(account);
}
use of org.killbill.billing.entitlement.api.DefaultEntitlement in project killbill by killbill.
the class TestEntitlementUtils method testCancellationIMM.
@Test(groups = "slow", description = "Verify add-ons blocking states are not impacted by IMM cancellations")
public void testCancellationIMM() throws Exception {
// Approximate check, as the blocking state check (checkBlockingStatesDAO) could be a bit off
final DateTime cancellationDateTime = clock.getUTCNow();
final LocalDate cancellationDate = clock.getUTCToday();
// Cancel the base plan
testListener.pushExpectedEvents(NextEvent.CANCEL, NextEvent.BLOCK, NextEvent.CANCEL, NextEvent.BLOCK);
final DefaultEntitlement cancelledBaseEntitlement = (DefaultEntitlement) baseEntitlement.cancelEntitlementWithPolicyOverrideBillingPolicy(EntitlementActionPolicy.IMMEDIATE, BillingActionPolicy.IMMEDIATE, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// Refresh the add-on state
final DefaultEntitlement cancelledAddOnEntitlement = (DefaultEntitlement) entitlementApi.getEntitlementForId(addOnEntitlement.getId(), callContext);
// Verify we compute the right blocking states for the "read" path...
checkFutureBlockingStatesToCancel(cancelledBaseEntitlement, null, null);
checkFutureBlockingStatesToCancel(cancelledAddOnEntitlement, null, null);
checkFutureBlockingStatesToCancel(cancelledBaseEntitlement, cancelledAddOnEntitlement, null);
// ...and for the "write" path (which has been exercised in the cancel call above).
checkActualBlockingStatesToCancel(cancelledBaseEntitlement, cancelledAddOnEntitlement, cancellationDateTime, true);
// Verify also the blocking states DAO doesn't add too many events (all on disk)
checkBlockingStatesDAO(cancelledBaseEntitlement, cancelledAddOnEntitlement, cancellationDate, true);
clock.addDays(30);
// No new event
assertListenerStatus();
checkFutureBlockingStatesToCancel(cancelledBaseEntitlement, null, null);
checkFutureBlockingStatesToCancel(cancelledAddOnEntitlement, null, null);
checkFutureBlockingStatesToCancel(cancelledBaseEntitlement, cancelledAddOnEntitlement, null);
checkActualBlockingStatesToCancel(cancelledBaseEntitlement, cancelledAddOnEntitlement, cancellationDateTime, true);
checkBlockingStatesDAO(cancelledBaseEntitlement, cancelledAddOnEntitlement, cancellationDate, true);
}
Aggregations