Search in sources :

Example 1 with WithAccountLock

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

the class DefaultInvoiceUserApi method insertCreditForInvoice.

private InvoiceItem insertCreditForInvoice(final UUID accountId, final UUID invoiceId, final BigDecimal amount, final LocalDate effectiveDate, final Currency currency, final boolean autoCommit, final String description, final CallContext context) throws InvoiceApiException {
    if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
        throw new InvoiceApiException(ErrorCode.CREDIT_AMOUNT_INVALID, amount);
    }
    final WithAccountLock withAccountLock = new WithAccountLock() {

        private InvoiceItem creditItem;

        @Override
        public List<Invoice> prepareInvoices() throws InvoiceApiException {
            final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(accountId, context);
            final LocalDate invoiceDate = internalTenantContext.toLocalDate(context.getCreatedDate());
            // Create an invoice for that credit if it doesn't exist
            final Invoice invoiceForCredit;
            if (invoiceId == null) {
                final InvoiceStatus status = autoCommit ? InvoiceStatus.COMMITTED : InvoiceStatus.DRAFT;
                invoiceForCredit = new DefaultInvoice(accountId, invoiceDate, effectiveDate, currency, status);
            } else {
                invoiceForCredit = getInvoiceAndCheckCurrency(invoiceId, currency, context);
                if (InvoiceStatus.COMMITTED.equals(invoiceForCredit.getStatus())) {
                    throw new InvoiceApiException(ErrorCode.INVOICE_ALREADY_COMMITTED, invoiceId);
                }
            }
            // Create the new credit
            creditItem = new CreditAdjInvoiceItem(UUIDs.randomUUID(), context.getCreatedDate(), invoiceForCredit.getId(), accountId, effectiveDate, description, // Note! The amount is negated here!
            amount.negate(), currency);
            invoiceForCredit.addInvoiceItem(creditItem);
            return ImmutableList.<Invoice>of(invoiceForCredit);
        }
    };
    final Collection<InvoiceItem> creditInvoiceItems = Collections2.<InvoiceItem>filter(invoiceApiHelper.dispatchToInvoicePluginsAndInsertItems(accountId, false, withAccountLock, context), new Predicate<InvoiceItem>() {

        @Override
        public boolean apply(final InvoiceItem invoiceItem) {
            return InvoiceItemType.CREDIT_ADJ.equals(invoiceItem.getInvoiceItemType());
        }
    });
    Preconditions.checkState(creditInvoiceItems.size() == 1, "Should have created a single credit invoice item: " + creditInvoiceItems);
    return creditInvoiceItems.iterator().next();
}
Also used : InvoiceApiException(org.killbill.billing.invoice.api.InvoiceApiException) 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) InternalTenantContext(org.killbill.billing.callcontext.InternalTenantContext) CreditAdjInvoiceItem(org.killbill.billing.invoice.model.CreditAdjInvoiceItem) WithAccountLock(org.killbill.billing.invoice.api.WithAccountLock) LocalDate(org.joda.time.LocalDate) InvoiceStatus(org.killbill.billing.invoice.api.InvoiceStatus) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice)

Example 2 with WithAccountLock

use of org.killbill.billing.invoice.api.WithAccountLock 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 3 with WithAccountLock

use of org.killbill.billing.invoice.api.WithAccountLock 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 4 with WithAccountLock

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

the class DefaultInvoiceInternalApi method recordRefund.

@Override
public InvoicePayment recordRefund(final UUID paymentId, final BigDecimal amount, final boolean isInvoiceAdjusted, final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts, final String transactionExternalKey, final InternalCallContext context) throws InvoiceApiException {
    if (amount.compareTo(BigDecimal.ZERO) <= 0) {
        throw new InvoiceApiException(ErrorCode.PAYMENT_REFUND_AMOUNT_NEGATIVE_OR_NULL, paymentId, amount);
    }
    final InvoicePaymentModelDao refund = dao.createRefund(paymentId, amount, isInvoiceAdjusted, invoiceItemIdsWithAmounts, transactionExternalKey, context);
    // See https://github.com/killbill/killbill/issues/265
    final CallContext callContext = internalCallContextFactory.createCallContext(context);
    final Invoice invoice = getInvoiceById(refund.getInvoiceId(), context);
    final UUID accountId = invoice.getAccountId();
    final WithAccountLock withAccountLock = new WithAccountLock() {

        @Override
        public Iterable<Invoice> prepareInvoices() throws InvoiceApiException {
            return ImmutableList.<Invoice>of(invoice);
        }
    };
    final List<InvoiceItem> createdInvoiceItems = invoiceApiHelper.dispatchToInvoicePluginsAndInsertItems(accountId, false, withAccountLock, callContext);
    return new DefaultInvoicePayment(refund);
}
Also used : InvoicePaymentModelDao(org.killbill.billing.invoice.dao.InvoicePaymentModelDao) InvoiceApiException(org.killbill.billing.invoice.api.InvoiceApiException) Invoice(org.killbill.billing.invoice.api.Invoice) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice) InvoiceItem(org.killbill.billing.invoice.api.InvoiceItem) WithAccountLock(org.killbill.billing.invoice.api.WithAccountLock) UUID(java.util.UUID) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) CallContext(org.killbill.billing.util.callcontext.CallContext) DefaultInvoicePayment(org.killbill.billing.invoice.model.DefaultInvoicePayment)

Aggregations

Invoice (org.killbill.billing.invoice.api.Invoice)4 InvoiceApiException (org.killbill.billing.invoice.api.InvoiceApiException)4 InvoiceItem (org.killbill.billing.invoice.api.InvoiceItem)4 WithAccountLock (org.killbill.billing.invoice.api.WithAccountLock)4 DefaultInvoice (org.killbill.billing.invoice.model.DefaultInvoice)4 CreditAdjInvoiceItem (org.killbill.billing.invoice.model.CreditAdjInvoiceItem)3 ExternalChargeInvoiceItem (org.killbill.billing.invoice.model.ExternalChargeInvoiceItem)3 HtmlInvoice (org.killbill.billing.invoice.template.HtmlInvoice)3 UUID (java.util.UUID)2 LocalDate (org.joda.time.LocalDate)2 InternalTenantContext (org.killbill.billing.callcontext.InternalTenantContext)2 InvoiceStatus (org.killbill.billing.invoice.api.InvoiceStatus)2 HashMap (java.util.HashMap)1 InternalCallContext (org.killbill.billing.callcontext.InternalCallContext)1 Currency (org.killbill.billing.catalog.api.Currency)1 InvoicePaymentModelDao (org.killbill.billing.invoice.dao.InvoicePaymentModelDao)1 DefaultInvoicePayment (org.killbill.billing.invoice.model.DefaultInvoicePayment)1 CallContext (org.killbill.billing.util.callcontext.CallContext)1