Search in sources :

Example 1 with DryRunFutureDateArguments

use of org.killbill.billing.invoice.TestInvoiceHelper.DryRunFutureDateArguments in project killbill by killbill.

the class TestInvoiceDispatcher method testWithParking.

@Test(groups = "slow")
public void testWithParking() throws InvoiceApiException, AccountApiException, CatalogApiException, SubscriptionBaseApiException, TagDefinitionApiException {
    final UUID accountId = account.getId();
    final BillingEventSet events = new MockBillingEventSet();
    final Plan plan = MockPlan.createBicycleNoTrialEvergreen1USD();
    final PlanPhase planPhase = MockPlanPhase.create1USDMonthlyEvergreen();
    final DateTime effectiveDate = clock.getUTCNow().minusDays(1);
    final Currency currency = Currency.USD;
    final BigDecimal fixedPrice = null;
    events.add(invoiceUtil.createMockBillingEvent(account, subscription, effectiveDate, plan, planPhase, fixedPrice, BigDecimal.ONE, currency, BillingPeriod.MONTHLY, 1, BillingMode.IN_ADVANCE, "", 1L, SubscriptionBaseTransitionType.CREATE));
    Mockito.when(billingApi.getBillingEventsForAccountAndUpdateAccountBCD(Mockito.<UUID>any(), Mockito.<DryRunArguments>any(), Mockito.<LocalDate>any(), Mockito.<InternalCallContext>any())).thenReturn(events);
    final LocalDate target = internalCallContext.toLocalDate(effectiveDate);
    final InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountApi, billingApi, subscriptionApi, invoiceDao, internalCallContextFactory, invoicePluginDispatcher, locker, bus, notificationQueueService, invoiceConfig, clock, invoiceOptimizer, parkedAccountsManager);
    // Verify initial tags state for account
    Assert.assertTrue(tagUserApi.getTagsForAccount(accountId, true, callContext).isEmpty());
    // Create chaos on disk
    final InvoiceModelDao invoiceModelDao = new InvoiceModelDao(accountId, target, target, currency, false);
    final InvoiceItemModelDao invoiceItemModelDao1 = new InvoiceItemModelDao(clock.getUTCNow(), InvoiceItemType.RECURRING, invoiceModelDao.getId(), accountId, subscription.getBundleId(), subscription.getId(), "Bad data", null, plan.getName(), planPhase.getName(), null, null, effectiveDate.toLocalDate(), effectiveDate.plusMonths(1).toLocalDate(), BigDecimal.TEN, BigDecimal.ONE, currency, null);
    final InvoiceItemModelDao invoiceItemModelDao2 = new InvoiceItemModelDao(clock.getUTCNow(), InvoiceItemType.RECURRING, invoiceModelDao.getId(), accountId, subscription.getBundleId(), subscription.getId(), "Bad data", null, plan.getName(), planPhase.getName(), null, null, effectiveDate.plusDays(1).toLocalDate(), effectiveDate.plusMonths(1).toLocalDate(), BigDecimal.TEN, BigDecimal.ONE, currency, null);
    invoiceModelDao.addInvoiceItem(invoiceItemModelDao1);
    invoiceModelDao.addInvoiceItem(invoiceItemModelDao2);
    invoiceDao.createInvoices(ImmutableList.<InvoiceModelDao>of(invoiceModelDao), events, ImmutableSet.of(), context);
    try {
        dispatcher.processAccountFromNotificationOrBusEvent(accountId, target, new DryRunFutureDateArguments(), false, context);
        Assert.fail();
    } catch (final InvoiceApiException e) {
        Assert.assertEquals(e.getCode(), ErrorCode.UNEXPECTED_ERROR.getCode());
        Assert.assertTrue(e.getCause().getMessage().startsWith("Double billing detected"));
    }
    // Dry-run: no side effect on disk
    Assert.assertEquals(invoiceDao.getInvoicesByAccount(false, context).size(), 1);
    Assert.assertTrue(tagUserApi.getTagsForAccount(accountId, true, callContext).isEmpty());
    try {
        dispatcher.processAccountFromNotificationOrBusEvent(accountId, target, null, false, context);
        Assert.fail();
    } catch (final InvoiceApiException e) {
        Assert.assertEquals(e.getCode(), ErrorCode.UNEXPECTED_ERROR.getCode());
        Assert.assertTrue(e.getCause().getMessage().startsWith("Double billing detected"));
    }
    Assert.assertEquals(invoiceDao.getInvoicesByAccount(false, context).size(), 1);
    // No dry-run: account is parked
    final List<Tag> tags = tagUserApi.getTagsForAccount(accountId, false, callContext);
    Assert.assertEquals(tags.size(), 1);
    Assert.assertEquals(tags.get(0).getTagDefinitionId(), SystemTags.PARK_TAG_DEFINITION_ID);
    // isApiCall=false
    final Invoice nullInvoice1 = dispatcher.processAccountFromNotificationOrBusEvent(accountId, target, null, false, context);
    Assert.assertNull(nullInvoice1);
    // No dry-run and isApiCall=true
    try {
        dispatcher.processAccount(true, accountId, target, null, false, context);
        Assert.fail();
    } catch (final InvoiceApiException e) {
        Assert.assertEquals(e.getCode(), ErrorCode.UNEXPECTED_ERROR.getCode());
        Assert.assertTrue(e.getCause().getMessage().startsWith("Double billing detected"));
    }
    // Idempotency
    Assert.assertEquals(invoiceDao.getInvoicesByAccount(false, context).size(), 1);
    Assert.assertEquals(tagUserApi.getTagsForAccount(accountId, false, callContext), tags);
    // Fix state
    dbi.withHandle(new HandleCallback<Void>() {

        @Override
        public Void withHandle(final Handle handle) throws Exception {
            handle.execute("delete from invoices");
            handle.execute("delete from invoice_items");
            return null;
        }
    });
    // Dry-run and isApiCall=false: still parked
    final Invoice nullInvoice2 = dispatcher.processAccountFromNotificationOrBusEvent(accountId, target, new DryRunFutureDateArguments(), false, context);
    Assert.assertNull(nullInvoice2);
    // Dry-run and isApiCall=true: call goes through
    final Invoice invoice1 = dispatcher.processAccount(true, accountId, target, new DryRunFutureDateArguments(), false, context);
    Assert.assertNotNull(invoice1);
    Assert.assertEquals(invoiceDao.getInvoicesByAccount(false, context).size(), 0);
    // Dry-run: still parked
    Assert.assertEquals(tagUserApi.getTagsForAccount(accountId, false, callContext).size(), 1);
    // No dry-run and isApiCall=true: call goes through
    final Invoice invoice2 = dispatcher.processAccount(true, accountId, target, null, false, context);
    Assert.assertNotNull(invoice2);
    Assert.assertEquals(invoiceDao.getInvoicesByAccount(false, context).size(), 1);
    // No dry-run: now unparked
    Assert.assertEquals(tagUserApi.getTagsForAccount(accountId, false, callContext).size(), 0);
    Assert.assertEquals(tagUserApi.getTagsForAccount(accountId, true, callContext).size(), 1);
}
Also used : Invoice(org.killbill.billing.invoice.api.Invoice) InvoiceModelDao(org.killbill.billing.invoice.dao.InvoiceModelDao) MockPlan(org.killbill.billing.catalog.MockPlan) Plan(org.killbill.billing.catalog.api.Plan) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) AccountApiException(org.killbill.billing.account.api.AccountApiException) InvoiceApiException(org.killbill.billing.invoice.api.InvoiceApiException) TagDefinitionApiException(org.killbill.billing.util.api.TagDefinitionApiException) SubscriptionBaseApiException(org.killbill.billing.subscription.api.user.SubscriptionBaseApiException) Handle(org.skife.jdbi.v2.Handle) InvoiceApiException(org.killbill.billing.invoice.api.InvoiceApiException) InvoiceItemModelDao(org.killbill.billing.invoice.dao.InvoiceItemModelDao) BillingEventSet(org.killbill.billing.junction.BillingEventSet) Currency(org.killbill.billing.catalog.api.Currency) DryRunFutureDateArguments(org.killbill.billing.invoice.TestInvoiceHelper.DryRunFutureDateArguments) PlanPhase(org.killbill.billing.catalog.api.PlanPhase) MockPlanPhase(org.killbill.billing.catalog.MockPlanPhase) Tag(org.killbill.billing.util.tag.Tag) UUID(java.util.UUID) Test(org.testng.annotations.Test)

Example 2 with DryRunFutureDateArguments

use of org.killbill.billing.invoice.TestInvoiceHelper.DryRunFutureDateArguments in project killbill by killbill.

the class TestDefaultInvoiceUserApi method testAdjustPartialInvoiceItem.

private void testAdjustPartialInvoiceItem(final boolean recurring) throws Exception {
    final Account account = invoiceUtil.createAccount(callContext);
    final UUID accountId = account.getId();
    final BigDecimal fixedPrice = recurring ? null : BigDecimal.ONE;
    final BigDecimal recurringPrice = !recurring ? null : BigDecimal.ONE;
    final UUID invoiceId = invoiceUtil.generateRegularInvoice(account, fixedPrice, recurringPrice, null, callContext);
    final InvoiceItem invoiceItem = invoiceUserApi.getInvoice(invoiceId, callContext).getInvoiceItems().get(0);
    // Verify we picked a non zero item
    Assert.assertEquals(invoiceItem.getAmount().compareTo(BigDecimal.ZERO), 1);
    // Verify the initial invoice balance
    final BigDecimal invoiceBalance = invoiceUserApi.getInvoice(invoiceId, callContext).getBalance();
    Assert.assertEquals(invoiceBalance.compareTo(BigDecimal.ZERO), 1);
    // Verify the initial account balance
    final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId, callContext);
    Assert.assertEquals(accountBalance, invoiceBalance);
    // Adjust the invoice with most of the amount (-1 cent)
    final BigDecimal adjAmount = invoiceItem.getAmount().subtract(new BigDecimal("0.01"));
    final InvoiceItem adjInvoiceItem = invoiceUserApi.insertInvoiceItemAdjustment(accountId, invoiceId, invoiceItem.getId(), clock.getUTCToday(), adjAmount, accountCurrency, null, null, null, callContext);
    Assert.assertEquals(adjInvoiceItem.getInvoiceId(), invoiceId);
    Assert.assertEquals(adjInvoiceItem.getInvoiceItemType(), InvoiceItemType.ITEM_ADJ);
    Assert.assertEquals(adjInvoiceItem.getAccountId(), accountId);
    Assert.assertEquals(adjInvoiceItem.getAmount(), adjAmount.negate());
    Assert.assertEquals(adjInvoiceItem.getCurrency(), accountCurrency);
    Assert.assertEquals(adjInvoiceItem.getLinkedItemId(), invoiceItem.getId());
    // Verify the adjusted invoice balance
    final BigDecimal adjustedInvoiceBalance = invoiceUserApi.getInvoice(invoiceId, callContext).getBalance();
    verifyAdjustedInvoiceBalance(invoiceBalance, adjAmount, accountCurrency, adjustedInvoiceBalance);
    // Verify the adjusted account balance
    final BigDecimal adjustedAccountBalance = invoiceUserApi.getAccountBalance(accountId, callContext);
    Assert.assertEquals(adjustedAccountBalance, adjustedInvoiceBalance);
    // Verify future invoice generation
    invoiceUtil.generateInvoice(account.getId(), null, new DryRunFutureDateArguments(), internalCallContext);
// Invoice may or may not be generated, but there is no exception
}
Also used : Account(org.killbill.billing.account.api.Account) TaxInvoiceItem(org.killbill.billing.invoice.model.TaxInvoiceItem) InvoiceItem(org.killbill.billing.invoice.api.InvoiceItem) ExternalChargeInvoiceItem(org.killbill.billing.invoice.model.ExternalChargeInvoiceItem) CreditAdjInvoiceItem(org.killbill.billing.invoice.model.CreditAdjInvoiceItem) DryRunFutureDateArguments(org.killbill.billing.invoice.TestInvoiceHelper.DryRunFutureDateArguments) UUID(java.util.UUID) BigDecimal(java.math.BigDecimal)

Example 3 with DryRunFutureDateArguments

use of org.killbill.billing.invoice.TestInvoiceHelper.DryRunFutureDateArguments in project killbill by killbill.

the class TestInvoiceDispatcher method testDryRunInvoice.

@Test(groups = "slow")
public void testDryRunInvoice() throws InvoiceApiException, AccountApiException, CatalogApiException, SubscriptionBaseApiException {
    final UUID accountId = account.getId();
    final BillingEventSet events = new MockBillingEventSet();
    final Plan plan = MockPlan.createBicycleNoTrialEvergreen1USD();
    final PlanPhase planPhase = MockPlanPhase.create1USDMonthlyEvergreen();
    final DateTime effectiveDate = clock.getUTCNow().minusDays(1);
    final Currency currency = Currency.USD;
    final BigDecimal fixedPrice = null;
    events.add(invoiceUtil.createMockBillingEvent(account, subscription, effectiveDate, plan, planPhase, fixedPrice, BigDecimal.ONE, currency, BillingPeriod.MONTHLY, 1, BillingMode.IN_ADVANCE, "", 1L, SubscriptionBaseTransitionType.CREATE));
    Mockito.when(billingApi.getBillingEventsForAccountAndUpdateAccountBCD(Mockito.<UUID>any(), Mockito.<DryRunArguments>any(), Mockito.<LocalDate>any(), Mockito.<InternalCallContext>any())).thenReturn(events);
    final LocalDate target = internalCallContext.toLocalDate(effectiveDate);
    final InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountApi, billingApi, subscriptionApi, invoiceDao, internalCallContextFactory, invoicePluginDispatcher, locker, bus, notificationQueueService, invoiceConfig, clock, invoiceOptimizer, parkedAccountsManager);
    Invoice invoice = dispatcher.processAccountFromNotificationOrBusEvent(accountId, target, new DryRunFutureDateArguments(), false, context);
    Assert.assertNotNull(invoice);
    List<InvoiceModelDao> invoices = invoiceDao.getInvoicesByAccount(false, context);
    Assert.assertEquals(invoices.size(), 0);
    // Try it again to double check
    invoice = dispatcher.processAccountFromNotificationOrBusEvent(accountId, target, new DryRunFutureDateArguments(), false, context);
    Assert.assertNotNull(invoice);
    invoices = invoiceDao.getInvoicesByAccount(false, context);
    Assert.assertEquals(invoices.size(), 0);
    // This time no dry run
    invoice = dispatcher.processAccountFromNotificationOrBusEvent(accountId, target, null, false, context);
    Assert.assertNotNull(invoice);
    invoices = invoiceDao.getInvoicesByAccount(false, context);
    Assert.assertEquals(invoices.size(), 1);
}
Also used : Invoice(org.killbill.billing.invoice.api.Invoice) InvoiceModelDao(org.killbill.billing.invoice.dao.InvoiceModelDao) MockPlan(org.killbill.billing.catalog.MockPlan) Plan(org.killbill.billing.catalog.api.Plan) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) BillingEventSet(org.killbill.billing.junction.BillingEventSet) Currency(org.killbill.billing.catalog.api.Currency) DryRunFutureDateArguments(org.killbill.billing.invoice.TestInvoiceHelper.DryRunFutureDateArguments) PlanPhase(org.killbill.billing.catalog.api.PlanPhase) MockPlanPhase(org.killbill.billing.catalog.MockPlanPhase) UUID(java.util.UUID) Test(org.testng.annotations.Test)

Aggregations

BigDecimal (java.math.BigDecimal)3 UUID (java.util.UUID)3 DryRunFutureDateArguments (org.killbill.billing.invoice.TestInvoiceHelper.DryRunFutureDateArguments)3 DateTime (org.joda.time.DateTime)2 LocalDate (org.joda.time.LocalDate)2 MockPlan (org.killbill.billing.catalog.MockPlan)2 MockPlanPhase (org.killbill.billing.catalog.MockPlanPhase)2 Currency (org.killbill.billing.catalog.api.Currency)2 Plan (org.killbill.billing.catalog.api.Plan)2 PlanPhase (org.killbill.billing.catalog.api.PlanPhase)2 Invoice (org.killbill.billing.invoice.api.Invoice)2 InvoiceModelDao (org.killbill.billing.invoice.dao.InvoiceModelDao)2 BillingEventSet (org.killbill.billing.junction.BillingEventSet)2 Test (org.testng.annotations.Test)2 Account (org.killbill.billing.account.api.Account)1 AccountApiException (org.killbill.billing.account.api.AccountApiException)1 CatalogApiException (org.killbill.billing.catalog.api.CatalogApiException)1 InvoiceApiException (org.killbill.billing.invoice.api.InvoiceApiException)1 InvoiceItem (org.killbill.billing.invoice.api.InvoiceItem)1 InvoiceItemModelDao (org.killbill.billing.invoice.dao.InvoiceItemModelDao)1