use of org.killbill.billing.invoice.model.DefaultInvoice in project killbill by killbill.
the class DefaultInvoiceInternalApi method getUnpaidInvoicesByAccountId.
@Override
public Collection<Invoice> getUnpaidInvoicesByAccountId(final UUID accountId, final LocalDate upToDate, final InternalTenantContext context) {
final List<InvoiceModelDao> unpaidInvoicesByAccountId = dao.getUnpaidInvoicesByAccountId(accountId, null, upToDate, context);
final Collection<Invoice> invoices = new LinkedList<Invoice>();
for (final InvoiceModelDao invoiceModelDao : unpaidInvoicesByAccountId) {
invoices.add(new DefaultInvoice(invoiceModelDao));
}
return invoices;
}
use of org.killbill.billing.invoice.model.DefaultInvoice in project killbill by killbill.
the class DefaultInvoiceUserApi method insertItems.
private List<InvoiceItem> insertItems(final UUID accountId, final LocalDate effectiveDate, final InvoiceItemType itemType, final Iterable<InvoiceItem> inputItems, final boolean autoCommit, final LinkedList<PluginProperty> properties, final CallContext context) throws InvoiceApiException {
final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(accountId, context);
ImmutableAccountData accountData;
try {
accountData = accountUserApi.getImmutableAccountDataById(accountId, internalTenantContext);
} catch (AccountApiException e) {
throw new InvoiceApiException(e);
}
final Currency accountCurrency = accountData.getCurrency();
final WithAccountLock withAccountLock = new WithAccountLock() {
@Override
public Iterable<DefaultInvoice> prepareInvoices() throws InvoiceApiException {
final LocalDate invoiceDate = internalTenantContext.toLocalDate(context.getCreatedDate());
final Map<UUID, DefaultInvoice> newAndExistingInvoices = new HashMap<UUID, DefaultInvoice>();
UUID newInvoiceId = null;
for (final InvoiceItem inputItem : inputItems) {
if (inputItem.getAmount() == null || inputItem.getAmount().compareTo(BigDecimal.ZERO) < 0) {
if (itemType == InvoiceItemType.EXTERNAL_CHARGE) {
throw new InvoiceApiException(ErrorCode.EXTERNAL_CHARGE_AMOUNT_INVALID, inputItem.getAmount());
} else if (itemType == InvoiceItemType.CREDIT_ADJ) {
throw new InvoiceApiException(ErrorCode.CREDIT_AMOUNT_INVALID, inputItem.getAmount());
}
}
if (inputItem.getCurrency() != null && !inputItem.getCurrency().equals(accountCurrency)) {
throw new InvoiceApiException(ErrorCode.CURRENCY_INVALID, inputItem.getCurrency(), accountCurrency);
}
final UUID invoiceIdForItem = inputItem.getInvoiceId();
final Invoice curInvoiceForItem;
if (invoiceIdForItem == null) {
final Currency currency = inputItem.getCurrency();
final InvoiceStatus status = autoCommit ? InvoiceStatus.COMMITTED : InvoiceStatus.DRAFT;
if (newInvoiceId == null) {
final DefaultInvoice newInvoiceForItems = new DefaultInvoice(accountId, invoiceDate, effectiveDate, currency, status);
newInvoiceId = newInvoiceForItems.getId();
newAndExistingInvoices.put(newInvoiceId, newInvoiceForItems);
}
curInvoiceForItem = newAndExistingInvoices.get(newInvoiceId);
} else {
if (newAndExistingInvoices.get(invoiceIdForItem) == null) {
final DefaultInvoice existingInvoiceForExternalCharge = getInvoiceInternal(invoiceIdForItem, context);
switch(existingInvoiceForExternalCharge.getStatus()) {
case COMMITTED:
throw new InvoiceApiException(ErrorCode.INVOICE_ALREADY_COMMITTED, existingInvoiceForExternalCharge.getId());
case VOID:
// TODO Add missing error https://github.com/killbill/killbill/issues/1501
throw new IllegalStateException(String.format("Cannot add credit or external charge for invoice id %s because it is in \" + InvoiceStatus.VOID + \" status\"", existingInvoiceForExternalCharge.getId()));
case DRAFT:
default:
break;
}
newAndExistingInvoices.put(invoiceIdForItem, existingInvoiceForExternalCharge);
}
curInvoiceForItem = newAndExistingInvoices.get(invoiceIdForItem);
}
final InvoiceItem newInvoiceItem;
switch(itemType) {
case EXTERNAL_CHARGE:
newInvoiceItem = new ExternalChargeInvoiceItem(UUIDs.randomUUID(), context.getCreatedDate(), curInvoiceForItem.getId(), accountId, inputItem.getBundleId(), inputItem.getSubscriptionId(), inputItem.getProductName(), inputItem.getPlanName(), inputItem.getPhaseName(), inputItem.getPrettyProductName(), inputItem.getPrettyPlanName(), inputItem.getPrettyPhaseName(), inputItem.getDescription(), MoreObjects.firstNonNull(inputItem.getStartDate(), effectiveDate), inputItem.getEndDate(), inputItem.getAmount(), inputItem.getRate(), accountCurrency, inputItem.getLinkedItemId(), inputItem.getQuantity(), inputItem.getItemDetails());
break;
case CREDIT_ADJ:
newInvoiceItem = new CreditAdjInvoiceItem(UUIDs.randomUUID(), context.getCreatedDate(), curInvoiceForItem.getId(), accountId, effectiveDate, inputItem.getDescription(), // Note! The amount is negated here!
inputItem.getAmount().negate(), inputItem.getRate(), inputItem.getCurrency(), inputItem.getQuantity(), inputItem.getItemDetails());
break;
case TAX:
newInvoiceItem = new TaxInvoiceItem(UUIDs.randomUUID(), curInvoiceForItem.getId(), accountId, inputItem.getBundleId(), inputItem.getDescription(), MoreObjects.firstNonNull(inputItem.getStartDate(), effectiveDate), inputItem.getAmount(), accountCurrency);
break;
default:
throw new IllegalStateException(String.format("Unsupported to add item of type '%s'", itemType));
}
curInvoiceForItem.addInvoiceItem(newInvoiceItem);
}
return newAndExistingInvoices.values();
}
};
return invoiceApiHelper.dispatchToInvoicePluginsAndInsertItems(accountId, false, withAccountLock, properties, context);
}
use of org.killbill.billing.invoice.model.DefaultInvoice in project killbill by killbill.
the class DefaultInvoiceUserApi method tagInvoiceAsWrittenOff.
@Override
public void tagInvoiceAsWrittenOff(final UUID invoiceId, final CallContext context) throws TagApiException, InvoiceApiException {
// Note: the tagApi is audited
final InternalCallContext internalContext = internalCallContextFactory.createInternalCallContext(invoiceId, ObjectType.INVOICE, context);
tagApi.addTag(invoiceId, ObjectType.INVOICE, ControlTagType.WRITTEN_OFF.getId(), internalContext);
// Retrieve the invoice for the account id
final Invoice invoice = new DefaultInvoice(dao.getById(invoiceId, internalContext));
// This is for overdue
notifyBusOfInvoiceAdjustment(invoiceId, invoice.getAccountId(), internalContext);
}
use of org.killbill.billing.invoice.model.DefaultInvoice in project killbill by killbill.
the class DefaultInvoiceUserApi method getInvoiceByInvoiceItem.
@Override
public Invoice getInvoiceByInvoiceItem(final UUID invoiceItemId, final TenantContext context) throws InvoiceApiException {
final InternalTenantContext internalTenantContextWithoutAccountRecordId = internalCallContextFactory.createInternalTenantContextWithoutAccountRecordId(context);
final InvoiceModelDao invoice = dao.getByInvoiceItem(invoiceItemId, internalTenantContextWithoutAccountRecordId);
final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(invoice.getAccountId(), context);
return new DefaultInvoice(invoice, getCatalogSafelyForPrettyNames(internalTenantContext));
}
use of org.killbill.billing.invoice.model.DefaultInvoice 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, final AccountInvoices existingInvoices, @Nullable final UUID targetInvoiceId, final LocalDate targetDate, final Currency targetCurrency, @Nullable final DryRunInfo dryRunInfo, final InternalCallContext context) throws InvoiceApiException {
if (events == null) {
return new InvoiceWithMetadata(null, ImmutableSet.of(), ImmutableMap.<UUID, SubscriptionFutureNotificationDates>of(), false, context);
}
validateTargetDate(targetDate, context);
final LocalDate adjustedTargetDate = adjustTargetDate(existingInvoices.getInvoices(), targetDate);
final LocalDate invoiceDate = context.toLocalDate(context.getCreatedDate());
final InvoiceStatus invoiceStatus = events.isAccountAutoInvoiceDraft() ? InvoiceStatus.DRAFT : InvoiceStatus.COMMITTED;
final DefaultInvoice invoice = targetInvoiceId != null ? new DefaultInvoice(targetInvoiceId, account.getId(), null, invoiceDate, adjustedTargetDate, targetCurrency, false, invoiceStatus) : new DefaultInvoice(account.getId(), invoiceDate, adjustedTargetDate, targetCurrency, invoiceStatus);
final Map<UUID, SubscriptionFutureNotificationDates> perSubscriptionFutureNotificationDates = new HashMap<UUID, SubscriptionFutureNotificationDates>();
final InvoiceGeneratorResult fixedAndRecurringItems = recurringInvoiceItemGenerator.generateItems(account, invoice.getId(), events, existingInvoices, adjustedTargetDate, targetCurrency, perSubscriptionFutureNotificationDates, dryRunInfo, context);
invoice.addInvoiceItems(fixedAndRecurringItems.getItems());
final InvoiceGeneratorResult usageItemsWithTrackingIds = usageInvoiceItemGenerator.generateItems(account, invoice.getId(), events, existingInvoices, adjustedTargetDate, targetCurrency, perSubscriptionFutureNotificationDates, dryRunInfo, context);
invoice.addInvoiceItems(usageItemsWithTrackingIds.getItems());
if (targetInvoiceId != null) {
final Invoice originalInvoice = Iterables.find(existingInvoices.getInvoices(), new Predicate<Invoice>() {
@Override
public boolean apply(final Invoice input) {
return input.getId().equals(targetInvoiceId);
}
});
invoice.addInvoiceItems(originalInvoice.getInvoiceItems());
}
return new InvoiceWithMetadata(invoice, usageItemsWithTrackingIds.getTrackingIds(), perSubscriptionFutureNotificationDates, config.isUsageZeroAmountDisabled(context), context);
}
Aggregations