use of org.killbill.billing.invoice.optimizer.InvoiceOptimizerExp.AccountInvoicesExp in project killbill by killbill.
the class TestInvoiceOptimizerExp method testInArrearWithCancellationP0M.
@Test(groups = "fast")
public void testInArrearWithCancellationP0M() {
final LocalDate startDate = new LocalDate(2021, 2, 1);
final LocalDate cancelDate = new LocalDate(2021, 4, 30);
LocalDate targetDate = new LocalDate(2021, 6, 1);
// Proposed: invoice from 2021-2-1 -> 2021-4-30
final List<InvoiceItem> proposedItems = new ArrayList<InvoiceItem>();
final Invoice proposed = createInvoice(targetDate);
proposedItems.add(createItem(proposed.getId(), BigDecimal.TEN, BigDecimal.TEN, startDate, new LocalDate(2021, 3, 1)));
proposedItems.add(createItem(proposed.getId(), BigDecimal.TEN, BigDecimal.TEN, new LocalDate(2021, 3, 1), new LocalDate(2021, 4, 1)));
proposedItems.add(createItem(proposed.getId(), BigDecimal.TEN, new BigDecimal("9.88"), new LocalDate(2021, 4, 1), cancelDate));
// P0M
final LocalDate cutoffDate = targetDate;
// Existing: invoice from 2021-2-1 -> 2021-4-30
// Existing (filtered) empty
final List<Invoice> existing = new ArrayList<Invoice>();
final Invoice invoice = createInvoice(cutoffDate);
existing.add(invoice);
final AccountInvoicesExp test = new AccountInvoicesExp(cutoffDate, null, existing);
// Note that we don't really need the billing events except to fetch Plan info in AccountInvoicesExp#filterProposedItems
// so we don't need to explicitly add the CANCEL billing event
final DefaultBillingEventSet billingEvents = new DefaultBillingEventSet(false, false, false);
billingEvents.add(createBillingEvent(startDate, BillingMode.IN_ARREAR, SubscriptionBaseTransitionType.CREATE));
test.filterProposedItems(proposedItems, billingEvents, internalCallContext);
Assert.assertEquals(proposedItems.size(), 0);
}
use of org.killbill.billing.invoice.optimizer.InvoiceOptimizerExp.AccountInvoicesExp in project killbill by killbill.
the class TestInvoiceOptimizerExp method testInArrearP1M.
@Test(groups = "fast")
public void testInArrearP1M() {
final LocalDate startDate = new LocalDate(2021, 2, 1);
LocalDate targetDate = new LocalDate(2021, 6, 1);
// Proposed: invoice from 2021-2-1 -> 2021-6-1
final List<InvoiceItem> proposedItems = new ArrayList<InvoiceItem>();
final Invoice proposed = createInvoice(targetDate);
proposedItems.add(createItem(proposed.getId(), BigDecimal.TEN, BigDecimal.TEN, startDate, new LocalDate(2021, 3, 1)));
proposedItems.add(createItem(proposed.getId(), BigDecimal.TEN, BigDecimal.TEN, new LocalDate(2021, 3, 1), new LocalDate(2021, 4, 1)));
proposedItems.add(createItem(proposed.getId(), BigDecimal.TEN, BigDecimal.TEN, new LocalDate(2021, 4, 1), new LocalDate(2021, 5, 1)));
proposedItems.add(createItem(proposed.getId(), BigDecimal.TEN, BigDecimal.TEN, new LocalDate(2021, 5, 1), new LocalDate(2021, 6, 1)));
// P1M
final LocalDate cutoffDate = targetDate.minusMonths(1);
// Existing: invoice from 2021-2-1 -> 2021-5-1
// Existing (filtered) 2021-4-1 -> 2021-5-1
final List<Invoice> existing = new ArrayList<Invoice>();
final Invoice invoice = createInvoice(cutoffDate);
final InvoiceItem newItem = createItem(invoice.getId(), BigDecimal.TEN, BigDecimal.TEN, cutoffDate.minusMonths(1), cutoffDate);
invoice.addInvoiceItem(newItem);
existing.add(invoice);
final AccountInvoicesExp test = new AccountInvoicesExp(cutoffDate, null, existing);
final DefaultBillingEventSet billingEvents = new DefaultBillingEventSet(false, false, false);
billingEvents.add(createBillingEvent(startDate, BillingMode.IN_ARREAR, SubscriptionBaseTransitionType.CREATE));
test.filterProposedItems(proposedItems, billingEvents, internalCallContext);
Assert.assertEquals(proposedItems.size(), 2);
// Latest existing (P1M)
Assert.assertEquals(proposedItems.get(0).getStartDate(), new LocalDate(2021, 4, 1));
Assert.assertEquals(proposedItems.get(0).getEndDate(), new LocalDate(2021, 5, 1));
// New proposed item
Assert.assertEquals(proposedItems.get(1).getStartDate(), new LocalDate(2021, 5, 1));
Assert.assertEquals(proposedItems.get(1).getEndDate(), new LocalDate(2021, 6, 1));
}
use of org.killbill.billing.invoice.optimizer.InvoiceOptimizerExp.AccountInvoicesExp in project killbill by killbill.
the class TestFixedAndRecurringInvoiceItemGeneratorWithOptimization method testRecurringInAdvance.
@Test(groups = "fast")
public void testRecurringInAdvance() throws InvoiceApiException {
final DateTime startDate = new DateTime("2020-01-01");
final BillingEventSet events = new MockBillingEventSet();
final BigDecimal amount = BigDecimal.TEN;
final MockInternationalPrice price = new MockInternationalPrice(new DefaultPrice(amount, account.getCurrency()));
final Plan plan = new MockPlan("my-plan");
final PlanPhase planPhase = new MockPlanPhase(price, null, BillingPeriod.MONTHLY, PhaseType.EVERGREEN);
final BillingEvent event = invoiceUtil.createMockBillingEvent(account, subscription, startDate, plan, planPhase, null, amount, account.getCurrency(), planPhase.getRecurring().getBillingPeriod(), 1, BillingMode.IN_ADVANCE, "Billing Event Desc", 1L, SubscriptionBaseTransitionType.CREATE);
events.add(event);
// Only look for older invoices 1 month from NOW (we assume targetDate = NOW as time pass normally)
final Period maxInvoiceLimit = new Period("P1m");
// Initial invoicing (targetDate1 = startDate)
// There is no existing invoice
// => Should generate the item
// 2020-01-01
final LocalDate targetDate1 = startDate.toLocalDate();
final LocalDate cuttoffDate1 = targetDate1.minus(maxInvoiceLimit);
final AccountInvoices existingInvoices1 = new AccountInvoicesExp(cuttoffDate1, null, ImmutableList.of());
final InvoiceGeneratorResult result1 = fixedAndRecurringInvoiceItemGenerator.generateItems(account, UUID.randomUUID(), events, existingInvoices1, targetDate1, account.getCurrency(), new HashMap<UUID, SubscriptionFutureNotificationDates>(), null, internalCallContext);
assertEquals(result1.getItems().size(), 1);
assertEquals(result1.getItems().get(0).getInvoiceItemType(), InvoiceItemType.RECURRING);
assertEquals(result1.getItems().get(0).getStartDate().compareTo(new LocalDate("2020-01-01")), 0);
assertEquals(result1.getItems().get(0).getEndDate().compareTo(new LocalDate("2020-02-01")), 0);
// One month after invoicing, optimization does not kick-in yet
// There is an existing invoice
// => Should not regenerate the item, but should correctly generate the next RECURRING item
// 2020-02-01
final LocalDate targetDate2 = startDate.toLocalDate().plusMonths(1);
final LocalDate cuttoffDate2 = targetDate2.minus(maxInvoiceLimit);
final Invoice invoice2 = new DefaultInvoice(account.getId(), clock.getUTCToday(), targetDate2, account.getCurrency());
invoice2.addInvoiceItem(new RecurringInvoiceItem(UUID.randomUUID(), startDate, invoice2.getId(), account.getId(), subscription.getBundleId(), subscription.getId(), null, event.getPlan().getName(), event.getPlanPhase().getName(), null, startDate.toLocalDate(), startDate.plusMonths(1).toLocalDate(), amount, amount, account.getCurrency()));
final AccountInvoices existingInvoices2 = new AccountInvoicesExp(cuttoffDate2, null, ImmutableList.of(invoice2));
final InvoiceGeneratorResult result2 = fixedAndRecurringInvoiceItemGenerator.generateItems(account, UUID.randomUUID(), events, existingInvoices2, targetDate2, account.getCurrency(), new HashMap<UUID, SubscriptionFutureNotificationDates>(), null, internalCallContext);
assertEquals(result2.getItems().size(), 1);
assertEquals(result2.getItems().get(0).getInvoiceItemType(), InvoiceItemType.RECURRING);
assertEquals(result2.getItems().get(0).getStartDate().compareTo(new LocalDate("2020-02-01")), 0);
assertEquals(result2.getItems().get(0).getEndDate().compareTo(new LocalDate("2020-03-01")), 0);
// Two month after invoicing, optimization **does** kick-in
// There are 2 existing invoices but the first one is ignored (optimization)
// => Should not regenerate the item
// 2020-03-01
final LocalDate targetDate3 = startDate.toLocalDate().plusMonths(2);
final LocalDate cuttoffDate3 = targetDate3.minus(maxInvoiceLimit);
final Invoice invoice3 = new DefaultInvoice(account.getId(), clock.getUTCToday(), targetDate3, account.getCurrency());
invoice3.addInvoiceItem(new RecurringInvoiceItem(UUID.randomUUID(), startDate.plusMonths(1), invoice3.getId(), account.getId(), subscription.getBundleId(), subscription.getId(), null, event.getPlan().getName(), event.getPlanPhase().getName(), null, startDate.plusMonths(1).toLocalDate(), startDate.plusMonths(2).toLocalDate(), amount, amount, account.getCurrency()));
final AccountInvoices existingInvoices3 = new AccountInvoicesExp(cuttoffDate3, null, ImmutableList.of(invoice3));
final InvoiceGeneratorResult result3 = fixedAndRecurringInvoiceItemGenerator.generateItems(account, UUID.randomUUID(), events, existingInvoices3, targetDate3, account.getCurrency(), new HashMap<UUID, SubscriptionFutureNotificationDates>(), null, internalCallContext);
assertEquals(result3.getItems().size(), 1);
assertEquals(result3.getItems().get(0).getInvoiceItemType(), InvoiceItemType.RECURRING);
assertEquals(result3.getItems().get(0).getStartDate().compareTo(new LocalDate("2020-03-01")), 0);
assertEquals(result3.getItems().get(0).getEndDate().compareTo(new LocalDate("2020-04-01")), 0);
}
Aggregations