Search in sources :

Example 1 with DryRunArguments

use of org.killbill.billing.invoice.api.DryRunArguments in project killbill by killbill.

the class TestIntegrationInvoice method testDryRunWithNoTargetDate.

//
// Basic test with one subscription that verifies the behavior of using invoice dryRun api with no date
//
@Test(groups = "slow")
public void testDryRunWithNoTargetDate() throws Exception {
    final int billingDay = 14;
    final DateTime initialCreationDate = new DateTime(2015, 5, 15, 0, 0, 0, 0, testTimeZone);
    // set clock to the initial start date
    clock.setTime(initialCreationDate);
    log.info("Beginning test with BCD of " + billingDay);
    final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(billingDay));
    int invoiceItemCount = 1;
    //
    // CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE, NextEvent.BLOCK NextEvent.INVOICE
    //
    DefaultEntitlement baseEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "bundleKey", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
    DefaultSubscriptionBase subscription = subscriptionDataFromSubscription(baseEntitlement.getSubscriptionBase());
    invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedInvoiceItemCheck(initialCreationDate.toLocalDate(), null, InvoiceItemType.FIXED, new BigDecimal("0")));
    // No end date for the trial item (fixed price of zero), and CTD should be today (i.e. when the trial started)
    invoiceChecker.checkChargedThroughDate(subscription.getId(), clock.getUTCToday(), callContext);
    final List<ExpectedInvoiceItemCheck> expectedInvoices = new ArrayList<ExpectedInvoiceItemCheck>();
    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);
    invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, callContext, expectedInvoices);
    // Move through time and verify we get the same invoice
    busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    clock.addDays(30);
    assertListenerStatus();
    List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, callContext);
    invoiceChecker.checkInvoice(invoices.get(1).getId(), callContext, expectedInvoices);
    expectedInvoices.clear();
    // 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);
    invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, callContext, expectedInvoices);
    // Move through time and verify we get the same invoice
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    clock.addMonths(1);
    assertListenerStatus();
    invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, callContext);
    invoiceChecker.checkInvoice(invoices.get(2).getId(), callContext, expectedInvoices);
    expectedInvoices.clear();
    // 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);
    invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, callContext, expectedInvoices);
}
Also used : Account(org.killbill.billing.account.api.Account) Invoice(org.killbill.billing.invoice.api.Invoice) DryRunArguments(org.killbill.billing.invoice.api.DryRunArguments) ArrayList(java.util.ArrayList) ExpectedInvoiceItemCheck(org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) DefaultSubscriptionBase(org.killbill.billing.subscription.api.user.DefaultSubscriptionBase) Test(org.testng.annotations.Test)

Example 2 with DryRunArguments

use of org.killbill.billing.invoice.api.DryRunArguments in project killbill by killbill.

the class InvoiceDispatcher method processSubscriptionInternal.

private Invoice processSubscriptionInternal(final UUID subscriptionId, final LocalDate targetDate, final boolean dryRunForNotification, final InternalCallContext context) throws InvoiceApiException {
    try {
        if (subscriptionId == null) {
            log.warn("Failed handling SubscriptionBase change.", new InvoiceApiException(ErrorCode.INVOICE_INVALID_TRANSITION));
            return null;
        }
        final UUID accountId = subscriptionApi.getAccountIdFromSubscriptionId(subscriptionId, context);
        final DryRunArguments dryRunArguments = dryRunForNotification ? TARGET_DATE_DRY_RUN_ARGUMENTS : null;
        return processAccountFromNotificationOrBusEvent(accountId, targetDate, dryRunArguments, context);
    } catch (final SubscriptionBaseApiException e) {
        log.warn("Failed handling SubscriptionBase change.", new InvoiceApiException(ErrorCode.INVOICE_NO_ACCOUNT_ID_FOR_SUBSCRIPTION_ID, subscriptionId.toString()));
        return null;
    }
}
Also used : InvoiceApiException(org.killbill.billing.invoice.api.InvoiceApiException) DryRunArguments(org.killbill.billing.invoice.api.DryRunArguments) UUID(java.util.UUID) SubscriptionBaseApiException(org.killbill.billing.subscription.api.user.SubscriptionBaseApiException)

Example 3 with DryRunArguments

use of org.killbill.billing.invoice.api.DryRunArguments in project killbill by killbill.

the class TestIntegration method testFutureCancelBPWithAOAfterPhase.

@Test(groups = "slow", description = "https://github.com/killbill/killbill/issues/897")
public void testFutureCancelBPWithAOAfterPhase() 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));
    final AccountData accountData = getAccountData(1);
    final Account account = createAccountWithNonOsgiPaymentMethod(accountData);
    accountChecker.checkAccount(account.getId(), accountData, callContext);
    final List<ExpectedInvoiceItemCheck> expectedInvoices = new ArrayList<ExpectedInvoiceItemCheck>();
    // 
    // CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE, NextEvent.BLOCK NextEvent.INVOICE
    // 
    final DefaultEntitlement bpSubscription = createBaseEntitlementAndCheckForCompletion(account.getId(), "bundleKey", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
    // Check bundle after BP got created otherwise we get an error from auditApi.
    subscriptionChecker.checkSubscriptionCreated(bpSubscription.getId(), internalCallContext);
    expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
    invoiceChecker.checkInvoice(account.getId(), 1, callContext, expectedInvoices);
    expectedInvoices.clear();
    // 
    // ADD ADD_ON
    // 
    addAOEntitlementAndCheckForCompletion(bpSubscription.getBundleId(), "Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), new LocalDate(2012, 5, 1), InvoiceItemType.RECURRING, new BigDecimal("399.95")));
    final Invoice invoice2 = invoiceChecker.checkInvoice(account.getId(), 2, callContext, expectedInvoices);
    paymentChecker.checkPayment(account.getId(), 1, callContext, new ExpectedPaymentCheck(new LocalDate(2012, 4, 1), new BigDecimal("399.95"), TransactionStatus.SUCCESS, invoice2.getId(), Currency.USD));
    expectedInvoices.clear();
    // Go past the PHASE events
    addMonthsAndCheckForCompletion(1, NextEvent.PHASE, NextEvent.PHASE, NextEvent.NULL_INVOICE, NextEvent.NULL_INVOICE, NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
    expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), new LocalDate(2012, 6, 1), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
    expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), new LocalDate(2012, 6, 1), InvoiceItemType.RECURRING, new BigDecimal("999.95")));
    final Invoice invoice3 = invoiceChecker.checkInvoice(account.getId(), 3, callContext, expectedInvoices);
    expectedInvoices.clear();
    paymentChecker.checkPayment(account.getId(), 2, callContext, new ExpectedPaymentCheck(new LocalDate(2012, 5, 1), new BigDecimal("1249.9"), TransactionStatus.SUCCESS, invoice3.getId(), Currency.USD));
    expectedInvoices.clear();
    // 
    // CANCEL BP EOT
    // 
    cancelEntitlementAndCheckForCompletion(bpSubscription, EntitlementActionPolicy.END_OF_TERM, BillingActionPolicy.END_OF_TERM);
    // Verify we can trigger a dry-run invoice while the cancellation is pending
    final DryRunArguments dryRun = new TestDryRunArguments(DryRunType.SUBSCRIPTION_ACTION, null, null, null, null, null, SubscriptionEventType.STOP_BILLING, bpSubscription.getId(), bpSubscription.getBundleId(), null, null);
    try {
        invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), new LocalDate(2012, 6, 1), dryRun, callContext);
        fail();
    } catch (final InvoiceApiException e) {
        assertEquals(e.getCode(), INVOICE_NOTHING_TO_DO.getCode());
    }
    addMonthsAndCheckForCompletion(1, NextEvent.BLOCK, NextEvent.BLOCK, NextEvent.CANCEL, NextEvent.CANCEL, NextEvent.NULL_INVOICE, NextEvent.NULL_INVOICE);
    checkNoMoreInvoiceToGenerate(account);
}
Also used : Account(org.killbill.billing.account.api.Account) Invoice(org.killbill.billing.invoice.api.Invoice) DryRunArguments(org.killbill.billing.invoice.api.DryRunArguments) ArrayList(java.util.ArrayList) LocalDate(org.joda.time.LocalDate) ExpectedInvoiceItemCheck(org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck) BigDecimal(java.math.BigDecimal) ExpectedPaymentCheck(org.killbill.billing.beatrix.util.PaymentChecker.ExpectedPaymentCheck) InvoiceApiException(org.killbill.billing.invoice.api.InvoiceApiException) AccountData(org.killbill.billing.account.api.AccountData) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) Test(org.testng.annotations.Test)

Example 4 with DryRunArguments

use of org.killbill.billing.invoice.api.DryRunArguments in project killbill by killbill.

the class TestIntegration method testFutureCancelBPWithAOBeforePhase.

@Test(groups = "slow", description = "https://github.com/killbill/killbill/issues/897")
public void testFutureCancelBPWithAOBeforePhase() 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));
    final AccountData accountData = getAccountData(1);
    final Account account = createAccountWithNonOsgiPaymentMethod(accountData);
    accountChecker.checkAccount(account.getId(), accountData, callContext);
    final List<ExpectedInvoiceItemCheck> expectedInvoices = new ArrayList<ExpectedInvoiceItemCheck>();
    // 
    // CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE, NextEvent.BLOCK NextEvent.INVOICE
    // 
    final DefaultEntitlement bpSubscription = createBaseEntitlementAndCheckForCompletion(account.getId(), "bundleKey", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
    // Check bundle after BP got created otherwise we get an error from auditApi.
    subscriptionChecker.checkSubscriptionCreated(bpSubscription.getId(), internalCallContext);
    expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
    invoiceChecker.checkInvoice(account.getId(), 1, callContext, expectedInvoices);
    expectedInvoices.clear();
    addMonthsAndCheckForCompletion(1, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
    expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), new LocalDate(2012, 6, 1), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
    final Invoice invoice2 = invoiceChecker.checkInvoice(account.getId(), 2, callContext, expectedInvoices);
    paymentChecker.checkPayment(account.getId(), 1, callContext, new ExpectedPaymentCheck(new LocalDate(2012, 5, 1), new BigDecimal("249.95"), TransactionStatus.SUCCESS, invoice2.getId(), Currency.USD));
    expectedInvoices.clear();
    // 
    // ADD ADD_ON (Laser-Scope has a START_OF_SUBSCRIPTION create alignment)
    // 
    addAOEntitlementAndCheckForCompletion(bpSubscription.getBundleId(), "Laser-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), new LocalDate(2012, 6, 1), InvoiceItemType.RECURRING, new BigDecimal("999.95")));
    final Invoice invoice3 = invoiceChecker.checkInvoice(account.getId(), 3, callContext, expectedInvoices);
    paymentChecker.checkPayment(account.getId(), 2, callContext, new ExpectedPaymentCheck(new LocalDate(2012, 5, 1), new BigDecimal("999.95"), TransactionStatus.SUCCESS, invoice3.getId(), Currency.USD));
    expectedInvoices.clear();
    // 
    // CANCEL BP
    // 
    cancelEntitlementAndCheckForCompletion(bpSubscription, EntitlementActionPolicy.END_OF_TERM, BillingActionPolicy.END_OF_TERM);
    // Verify we can trigger a dry-run invoice while the cancellation is pending
    final DryRunArguments dryRun = new TestDryRunArguments(DryRunType.SUBSCRIPTION_ACTION, null, null, null, null, null, SubscriptionEventType.STOP_BILLING, bpSubscription.getId(), bpSubscription.getBundleId(), null, null);
    try {
        invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), new LocalDate(2012, 6, 1), dryRun, callContext);
        fail();
    } catch (final InvoiceApiException e) {
        assertEquals(e.getCode(), INVOICE_NOTHING_TO_DO.getCode());
    }
    addMonthsAndCheckForCompletion(1, NextEvent.BLOCK, NextEvent.BLOCK, NextEvent.CANCEL, NextEvent.CANCEL, NextEvent.NULL_INVOICE, NextEvent.NULL_INVOICE);
    checkNoMoreInvoiceToGenerate(account);
}
Also used : Account(org.killbill.billing.account.api.Account) Invoice(org.killbill.billing.invoice.api.Invoice) DryRunArguments(org.killbill.billing.invoice.api.DryRunArguments) ArrayList(java.util.ArrayList) LocalDate(org.joda.time.LocalDate) ExpectedInvoiceItemCheck(org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck) BigDecimal(java.math.BigDecimal) ExpectedPaymentCheck(org.killbill.billing.beatrix.util.PaymentChecker.ExpectedPaymentCheck) InvoiceApiException(org.killbill.billing.invoice.api.InvoiceApiException) AccountData(org.killbill.billing.account.api.AccountData) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) Test(org.testng.annotations.Test)

Example 5 with DryRunArguments

use of org.killbill.billing.invoice.api.DryRunArguments 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);
}
Also used : PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) Account(org.killbill.billing.account.api.Account) Invoice(org.killbill.billing.invoice.api.Invoice) DryRunArguments(org.killbill.billing.invoice.api.DryRunArguments) ArrayList(java.util.ArrayList) LocalDate(org.joda.time.LocalDate) ExpectedInvoiceItemCheck(org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck) BigDecimal(java.math.BigDecimal) DefaultEntitlementSpecifier(org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier) UUID(java.util.UUID) Entitlement(org.killbill.billing.entitlement.api.Entitlement) Test(org.testng.annotations.Test)

Aggregations

DryRunArguments (org.killbill.billing.invoice.api.DryRunArguments)16 LocalDate (org.joda.time.LocalDate)12 Account (org.killbill.billing.account.api.Account)11 Invoice (org.killbill.billing.invoice.api.Invoice)11 Test (org.testng.annotations.Test)10 BigDecimal (java.math.BigDecimal)8 ArrayList (java.util.ArrayList)8 UUID (java.util.UUID)8 ExpectedInvoiceItemCheck (org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck)8 DefaultEntitlement (org.killbill.billing.entitlement.api.DefaultEntitlement)7 InvoiceApiException (org.killbill.billing.invoice.api.InvoiceApiException)6 PlanPhaseSpecifier (org.killbill.billing.catalog.api.PlanPhaseSpecifier)5 DefaultEntitlementSpecifier (org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier)5 Entitlement (org.killbill.billing.entitlement.api.Entitlement)4 DateTime (org.joda.time.DateTime)3 SubscriptionBase (org.killbill.billing.subscription.api.SubscriptionBase)3 DefaultSubscriptionBase (org.killbill.billing.subscription.api.user.DefaultSubscriptionBase)3 CallContext (org.killbill.billing.util.callcontext.CallContext)3 ApiOperation (io.swagger.annotations.ApiOperation)2 ApiResponses (io.swagger.annotations.ApiResponses)2