Search in sources :

Example 26 with InvoiceItem

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

the class TestPaymentHelper method createTestInvoice.

public Invoice createTestInvoice(final Account account, final LocalDate targetDate, final Currency currency, final InvoiceItem... items) throws EventBusException, InvoiceApiException {
    final Invoice invoice = new MockInvoice(account.getId(), clock.getUTCToday(), targetDate, currency);
    for (final InvoiceItem item : items) {
        if (item instanceof MockRecurringInvoiceItem) {
            final MockRecurringInvoiceItem recurringInvoiceItem = (MockRecurringInvoiceItem) item;
            invoice.addInvoiceItem(new MockRecurringInvoiceItem(invoice.getId(), account.getId(), recurringInvoiceItem.getBundleId(), recurringInvoiceItem.getSubscriptionId(), recurringInvoiceItem.getPlanName(), recurringInvoiceItem.getPhaseName(), null, recurringInvoiceItem.getStartDate(), recurringInvoiceItem.getEndDate(), recurringInvoiceItem.getAmount(), recurringInvoiceItem.getRate(), recurringInvoiceItem.getCurrency()));
        }
    }
    Mockito.when(invoiceApi.getInvoiceById(Mockito.eq(invoice.getId()), Mockito.<InternalTenantContext>any())).thenReturn(invoice);
    Mockito.when(invoiceApi.getInvoiceForPaymentId(Mockito.<UUID>any(), Mockito.<InternalCallContext>any())).thenReturn(invoice);
    final InvoiceCreationInternalEvent event = new MockInvoiceCreationEvent(invoice.getId(), invoice.getAccountId(), invoice.getBalance(), invoice.getCurrency(), invoice.getInvoiceDate(), internalCallContext.getAccountRecordId(), internalCallContext.getTenantRecordId(), null);
    eventBus.post(event);
    return invoice;
}
Also used : Invoice(org.killbill.billing.invoice.api.Invoice) InvoiceItem(org.killbill.billing.invoice.api.InvoiceItem) InvoiceCreationInternalEvent(org.killbill.billing.events.InvoiceCreationInternalEvent)

Example 27 with InvoiceItem

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

the class TestBundleTransfer method testBundleTransferWithBPAnnualOnly.

@Test(groups = "slow")
public void testBundleTransferWithBPAnnualOnly() throws Exception {
    // Set clock to the initial start date - we implicitly assume here that the account timezone is UTC
    final DateTime initialDate = new DateTime(2012, 4, 1, 0, 15, 42, 0, testTimeZone);
    clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
    final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(3));
    final String productName = "Shotgun";
    final BillingPeriod term = BillingPeriod.ANNUAL;
    final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
    //
    // CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE, NextEvent.BLOCK NextEvent.INVOICE
    //
    final DefaultEntitlement bpEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey", productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
    assertNotNull(bpEntitlement);
    assertEquals(invoiceUserApi.getInvoicesByAccount(account.getId(), false, callContext).size(), 1);
    assertEquals(bpEntitlement.getSubscriptionBase().getCurrentPlan().getRecurringBillingPeriod(), BillingPeriod.ANNUAL);
    // Move out of trials for interesting invoices adjustments
    busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    clock.addDays(40);
    assertListenerStatus();
    // BUNDLE TRANSFER
    final Account newAccount = createAccountWithNonOsgiPaymentMethod(getAccountData(17));
    busHandler.pushExpectedEvents(NextEvent.TRANSFER, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    transferApi.transferBundle(account.getId(), newAccount.getId(), "externalKey", clock.getUTCNow(), false, false, callContext);
    assertListenerStatus();
    final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(newAccount.getId(), false, callContext);
    assertEquals(invoices.size(), 1);
    final List<InvoiceItem> invoiceItems = invoices.get(0).getInvoiceItems();
    assertEquals(invoiceItems.size(), 1);
    final InvoiceItem theItem = invoiceItems.get(0);
    assertTrue(theItem.getStartDate().compareTo(new LocalDate(2012, 5, 11)) == 0);
    assertTrue(theItem.getEndDate().compareTo(new LocalDate(2013, 5, 11)) == 0);
    assertTrue(theItem.getAmount().compareTo(new BigDecimal("2399.9500")) == 0);
    checkNoMoreInvoiceToGenerate(account);
}
Also used : Account(org.killbill.billing.account.api.Account) Invoice(org.killbill.billing.invoice.api.Invoice) InvoiceItem(org.killbill.billing.invoice.api.InvoiceItem) BillingPeriod(org.killbill.billing.catalog.api.BillingPeriod) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) Test(org.testng.annotations.Test)

Example 28 with InvoiceItem

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

the class TestBundleTransfer method testBundleTransferWithBPMonthlyOnly.

@Test(groups = "slow")
public void testBundleTransferWithBPMonthlyOnly() throws Exception {
    // Set clock to the initial start date - we implicitly assume here that the account timezone is UTC
    final DateTime initialDate = new DateTime(2012, 4, 1, 0, 15, 42, 0, testTimeZone);
    clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
    final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(0));
    final String productName = "Shotgun";
    final BillingPeriod term = BillingPeriod.MONTHLY;
    final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
    //
    // CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE, NextEvent.BLOCK NextEvent.INVOICE
    //
    final DefaultEntitlement bpEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey", productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
    assertNotNull(bpEntitlement);
    assertListenerStatus();
    assertEquals(invoiceUserApi.getInvoicesByAccount(account.getId(), false, callContext).size(), 1);
    assertEquals(bpEntitlement.getSubscriptionBase().getCurrentPlan().getRecurringBillingPeriod(), BillingPeriod.MONTHLY);
    // Move out of trials for interesting invoices adjustments
    busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    clock.addDays(32);
    assertListenerStatus();
    // BUNDLE TRANSFER
    final Account newAccount = createAccountWithNonOsgiPaymentMethod(getAccountData(0));
    busHandler.pushExpectedEvents(NextEvent.TRANSFER, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    transferApi.transferBundle(account.getId(), newAccount.getId(), "externalKey", clock.getUTCNow(), false, false, callContext);
    assertListenerStatus();
    // Verify the BCD of the new account
    final Integer oldBCD = accountUserApi.getAccountById(account.getId(), callContext).getBillCycleDayLocal();
    final Integer newBCD = accountUserApi.getAccountById(newAccount.getId(), callContext).getBillCycleDayLocal();
    assertEquals(oldBCD, (Integer) 1);
    // Day of the transfer
    assertEquals(newBCD, (Integer) 3);
    final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(newAccount.getId(), false, callContext);
    assertEquals(invoices.size(), 1);
    final List<InvoiceItem> invoiceItems = invoices.get(0).getInvoiceItems();
    assertEquals(invoiceItems.size(), 1);
    final InvoiceItem theItem = invoiceItems.get(0);
    assertTrue(theItem.getStartDate().compareTo(new LocalDate(2012, 5, 3)) == 0);
    assertTrue(theItem.getEndDate().compareTo(new LocalDate(2012, 6, 3)) == 0);
    assertTrue(theItem.getAmount().compareTo(new BigDecimal("249.95")) == 0);
    checkNoMoreInvoiceToGenerate(account);
}
Also used : Account(org.killbill.billing.account.api.Account) Invoice(org.killbill.billing.invoice.api.Invoice) InvoiceItem(org.killbill.billing.invoice.api.InvoiceItem) BillingPeriod(org.killbill.billing.catalog.api.BillingPeriod) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) Test(org.testng.annotations.Test)

Example 29 with InvoiceItem

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

the class TestIntegrationParentInvoice method testParentInvoiceGeneration.

@Test(groups = "slow")
public void testParentInvoiceGeneration() 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 parentAccount = createAccountWithNonOsgiPaymentMethod(getAccountData(billingDay));
    final Account child1Account = createAccountWithNonOsgiPaymentMethod(getChildAccountData(billingDay, parentAccount.getId(), true));
    final Account child2Account = createAccountWithNonOsgiPaymentMethod(getChildAccountData(billingDay, parentAccount.getId(), true));
    // CREATE SUBSCRIPTIONS AND EXPECT BOTH EVENTS EACH: NextEvent.CREATE NextEvent.INVOICE
    createBaseEntitlementAndCheckForCompletion(child1Account.getId(), "bundleKey1", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
    createBaseEntitlementAndCheckForCompletion(child2Account.getId(), "bundleKey2", "Pistol", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
    // First Parent invoice over TRIAL period
    List<Invoice> parentInvoices = invoiceUserApi.getInvoicesByAccount(parentAccount.getId(), false, callContext);
    assertEquals(parentInvoices.size(), 1);
    Invoice parentInvoice = parentInvoices.get(0);
    assertEquals(parentInvoice.getNumberOfItems(), 2);
    assertEquals(parentInvoice.getStatus(), InvoiceStatus.DRAFT);
    assertTrue(parentInvoice.isParentInvoice());
    assertEquals(parentInvoice.getBalance().compareTo(BigDecimal.ZERO), 0);
    // Moving a day the NotificationQ calls the commitInvoice. No payment is expected
    busHandler.pushExpectedEvents(NextEvent.INVOICE);
    clock.addDays(1);
    assertListenerStatus();
    // reload parent invoice
    parentInvoice = invoiceUserApi.getInvoice(parentInvoice.getId(), callContext);
    assertEquals(parentInvoice.getStatus(), InvoiceStatus.COMMITTED);
    // Move through time and verify new parent Invoice. No payments are expected yet.
    busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.INVOICE);
    clock.addDays(29);
    assertListenerStatus();
    // Second Parent invoice over Recurring period
    parentInvoices = invoiceUserApi.getInvoicesByAccount(parentAccount.getId(), false, callContext);
    assertEquals(parentInvoices.size(), 2);
    parentInvoice = parentInvoices.get(1);
    assertEquals(parentInvoice.getNumberOfItems(), 2);
    assertEquals(parentInvoice.getStatus(), InvoiceStatus.DRAFT);
    assertTrue(parentInvoice.isParentInvoice());
    // balance is 0 because parent invoice status is DRAFT
    assertEquals(parentInvoice.getBalance().compareTo(BigDecimal.ZERO), 0);
    // total 279.95
    assertEquals(parentInvoice.getInvoiceItems().get(0).getInvoiceItemType(), InvoiceItemType.PARENT_SUMMARY);
    assertEquals(parentInvoice.getInvoiceItems().get(0).getAmount().compareTo(BigDecimal.valueOf(249.95)), 0);
    assertEquals(parentInvoice.getInvoiceItems().get(1).getInvoiceItemType(), InvoiceItemType.PARENT_SUMMARY);
    assertEquals(parentInvoice.getInvoiceItems().get(1).getAmount().compareTo(BigDecimal.valueOf(29.95)), 0);
    // Check Child Balance. It should be > 0 here because Parent invoice is unpaid yet.
    List<Invoice> child1Invoices = invoiceUserApi.getInvoicesByAccount(child1Account.getId(), false, callContext);
    assertEquals(child1Invoices.size(), 2);
    // child balance is 0 because parent invoice status is DRAFT at this point
    assertEquals(child1Invoices.get(1).getBalance().compareTo(BigDecimal.ZERO), 0);
    // Moving a day the NotificationQ calls the commitInvoice. Payment is expected.
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    clock.addDays(1);
    assertListenerStatus();
    parentInvoice = invoiceUserApi.getInvoice(parentInvoice.getId(), callContext);
    assertEquals(parentInvoice.getStatus(), InvoiceStatus.COMMITTED);
    // Check Child Balance. It should be = 0 because parent invoice had already paid.
    child1Invoices = invoiceUserApi.getInvoicesByAccount(child1Account.getId(), false, callContext);
    assertEquals(child1Invoices.size(), 2);
    assertTrue(parentInvoice.getBalance().compareTo(BigDecimal.ZERO) == 0);
    assertTrue(child1Invoices.get(1).getBalance().compareTo(BigDecimal.ZERO) == 0);
    // load children invoice items
    final List<InvoiceItem> childrenInvoiceItems = invoiceUserApi.getInvoiceItemsByParentInvoice(parentInvoice.getId(), callContext);
    assertEquals(childrenInvoiceItems.size(), 2);
    assertEquals(childrenInvoiceItems.get(0).getAccountId(), child1Account.getId());
    assertEquals(childrenInvoiceItems.get(0).getAmount().compareTo(BigDecimal.valueOf(249.95)), 0);
    assertEquals(childrenInvoiceItems.get(1).getAccountId(), child2Account.getId());
    assertEquals(childrenInvoiceItems.get(1).getAmount().compareTo(BigDecimal.valueOf(29.95)), 0);
    // loading children items from non parent account should return empty list
    assertEquals(invoiceUserApi.getInvoiceItemsByParentInvoice(child1Invoices.get(1).getId(), callContext).size(), 0);
}
Also used : DefaultAccount(org.killbill.billing.account.api.DefaultAccount) Account(org.killbill.billing.account.api.Account) Invoice(org.killbill.billing.invoice.api.Invoice) InvoiceItem(org.killbill.billing.invoice.api.InvoiceItem) DateTime(org.joda.time.DateTime) Test(org.testng.annotations.Test)

Example 30 with InvoiceItem

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

the class DefaultInvoiceGenerator method generateInvoice.

/*
     * adjusts target date to the maximum invoice target date, if future invoices exist
     */
@Override
public InvoiceWithMetadata generateInvoice(final ImmutableAccountData account, @Nullable final BillingEventSet events, @Nullable final List<Invoice> existingInvoices, final LocalDate targetDate, final Currency targetCurrency, final InternalCallContext context) throws InvoiceApiException {
    if ((events == null) || (events.size() == 0) || events.isAccountAutoInvoiceOff()) {
        return new InvoiceWithMetadata(null, ImmutableMap.<UUID, SubscriptionFutureNotificationDates>of());
    }
    validateTargetDate(targetDate, context);
    final LocalDate adjustedTargetDate = adjustTargetDate(existingInvoices, targetDate);
    final LocalDate invoiceDate = context.toLocalDate(context.getCreatedDate());
    final DefaultInvoice invoice = new DefaultInvoice(account.getId(), invoiceDate, adjustedTargetDate, targetCurrency);
    final UUID invoiceId = invoice.getId();
    final Map<UUID, SubscriptionFutureNotificationDates> perSubscriptionFutureNotificationDates = new HashMap<UUID, SubscriptionFutureNotificationDates>();
    final List<InvoiceItem> fixedAndRecurringItems = recurringInvoiceItemGenerator.generateItems(account, invoiceId, events, existingInvoices, adjustedTargetDate, targetCurrency, perSubscriptionFutureNotificationDates, context);
    invoice.addInvoiceItems(fixedAndRecurringItems);
    final List<InvoiceItem> usageItems = usageInvoiceItemGenerator.generateItems(account, invoiceId, events, existingInvoices, adjustedTargetDate, targetCurrency, perSubscriptionFutureNotificationDates, context);
    invoice.addInvoiceItems(usageItems);
    return new InvoiceWithMetadata(invoice.getInvoiceItems().isEmpty() ? null : invoice, perSubscriptionFutureNotificationDates);
}
Also used : SubscriptionFutureNotificationDates(org.killbill.billing.invoice.generator.InvoiceWithMetadata.SubscriptionFutureNotificationDates) InvoiceItem(org.killbill.billing.invoice.api.InvoiceItem) HashMap(java.util.HashMap) UUID(java.util.UUID) LocalDate(org.joda.time.LocalDate) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice)

Aggregations

InvoiceItem (org.killbill.billing.invoice.api.InvoiceItem)168 LocalDate (org.joda.time.LocalDate)118 Test (org.testng.annotations.Test)109 BigDecimal (java.math.BigDecimal)103 FixedPriceInvoiceItem (org.killbill.billing.invoice.model.FixedPriceInvoiceItem)97 RecurringInvoiceItem (org.killbill.billing.invoice.model.RecurringInvoiceItem)92 ItemAdjInvoiceItem (org.killbill.billing.invoice.model.ItemAdjInvoiceItem)79 RepairAdjInvoiceItem (org.killbill.billing.invoice.model.RepairAdjInvoiceItem)76 UUID (java.util.UUID)68 Invoice (org.killbill.billing.invoice.api.Invoice)57 DefaultInvoice (org.killbill.billing.invoice.model.DefaultInvoice)36 ExternalChargeInvoiceItem (org.killbill.billing.invoice.model.ExternalChargeInvoiceItem)32 BillingEvent (org.killbill.billing.junction.BillingEvent)27 InvoiceApiException (org.killbill.billing.invoice.api.InvoiceApiException)25 ArrayList (java.util.ArrayList)23 DateTime (org.joda.time.DateTime)23 MockPlan (org.killbill.billing.catalog.MockPlan)23 MockPlanPhase (org.killbill.billing.catalog.MockPlanPhase)23 Plan (org.killbill.billing.catalog.api.Plan)22 PlanPhase (org.killbill.billing.catalog.api.PlanPhase)21