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();
}
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);
}
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);
}
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);
}
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;
}
});
}
Aggregations