Skip to content

Commit

Permalink
invoice: Fix UPCOMING_INVOICE mode to also work with subscription fil…
Browse files Browse the repository at this point in the history
…ter. See #774
  • Loading branch information
sbrossie committed Dec 12, 2017
1 parent 78938bf commit 04da9a9
Show file tree
Hide file tree
Showing 10 changed files with 132 additions and 76 deletions.
Expand Up @@ -95,7 +95,7 @@ public List<EntitlementAOStatusDryRun> getDryRunChangePlanStatus(UUID subscripti

public Iterable<DateTime> getFutureNotificationsForAccount(InternalCallContext context);

public Map<UUID, DateTime> getNextFutureEventForSubscriptions(final SubscriptionBaseTransitionType eventType, final InternalCallContext internalCallContext);
public Map<UUID, DateTime> getNextFutureEventForSubscriptions(final List<SubscriptionBaseTransitionType> eventTypes, final InternalCallContext internalCallContext);


public void updateBCD(final UUID subscriptionId, final int bcd, @Nullable final LocalDate effectiveFromDate, final InternalCallContext internalCallContext) throws SubscriptionBaseApiException;
Expand Down
Expand Up @@ -53,6 +53,10 @@

public class TestIntegrationDryRunInvoice extends TestIntegrationBase {


private static final DryRunArguments DRY_RUN_UPCOMING_INVOICE_ARG = new TestDryRunArguments(DryRunType.UPCOMING_INVOICE);
private static final DryRunArguments DRY_RUN_TARGET_DATE_ARG = new TestDryRunArguments(DryRunType.TARGET_DATE);

//
// Basic test with one subscription that verifies the behavior of using invoice dryRun api with no date
//
Expand Down Expand Up @@ -81,8 +85,7 @@ public void testDryRunWithNoTargetDate() throws Exception {
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 6, 14), new LocalDate(2015, 7, 14), InvoiceItemType.RECURRING, new BigDecimal("249.95")));

// This will verify that the upcoming Phase is found and the invoice is generated at the right date, with correct items
DryRunArguments dryRun = new TestDryRunArguments(DryRunType.UPCOMING_INVOICE);
Invoice dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, dryRun, callContext);
Invoice dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, callContext, expectedInvoices);

// Move through time and verify we get the same invoice
Expand All @@ -95,7 +98,7 @@ public void testDryRunWithNoTargetDate() throws Exception {

// This will verify that the upcoming invoice notification is found and the invoice is generated at the right date, with correct items
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 7, 14), new LocalDate(2015, 8, 14), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, dryRun, callContext);
dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, callContext, expectedInvoices);

// Move through time and verify we get the same invoice
Expand All @@ -108,7 +111,7 @@ public void testDryRunWithNoTargetDate() throws Exception {

// One more time, this will verify that the upcoming invoice notification is found and the invoice is generated at the right date, with correct items
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 8, 14), new LocalDate(2015, 9, 14), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, dryRun, callContext);
dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, callContext, expectedInvoices);
}

Expand Down Expand Up @@ -143,8 +146,7 @@ public void testDryRunWithNoTargetDateAndMultipleNonAlignedSubscriptions() throw
final List<ExpectedInvoiceItemCheck> expectedInvoices = new ArrayList<ExpectedInvoiceItemCheck>();
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2014, 2, 1), new LocalDate(2015, 2, 1), InvoiceItemType.RECURRING, new BigDecimal("2399.95")));

DryRunArguments dryRun = new TestDryRunArguments(DryRunType.UPCOMING_INVOICE);
Invoice dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, dryRun, callContext);
Invoice dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, callContext, expectedInvoices);

busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
Expand All @@ -156,7 +158,7 @@ public void testDryRunWithNoTargetDateAndMultipleNonAlignedSubscriptions() throw

// Since we only have one subscription next dryRun will show the annual
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 2, 1), new LocalDate(2016, 2, 1), InvoiceItemType.RECURRING, new BigDecimal("2399.95")));
dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, dryRun, callContext);
dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, callContext, expectedInvoices);
expectedInvoices.clear();

Expand All @@ -173,7 +175,7 @@ public void testDryRunWithNoTargetDateAndMultipleNonAlignedSubscriptions() throw

// Verify next dryRun invoice and then move the clock to that date to also verify real invoice is the same
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 1, 14), new LocalDate(2015, 2, 14), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, dryRun, callContext);
dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, callContext, expectedInvoices);

busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
Expand All @@ -183,18 +185,17 @@ public void testDryRunWithNoTargetDateAndMultipleNonAlignedSubscriptions() throw
invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, expectedInvoices);
expectedInvoices.clear();

// We test first the next expected invoice for a specific subscription: We can see the targetDate is 2015-2-14 and not 2015-2-1, however we do see both recurring items
final DryRunArguments dryRunWIthSubscription = new TestDryRunArguments(DryRunType.UPCOMING_INVOICE, null, null, null, null, null, null, subscriptionMonthly.getId(), null, null, null);
// We test first the next expected invoice for a specific subscription: We can see the targetDate is 2015-2-14 and not 2015-2-1, and also we only see the item for the monthly subscription
final DryRunArguments dryRunUpcomingInvoiceWithFilterArg = new TestDryRunArguments(DryRunType.UPCOMING_INVOICE, null, null, null, null, null, null, subscriptionMonthly.getId(), null, null, null);
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 2, 14), new LocalDate(2015, 3, 14), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 2, 1), new LocalDate(2016, 2, 1), InvoiceItemType.RECURRING, new BigDecimal("2399.95")));
dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, dryRunWIthSubscription, callContext);
dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, dryRunUpcomingInvoiceWithFilterArg, callContext);
assertEquals(dryRunInvoice.getTargetDate(), new LocalDate(2015, 2, 14));
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, callContext, expectedInvoices);
expectedInvoices.clear();

// Then we test first the next expected invoice at the account level
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 2, 1), new LocalDate(2016, 2, 1), InvoiceItemType.RECURRING, new BigDecimal("2399.95")));
dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, dryRun, callContext);
dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, callContext, expectedInvoices);

busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
Expand All @@ -205,7 +206,7 @@ public void testDryRunWithNoTargetDateAndMultipleNonAlignedSubscriptions() throw
expectedInvoices.clear();

expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 2, 14), new LocalDate(2015, 3, 14), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, dryRun, callContext);
dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, callContext, expectedInvoices);
}

Expand All @@ -230,28 +231,27 @@ public void testDryRunWithPendingSubscription() throws Exception {
assertListenerStatus();

// Generate a dryRun invoice on the billing startDate
final DryRunArguments dryRunArguments1 = new TestDryRunArguments(DryRunType.TARGET_DATE);
final Invoice dryRunInvoice1 = invoiceUserApi.triggerInvoiceGeneration(createdEntitlement.getAccountId(), futureDate, dryRunArguments1, callContext);
final Invoice dryRunInvoice1 = invoiceUserApi.triggerInvoiceGeneration(createdEntitlement.getAccountId(), futureDate, DRY_RUN_TARGET_DATE_ARG, callContext);
assertEquals(dryRunInvoice1.getInvoiceItems().size(), 1);
assertEquals(dryRunInvoice1.getInvoiceItems().get(0).getInvoiceItemType(), InvoiceItemType.FIXED);
assertEquals(dryRunInvoice1.getInvoiceItems().get(0).getAmount().compareTo(BigDecimal.ZERO), 0);
assertEquals(dryRunInvoice1.getInvoiceItems().get(0).getStartDate(), futureDate);
assertEquals(dryRunInvoice1.getInvoiceItems().get(0).getPlanName(), "shotgun-annual");

// Generate a dryRun invoice with a plan change
final DryRunArguments dryRunArguments = new TestDryRunArguments(DryRunType.SUBSCRIPTION_ACTION, "Pistol", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null,
final DryRunArguments dryRunSubscriptionActionArg = new TestDryRunArguments(DryRunType.SUBSCRIPTION_ACTION, "Pistol", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null,
SubscriptionEventType.CHANGE, createdEntitlement.getId(), createdEntitlement.getBundleId(), futureDate, BillingActionPolicy.IMMEDIATE);

// First one day prior subscription starts
try {
invoiceUserApi.triggerInvoiceGeneration(createdEntitlement.getAccountId(), futureDate.minusDays(1), dryRunArguments, callContext);
invoiceUserApi.triggerInvoiceGeneration(createdEntitlement.getAccountId(), futureDate.minusDays(1), dryRunSubscriptionActionArg, callContext);
fail("Should fail to trigger dryRun invoice prior subscription starts");
} catch (final InvoiceApiException e) {
assertEquals(e.getCode(), ErrorCode.INVOICE_NOTHING_TO_DO.getCode());
}

// Second, on the startDate
final Invoice dryRunInvoice2 = invoiceUserApi.triggerInvoiceGeneration(createdEntitlement.getAccountId(), futureDate, dryRunArguments, callContext);
final Invoice dryRunInvoice2 = invoiceUserApi.triggerInvoiceGeneration(createdEntitlement.getAccountId(), futureDate, dryRunSubscriptionActionArg, callContext);
assertEquals(dryRunInvoice2.getInvoiceItems().size(), 1);
assertEquals(dryRunInvoice2.getInvoiceItems().get(0).getInvoiceItemType(), InvoiceItemType.FIXED);
assertEquals(dryRunInvoice2.getInvoiceItems().get(0).getAmount().compareTo(BigDecimal.ZERO), 0);
Expand Down Expand Up @@ -448,9 +448,8 @@ public void testDryRunTargetDateWithIntermediateInvoice() throws Exception {
//
// 1. We verify that a DryRunType.TARGET_DATE for 2015-2-14 leads to an invoice that **only** contains the MONTHLY item (fix for #774)
//
final DryRunArguments dryRun = new TestDryRunArguments(DryRunType.TARGET_DATE, null, null, null, null, null, null, null, null, null, null);
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 2, 14), new LocalDate(2015, 3, 14), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
Invoice dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), new LocalDate(2015, 2, 14), dryRun, callContext);
Invoice dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), new LocalDate(2015, 2, 14), DRY_RUN_TARGET_DATE_ARG, callContext);
assertEquals(dryRunInvoice.getTargetDate(), new LocalDate(2015, 2, 14));
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, callContext, expectedInvoices);
expectedInvoices.clear();
Expand All @@ -459,15 +458,15 @@ public void testDryRunTargetDateWithIntermediateInvoice() throws Exception {
// 2. We verify that a DryRunType.TARGET_DATE for 2015-2-3 leads to an invoice that **only** contains the 2nd ANNUAL item (fix for #774)
//
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 2, 3), new LocalDate(2016, 2, 3), InvoiceItemType.RECURRING, new BigDecimal("199.95")));
dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), new LocalDate(2015, 2, 3), dryRun, callContext);
dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), new LocalDate(2015, 2, 3), DRY_RUN_TARGET_DATE_ARG, callContext);
assertEquals(dryRunInvoice.getTargetDate(), new LocalDate(2015, 2, 3));
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, callContext, expectedInvoices);
expectedInvoices.clear();


// 3. We verify that UPCOMING_INVOICE leads to next invoice fo the ANNUAL
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 2, 1), new LocalDate(2016, 2, 1), InvoiceItemType.RECURRING, new BigDecimal("2399.95")));
dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, new TestDryRunArguments(DryRunType.UPCOMING_INVOICE), callContext);
dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
assertEquals(dryRunInvoice.getTargetDate(), new LocalDate(2015, 2, 1));
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, callContext, expectedInvoices);
expectedInvoices.clear();
Expand Down

1 comment on commit 04da9a9

@pierre
Copy link
Member

@pierre pierre commented on 04da9a9 Dec 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Please sign in to comment.