Search in sources :

Example 31 with InvoiceApiException

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

the class DefaultInvoiceUserApi method insertInvoiceItemAdjustment.

@Override
public InvoiceItem insertInvoiceItemAdjustment(final UUID accountId, final UUID invoiceId, final UUID invoiceItemId, final LocalDate effectiveDate, @Nullable final BigDecimal amount, @Nullable final Currency currency, final String description, final CallContext context) throws InvoiceApiException {
    if (amount != null && amount.compareTo(BigDecimal.ZERO) <= 0) {
        throw new InvoiceApiException(ErrorCode.INVOICE_ITEM_ADJUSTMENT_AMOUNT_SHOULD_BE_POSITIVE, amount);
    }
    final WithAccountLock withAccountLock = new WithAccountLock() {

        @Override
        public Iterable<Invoice> prepareInvoices() throws InvoiceApiException {
            final Invoice invoice = getInvoiceAndCheckCurrency(invoiceId, currency, context);
            final InvoiceItem adjustmentItem = invoiceApiHelper.createAdjustmentItem(invoice, invoiceItemId, amount, currency, effectiveDate, description, internalCallContextFactory.createInternalCallContext(accountId, context));
            invoice.addInvoiceItem(adjustmentItem);
            return ImmutableList.<Invoice>of(invoice);
        }
    };
    final Collection<InvoiceItem> adjustmentInvoiceItems = Collections2.<InvoiceItem>filter(invoiceApiHelper.dispatchToInvoicePluginsAndInsertItems(accountId, false, withAccountLock, context), new Predicate<InvoiceItem>() {

        @Override
        public boolean apply(final InvoiceItem invoiceItem) {
            return InvoiceItemType.ITEM_ADJ.equals(invoiceItem.getInvoiceItemType());
        }
    });
    Preconditions.checkState(adjustmentInvoiceItems.size() == 1, "Should have created a single adjustment item: " + adjustmentInvoiceItems);
    return adjustmentInvoiceItems.iterator().next();
}
Also used : InvoiceApiException(org.killbill.billing.invoice.api.InvoiceApiException) Invoice(org.killbill.billing.invoice.api.Invoice) HtmlInvoice(org.killbill.billing.invoice.template.HtmlInvoice) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice) InvoiceItem(org.killbill.billing.invoice.api.InvoiceItem) ExternalChargeInvoiceItem(org.killbill.billing.invoice.model.ExternalChargeInvoiceItem) CreditAdjInvoiceItem(org.killbill.billing.invoice.model.CreditAdjInvoiceItem) WithAccountLock(org.killbill.billing.invoice.api.WithAccountLock)

Example 32 with InvoiceApiException

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

the class DefaultInvoiceUserApi method getInvoiceByPayment.

@Override
public Invoice getInvoiceByPayment(final UUID paymentId, final TenantContext context) throws InvoiceApiException {
    final InternalTenantContext tenantContext = internalCallContextFactory.createInternalTenantContext(paymentId, ObjectType.PAYMENT, context);
    final UUID invoiceId = dao.getInvoiceIdByPaymentId(paymentId, tenantContext);
    if (invoiceId == null) {
        throw new InvoiceApiException(ErrorCode.INVOICE_NOT_FOUND, paymentId);
    }
    final InvoiceModelDao invoiceModelDao = dao.getById(invoiceId, tenantContext);
    return new DefaultInvoice(invoiceModelDao);
}
Also used : InvoiceApiException(org.killbill.billing.invoice.api.InvoiceApiException) InternalTenantContext(org.killbill.billing.callcontext.InternalTenantContext) InvoiceModelDao(org.killbill.billing.invoice.dao.InvoiceModelDao) UUID(java.util.UUID) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice)

Example 33 with InvoiceApiException

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

the class DefaultInvoiceUserApi method insertExternalCharges.

@Override
public List<InvoiceItem> insertExternalCharges(final UUID accountId, final LocalDate effectiveDate, final Iterable<InvoiceItem> charges, final boolean autoCommit, final CallContext context) throws InvoiceApiException {
    for (final InvoiceItem charge : charges) {
        if (charge.getAmount() == null || charge.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
            throw new InvoiceApiException(ErrorCode.EXTERNAL_CHARGE_AMOUNT_INVALID, charge.getAmount());
        }
    }
    final WithAccountLock withAccountLock = new WithAccountLock() {

        @Override
        public Iterable<Invoice> prepareInvoices() throws InvoiceApiException {
            final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(accountId, context);
            final LocalDate invoiceDate = internalTenantContext.toLocalDate(context.getCreatedDate());
            // Group all new external charges on the same invoice (per currency)
            final Map<Currency, Invoice> newInvoicesForExternalCharges = new HashMap<Currency, Invoice>();
            final Map<UUID, Invoice> existingInvoicesForExternalCharges = new HashMap<UUID, Invoice>();
            for (final InvoiceItem charge : charges) {
                final Invoice invoiceForExternalCharge;
                final UUID invoiceIdForExternalCharge = charge.getInvoiceId();
                // Create an invoice for that external charge if it doesn't exist
                if (invoiceIdForExternalCharge == null) {
                    final Currency currency = charge.getCurrency();
                    if (newInvoicesForExternalCharges.get(currency) == null) {
                        final InvoiceStatus status = autoCommit ? InvoiceStatus.COMMITTED : InvoiceStatus.DRAFT;
                        final Invoice newInvoiceForExternalCharge = new DefaultInvoice(accountId, invoiceDate, effectiveDate, currency, status);
                        newInvoicesForExternalCharges.put(currency, newInvoiceForExternalCharge);
                    }
                    invoiceForExternalCharge = newInvoicesForExternalCharges.get(currency);
                } else {
                    if (existingInvoicesForExternalCharges.get(invoiceIdForExternalCharge) == null) {
                        final Invoice existingInvoiceForExternalCharge = getInvoice(invoiceIdForExternalCharge, context);
                        existingInvoicesForExternalCharges.put(invoiceIdForExternalCharge, existingInvoiceForExternalCharge);
                    }
                    invoiceForExternalCharge = existingInvoicesForExternalCharges.get(invoiceIdForExternalCharge);
                }
                final InvoiceItem externalCharge = new ExternalChargeInvoiceItem(UUIDs.randomUUID(), context.getCreatedDate(), invoiceForExternalCharge.getId(), accountId, charge.getBundleId(), charge.getDescription(), effectiveDate, charge.getAmount(), charge.getCurrency());
                invoiceForExternalCharge.addInvoiceItem(externalCharge);
            }
            return Iterables.<Invoice>concat(newInvoicesForExternalCharges.values(), existingInvoicesForExternalCharges.values());
        }
    };
    return invoiceApiHelper.dispatchToInvoicePluginsAndInsertItems(accountId, false, withAccountLock, context);
}
Also used : InvoiceItem(org.killbill.billing.invoice.api.InvoiceItem) ExternalChargeInvoiceItem(org.killbill.billing.invoice.model.ExternalChargeInvoiceItem) CreditAdjInvoiceItem(org.killbill.billing.invoice.model.CreditAdjInvoiceItem) Invoice(org.killbill.billing.invoice.api.Invoice) HtmlInvoice(org.killbill.billing.invoice.template.HtmlInvoice) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice) HashMap(java.util.HashMap) WithAccountLock(org.killbill.billing.invoice.api.WithAccountLock) ExternalChargeInvoiceItem(org.killbill.billing.invoice.model.ExternalChargeInvoiceItem) LocalDate(org.joda.time.LocalDate) InvoiceApiException(org.killbill.billing.invoice.api.InvoiceApiException) InternalTenantContext(org.killbill.billing.callcontext.InternalTenantContext) Currency(org.killbill.billing.catalog.api.Currency) UUID(java.util.UUID) InvoiceStatus(org.killbill.billing.invoice.api.InvoiceStatus) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice)

Example 34 with InvoiceApiException

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

the class DefaultInvoiceUserApi method transferChildCreditToParent.

@Override
public void transferChildCreditToParent(final UUID childAccountId, final CallContext context) throws InvoiceApiException {
    final Account childAccount;
    final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(childAccountId, ObjectType.ACCOUNT, context);
    try {
        childAccount = accountUserApi.getAccountById(childAccountId, internalCallContext);
    } catch (AccountApiException e) {
        throw new InvoiceApiException(e);
    }
    if (childAccount.getParentAccountId() == null) {
        throw new InvoiceApiException(ErrorCode.ACCOUNT_DOES_NOT_HAVE_PARENT_ACCOUNT, childAccountId);
    }
    final BigDecimal accountCBA = getAccountCBA(childAccountId, context);
    if (accountCBA.compareTo(BigDecimal.ZERO) <= 0) {
        throw new InvoiceApiException(ErrorCode.CHILD_ACCOUNT_MISSING_CREDIT, childAccountId);
    }
    dao.transferChildCreditToParent(childAccount, internalCallContext);
}
Also used : Account(org.killbill.billing.account.api.Account) InvoiceApiException(org.killbill.billing.invoice.api.InvoiceApiException) AccountApiException(org.killbill.billing.account.api.AccountApiException) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) BigDecimal(java.math.BigDecimal)

Example 35 with InvoiceApiException

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

the class DefaultInvoiceDao method transferChildCreditToParent.

@Override
public void transferChildCreditToParent(final Account childAccount, final InternalCallContext childAccountContext) throws InvoiceApiException {
    // Need to create an internalCallContext for parent account because it's needed to save the correct accountRecordId in Invoice tables.
    // Then it's used to load invoices by account.
    final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(childAccount.getParentAccountId(), childAccountContext);
    final InternalCallContext parentAccountContext = internalCallContextFactory.createInternalCallContext(internalTenantContext.getAccountRecordId(), childAccountContext);
    final List<Tag> parentInvoicesTags = getInvoicesTags(parentAccountContext);
    final List<Tag> childInvoicesTags = getInvoicesTags(childAccountContext);
    transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {

        @Override
        public Void inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
            final InvoiceSqlDao invoiceSqlDao = entitySqlDaoWrapperFactory.become(InvoiceSqlDao.class);
            final InvoiceItemSqlDao transInvoiceItemSqlDao = entitySqlDaoWrapperFactory.become(InvoiceItemSqlDao.class);
            // create child and parent invoices
            final DateTime childCreatedDate = childAccountContext.getCreatedDate();
            final BigDecimal accountCBA = getAccountCBA(childAccount.getId(), childAccountContext);
            // create external charge to child account
            final LocalDate childInvoiceDate = childAccountContext.toLocalDate(childAccountContext.getCreatedDate());
            final Invoice invoiceForExternalCharge = new DefaultInvoice(childAccount.getId(), childInvoiceDate, childCreatedDate.toLocalDate(), childAccount.getCurrency(), InvoiceStatus.COMMITTED);
            final String chargeDescription = "Charge to move credit from child to parent account";
            final InvoiceItem externalChargeItem = new ExternalChargeInvoiceItem(UUIDs.randomUUID(), childCreatedDate, invoiceForExternalCharge.getId(), childAccount.getId(), null, chargeDescription, childCreatedDate.toLocalDate(), accountCBA, childAccount.getCurrency());
            invoiceForExternalCharge.addInvoiceItem(externalChargeItem);
            // create credit to parent account
            final LocalDate parentInvoiceDate = parentAccountContext.toLocalDate(parentAccountContext.getCreatedDate());
            final Invoice invoiceForCredit = new DefaultInvoice(childAccount.getParentAccountId(), parentInvoiceDate, childCreatedDate.toLocalDate(), childAccount.getCurrency(), InvoiceStatus.COMMITTED);
            final String creditDescription = "Credit migrated from child account " + childAccount.getId();
            final InvoiceItem creditItem = new CreditAdjInvoiceItem(UUIDs.randomUUID(), childCreatedDate, invoiceForCredit.getId(), childAccount.getParentAccountId(), childCreatedDate.toLocalDate(), creditDescription, // Note! The amount is negated here!
            accountCBA.negate(), childAccount.getCurrency());
            invoiceForCredit.addInvoiceItem(creditItem);
            // save invoices and invoice items
            final InvoiceModelDao childInvoice = new InvoiceModelDao(invoiceForExternalCharge);
            invoiceSqlDao.create(childInvoice, childAccountContext);
            final InvoiceItemModelDao childExternalChargeItem = new InvoiceItemModelDao(externalChargeItem);
            createInvoiceItemFromTransaction(transInvoiceItemSqlDao, childExternalChargeItem, childAccountContext);
            // Keep invoice up-to-date for CBA below
            childInvoice.addInvoiceItem(childExternalChargeItem);
            final InvoiceModelDao parentInvoice = new InvoiceModelDao(invoiceForCredit);
            invoiceSqlDao.create(parentInvoice, parentAccountContext);
            final InvoiceItemModelDao parentCreditItem = new InvoiceItemModelDao(creditItem);
            createInvoiceItemFromTransaction(transInvoiceItemSqlDao, parentCreditItem, parentAccountContext);
            // Keep invoice up-to-date for CBA below
            parentInvoice.addInvoiceItem(parentCreditItem);
            // add CBA complexity and notify bus on child invoice creation
            cbaDao.doCBAComplexityFromTransaction(childInvoice, childInvoicesTags, entitySqlDaoWrapperFactory, childAccountContext);
            notifyBusOfInvoiceCreation(entitySqlDaoWrapperFactory, childInvoice, childAccountContext);
            cbaDao.doCBAComplexityFromTransaction(parentInvoice, parentInvoicesTags, entitySqlDaoWrapperFactory, parentAccountContext);
            notifyBusOfInvoiceCreation(entitySqlDaoWrapperFactory, parentInvoice, parentAccountContext);
            return null;
        }
    });
}
Also used : Invoice(org.killbill.billing.invoice.api.Invoice) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice) InvoiceItem(org.killbill.billing.invoice.api.InvoiceItem) ExternalChargeInvoiceItem(org.killbill.billing.invoice.model.ExternalChargeInvoiceItem) CreditAdjInvoiceItem(org.killbill.billing.invoice.model.CreditAdjInvoiceItem) CreditAdjInvoiceItem(org.killbill.billing.invoice.model.CreditAdjInvoiceItem) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) ExternalChargeInvoiceItem(org.killbill.billing.invoice.model.ExternalChargeInvoiceItem) LocalDate(org.joda.time.LocalDate) InvoiceApiException(org.killbill.billing.invoice.api.InvoiceApiException) EventBusException(org.killbill.bus.api.PersistentBus.EventBusException) EntityPersistenceException(org.killbill.billing.entity.EntityPersistenceException) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) InternalTenantContext(org.killbill.billing.callcontext.InternalTenantContext) EntitySqlDaoWrapperFactory(org.killbill.billing.util.entity.dao.EntitySqlDaoWrapperFactory) Tag(org.killbill.billing.util.tag.Tag) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice)

Aggregations

InvoiceApiException (org.killbill.billing.invoice.api.InvoiceApiException)56 UUID (java.util.UUID)29 Invoice (org.killbill.billing.invoice.api.Invoice)26 InvoiceItem (org.killbill.billing.invoice.api.InvoiceItem)24 BigDecimal (java.math.BigDecimal)23 LocalDate (org.joda.time.LocalDate)23 DefaultInvoice (org.killbill.billing.invoice.model.DefaultInvoice)19 Test (org.testng.annotations.Test)16 InternalCallContext (org.killbill.billing.callcontext.InternalCallContext)14 FixedPriceInvoiceItem (org.killbill.billing.invoice.model.FixedPriceInvoiceItem)14 RecurringInvoiceItem (org.killbill.billing.invoice.model.RecurringInvoiceItem)14 LinkedList (java.util.LinkedList)13 ItemAdjInvoiceItem (org.killbill.billing.invoice.model.ItemAdjInvoiceItem)12 RepairAdjInvoiceItem (org.killbill.billing.invoice.model.RepairAdjInvoiceItem)12 BillingEventSet (org.killbill.billing.junction.BillingEventSet)9 AccountApiException (org.killbill.billing.account.api.AccountApiException)7 MockPlan (org.killbill.billing.catalog.MockPlan)7 MockPlanPhase (org.killbill.billing.catalog.MockPlanPhase)7 MockBillingEventSet (org.killbill.billing.invoice.MockBillingEventSet)7 SubscriptionFutureNotificationDates (org.killbill.billing.invoice.generator.InvoiceWithMetadata.SubscriptionFutureNotificationDates)7