use of org.killbill.billing.account.api.Account in project killbill by killbill.
the class TestBillingAlignment method testTransitionAccountBAToSubscriptionBA.
@Test(groups = "slow")
public void testTransitionAccountBAToSubscriptionBA() throws Exception {
// We take april as it has 30 days (easier to play with BCD)
// Set clock to the initial start date - we implicitly assume here that the account timezone is UTC
clock.setDay(new LocalDate(2012, 4, 1));
// Set the BCD to the 25th
final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(25));
//
// CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE NextEvent.INVOICE
// (Start with monthly that has an 'Account' billing alignment)
//
final DefaultEntitlement bpEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
assertNotNull(bpEntitlement);
invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
invoiceChecker.checkChargedThroughDate(bpEntitlement.getId(), new LocalDate(2012, 4, 1), callContext);
// GET OUT TRIAL (moving clock to 2012-05-04)
addDaysAndCheckForCompletion(33, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), new LocalDate(2012, 5, 25), InvoiceItemType.RECURRING, new BigDecimal("199.96")));
invoiceChecker.checkChargedThroughDate(bpEntitlement.getId(), new LocalDate(2012, 5, 25), callContext);
// Change plan to annual that has been configured to have a 'Subscription' billing alignment
final DefaultEntitlement changedBpEntitlement = changeEntitlementAndCheckForCompletion(bpEntitlement, "Shotgun", BillingPeriod.ANNUAL, null, NextEvent.CHANGE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
invoiceChecker.checkInvoice(account.getId(), 3, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 4), new LocalDate(2013, 5, 1), InvoiceItemType.RECURRING, new BigDecimal("2380.22")), new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 4), new LocalDate(2012, 5, 25), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-174.97")));
invoiceChecker.checkChargedThroughDate(bpEntitlement.getId(), new LocalDate(2013, 5, 1), callContext);
Assert.assertEquals(changedBpEntitlement.getSubscriptionBase().getAllTransitions().size(), 3);
final SubscriptionBaseTransition trial = changedBpEntitlement.getSubscriptionBase().getAllTransitions().get(0);
Assert.assertEquals(trial.getEffectiveTransitionTime().toLocalDate().compareTo(new LocalDate(2012, 4, 1)), 0);
Assert.assertEquals(trial.getNextPhase().getName(), "shotgun-monthly-trial");
final SubscriptionBaseTransition smEvergreen = changedBpEntitlement.getSubscriptionBase().getAllTransitions().get(1);
Assert.assertEquals(smEvergreen.getEffectiveTransitionTime().toLocalDate().compareTo(new LocalDate(2012, 5, 1)), 0);
Assert.assertEquals(smEvergreen.getNextPhase().getName(), "shotgun-monthly-evergreen");
final SubscriptionBaseTransition saEvergreen = changedBpEntitlement.getSubscriptionBase().getAllTransitions().get(2);
// Verify the IMMEDIATE policy
Assert.assertEquals(saEvergreen.getEffectiveTransitionTime().toLocalDate().compareTo(new LocalDate(2012, 5, 4)), 0);
// Verify the START_OF_SUBSCRIPTION alignment (both plans have the same 30 days trial)
Assert.assertEquals(saEvergreen.getNextPhase().getName(), "shotgun-annual-evergreen");
}
use of org.killbill.billing.account.api.Account in project killbill by killbill.
the class TestOverdueChildParentRelationship method testOverdueStagesParentMultiChildAccounts.
@Test(groups = "slow", description = "Test overdue stages and return to clear on CTD for Parent and Child accounts")
public void testOverdueStagesParentMultiChildAccounts() throws Exception {
// 2012-05-01T00:03:42.000Z
clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0));
setupAccount();
final Account childAccount1 = createAccountWithNonOsgiPaymentMethod(getChildAccountData(0, account.getId(), true));
final Account childAccount2 = createAccountWithNonOsgiPaymentMethod(getChildAccountData(0, account.getId(), true));
final Account childAccount3 = createAccountWithNonOsgiPaymentMethod(getChildAccountData(0, account.getId(), true));
final Account childAccountNoPaymentDelegated = createAccountWithNonOsgiPaymentMethod(getChildAccountData(0, account.getId(), false));
// Set next invoice to fail and create subscription
paymentPlugin.makeAllInvoicesFailWithError(true);
final DefaultEntitlement baseEntitlement = createBaseEntitlementAndCheckForCompletion(childAccount1.getId(), "externalKey", productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
bundle = subscriptionApi.getSubscriptionBundle(baseEntitlement.getBundleId(), callContext);
invoiceChecker.checkInvoice(childAccount1.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-2 => DAY 1 : Parent Invoice commit status
addDaysAndCheckForCompletion(1, NextEvent.INVOICE);
// 2012-05-2 => DAY 2
addDaysAndCheckForCompletion(1);
final DefaultEntitlement baseEntitlement2 = createBaseEntitlementAndCheckForCompletion(childAccount2.getId(), "externalKey2", productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
invoiceChecker.checkInvoice(childAccount2.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 3), null, InvoiceItemType.FIXED, new BigDecimal("0")));
invoiceChecker.checkChargedThroughDate(baseEntitlement2.getId(), new LocalDate(2012, 5, 3), callContext);
// 2012-05-3 => DAY 3 : Parent Invoice commit status (Sub.2)
addDaysAndCheckForCompletion(1, NextEvent.INVOICE);
// 2012-05-31 => DAY 30 have to get out of trial {I0, P0}
addDaysAndCheckForCompletion(27, NextEvent.PHASE, NextEvent.INVOICE);
// 2012-06-01 => Parent Invoice payment attempt
addDaysAndCheckForCompletion(1, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
// 2012-06-02 => DAY 30 have to get out of trial {I0, P0} (Sub.2)
addDaysAndCheckForCompletion(1, NextEvent.PHASE, NextEvent.INVOICE);
// 2012-06-03 => Parent Invoice payment attempt (Sub.2)
addDaysAndCheckForCompletion(1, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
invoiceChecker.checkInvoice(childAccount1.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);
// 2012-06-09 => DAY 8 : Retry P0
addDaysAndCheckForCompletion(6, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
checkODState(OverdueWrapper.CLEAR_STATE_NAME, account.getId());
checkODState(OverdueWrapper.CLEAR_STATE_NAME, childAccount1.getId());
checkODState(OverdueWrapper.CLEAR_STATE_NAME, childAccount2.getId());
checkODState(OverdueWrapper.CLEAR_STATE_NAME, childAccount3.getId());
checkODState(OverdueWrapper.CLEAR_STATE_NAME, childAccountNoPaymentDelegated.getId());
// 2012-06-11 => Day 10 - Retry P0 - Move to OD1 state
addDaysAndCheckForCompletion(2, NextEvent.BLOCK, NextEvent.BLOCK, NextEvent.BLOCK, NextEvent.BLOCK, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
checkODState("OD1", account.getId());
checkODState("OD1", childAccount1.getId());
checkODState("OD1", childAccount2.getId());
checkODState("OD1", childAccount3.getId());
checkODState(OverdueWrapper.CLEAR_STATE_NAME, childAccountNoPaymentDelegated.getId());
// 2012-06-17 => DAY 16 : Retry P0
addDaysAndCheckForCompletion(6, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
checkODState("OD1", account.getId());
checkODState("OD1", childAccount1.getId());
checkODState("OD1", childAccount2.getId());
checkODState("OD1", childAccount3.getId());
checkODState(OverdueWrapper.CLEAR_STATE_NAME, childAccountNoPaymentDelegated.getId());
// 2012-06-19 => Day 18 - Retry P0 - Move to OD2 state
addDaysAndCheckForCompletion(2, NextEvent.TAG, NextEvent.BLOCK, NextEvent.TAG, NextEvent.BLOCK, NextEvent.TAG, NextEvent.BLOCK, NextEvent.TAG, NextEvent.BLOCK, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
checkODState("OD2", account.getId());
checkODState("OD2", childAccount1.getId());
checkODState("OD2", childAccount2.getId());
checkODState("OD2", childAccount3.getId());
checkODState(OverdueWrapper.CLEAR_STATE_NAME, childAccountNoPaymentDelegated.getId());
allowPaymentsAndResetOverdueToClearByPayingAllUnpaidInvoices(0, 4, childAccount1, childAccount2, childAccount3);
}
use of org.killbill.billing.account.api.Account in project killbill by killbill.
the class TestOverdueChildParentRelationship method testOverdueStagesParentChildAccounts.
@Test(groups = "slow", description = "Test overdue stages and return to clear on CTD for Parent and Child accounts")
public void testOverdueStagesParentChildAccounts() throws Exception {
// 2012-05-01T00:03:42.000Z
clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0));
setupAccount();
final Account childAccount = createAccountWithNonOsgiPaymentMethod(getChildAccountData(0, account.getId(), true));
// Set next invoice to fail and create subscription
paymentPlugin.makeAllInvoicesFailWithError(true);
final DefaultEntitlement baseEntitlement = createBaseEntitlementAndCheckForCompletion(childAccount.getId(), "externalKey", productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
bundle = subscriptionApi.getSubscriptionBundle(baseEntitlement.getBundleId(), callContext);
invoiceChecker.checkInvoice(childAccount.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
//invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.PARENT_SUMMARY, new BigDecimal("0")));
invoiceChecker.checkChargedThroughDate(baseEntitlement.getId(), new LocalDate(2012, 5, 1), callContext);
// 2012-05-2 => DAY 1 : Parent Invoice commit status
addDaysAndCheckForCompletion(1, NextEvent.INVOICE);
// 2012-05-31 => DAY 30 have to get out of trial {I0, P0}
addDaysAndCheckForCompletion(29, NextEvent.PHASE, NextEvent.INVOICE);
// 2012-06-01 => Parent Invoice payment attempt
addDaysAndCheckForCompletion(1, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
invoiceChecker.checkInvoice(childAccount.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
//invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.PARENT_SUMMARY, new BigDecimal("249.95")));
invoiceChecker.checkChargedThroughDate(baseEntitlement.getId(), new LocalDate(2012, 6, 30), callContext);
// 2012-06-09 => DAY 8 : Retry P0
addDaysAndCheckForCompletion(8, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
checkODState(OverdueWrapper.CLEAR_STATE_NAME, account.getId());
checkODState(OverdueWrapper.CLEAR_STATE_NAME, childAccount.getId());
// 2012-06-11 => Day 10 - Retry P0 - Move to OD1 state
addDaysAndCheckForCompletion(2, NextEvent.BLOCK, NextEvent.BLOCK);
checkODState("OD1", account.getId());
checkODState("OD1", childAccount.getId());
// 2012-06-17 => DAY 16 - Retry P1
addDaysAndCheckForCompletion(6, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
checkODState("OD1", account.getId());
checkODState("OD1", childAccount.getId());
// 2012-06-19 => Day 18 - Retry P0 - Move to OD2 state
addDaysAndCheckForCompletion(2, NextEvent.TAG, NextEvent.BLOCK, NextEvent.TAG, NextEvent.BLOCK);
checkODState("OD2", account.getId());
checkODState("OD2", childAccount.getId());
// 2012-06-25 => DAY 24 - Retry P2
addDaysAndCheckForCompletion(6, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
checkODState("OD2", account.getId());
checkODState("OD2", childAccount.getId());
// 2012-06-27 => Day 26 - Retry P2 - Move to OD3 state
addDaysAndCheckForCompletion(2, NextEvent.BLOCK, NextEvent.BLOCK);
checkODState("OD3", account.getId());
checkODState("OD3", childAccount.getId());
// Make sure the 'invoice-service:next-billing-date-queue' gets processed before we continue and since we are in AUTO_INVOICING_OFF
// no event (NULL_INVOICE) will be generated and so we can't synchronize on any event, and we need to add a small amount of sleep
Thread.sleep(1000);
// Verify the account balance is 0
assertEquals(invoiceUserApi.getAccountBalance(account.getId(), callContext).compareTo(new BigDecimal("249.95")), 0);
assertEquals(invoiceUserApi.getAccountBalance(childAccount.getId(), callContext).compareTo(new BigDecimal("249.95")), 0);
allowPaymentsAndResetOverdueToClearByPayingAllUnpaidInvoices(1, 1, childAccount);
// check invoice generated after clear child account
invoiceChecker.checkInvoice(childAccount.getId(), 3, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 19), new LocalDate(2012, 6, 27), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-66.65")), new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 27), new LocalDate(2012, 6, 27), InvoiceItemType.CBA_ADJ, new BigDecimal("66.65")));
// Verify the account balance is now 0
assertEquals(invoiceUserApi.getAccountBalance(account.getId(), callContext).compareTo(BigDecimal.ZERO), 0);
assertEquals(invoiceUserApi.getAccountBalance(childAccount.getId(), callContext).compareTo(BigDecimal.valueOf(-66.65)), 0);
}
use of org.killbill.billing.account.api.Account in project killbill by killbill.
the class TestMigrationSubscriptions method testSimpleMigrationBPSkipTrial.
//
// Scenario: On 2016-1-1, we decide to migrate a subscription with a cutOverDate of 2015-12-20 (12 days in the past) and a billing date of 2016-2-01, we we want to skip the trial
// (note that since we skip the trial billingDate = 2016-2-01 aligns well with the BCD=1 we set on our test account)
//
//
@Test(groups = "slow")
public void testSimpleMigrationBPSkipTrial() 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(2015, 12, 20);
final LocalDate billingMigrationDate = new LocalDate(2016, 2, 1);
// Entitlement wil be created in ACTIVE state because entitlementMigrationDate was set in the past
busHandler.pushExpectedEvents(NextEvent.BLOCK);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleKey", null, entitlementMigrationDate, billingMigrationDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
Assert.assertEquals(entitlement.getState(), EntitlementState.ACTIVE);
// Move clock next month for first RECURRING invoice (note that TRIAL was correctly skipped, we directly start RECURRING on billingMigrationDate
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
assertListenerStatus();
final LocalDate startDate = billingMigrationDate;
final LocalDate endDate = startDate.plusMonths(1);
expectedInvoices.add(new ExpectedInvoiceItemCheck(startDate, endDate, InvoiceItemType.RECURRING, new BigDecimal("249.95")));
invoiceChecker.checkInvoice(account.getId(), 1, callContext, expectedInvoices);
expectedInvoices.clear();
}
use of org.killbill.billing.account.api.Account in project killbill by killbill.
the class TestMigrationSubscriptions method testSimpleMigrationBPSkipTrialWithPendingCancellation.
//
// Scenario: On 2016-1-1, we decide to migrate a subscription with a cutOverDate of 2015-12-20 (12 days in the past) and a billing date of 2016-2-01, we we want to skip the trial.
// In addition we subscription needs to be future cancelled (2016-2-15) at the time we migrate it
// (note that since we skip the trial billingDate = 2016-2-01 aligns well with the BCD=1 we set on our test account)
//
//
@Test(groups = "slow")
public void testSimpleMigrationBPSkipTrialWithPendingCancellation() 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>();
final LocalDate entitlementMigrationDate = new LocalDate(2015, 12, 20);
// We set both entitlement and billing date with desired value
final LocalDate billingMigrationDate = new LocalDate(2016, 2, 1);
final LocalDate effectiveCancellationDate = new LocalDate(2016, 2, 15);
// Entitlement wil be created in ACTIVE state because entitlementMigrationDate was set in the past
busHandler.pushExpectedEvents(NextEvent.BLOCK);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleKey", null, entitlementMigrationDate, billingMigrationDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
Assert.assertEquals(entitlement.getState(), EntitlementState.ACTIVE);
// Perform the cancellation (we did not move the clock, the is is future cancellation done at the time we decide to migrate)
entitlement.cancelEntitlementWithDate(effectiveCancellationDate, true, ImmutableList.<PluginProperty>of(), callContext);
// Billing starts straight on EVERGREEN
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
assertListenerStatus();
// The invoice will be pro-rated up to the cancellation date
final LocalDate startDate = billingMigrationDate;
final LocalDate endDate = effectiveCancellationDate;
expectedInvoices.add(new ExpectedInvoiceItemCheck(startDate, endDate, InvoiceItemType.RECURRING, new BigDecimal("120.67")));
invoiceChecker.checkInvoice(account.getId(), 1, callContext, expectedInvoices);
expectedInvoices.clear();
// Move to cancellation date
busHandler.pushExpectedEvents(NextEvent.CANCEL, NextEvent.BLOCK, NextEvent.NULL_INVOICE, NextEvent.NULL_INVOICE);
clock.addMonths(14);
assertListenerStatus();
final Entitlement cancelledEntitlement = entitlementApi.getEntitlementForId(entitlement.getId(), callContext);
Assert.assertEquals(cancelledEntitlement.getState(), EntitlementState.CANCELLED);
}
Aggregations