Search in sources :

Example 26 with DefaultInvoice

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;
}
Also used : Invoice(org.killbill.billing.invoice.api.Invoice) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice) InvoiceModelDao(org.killbill.billing.invoice.dao.InvoiceModelDao) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice) LinkedList(java.util.LinkedList)

Example 27 with DefaultInvoice

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);
}
Also used : ImmutableAccountData(org.killbill.billing.account.api.ImmutableAccountData) TaxInvoiceItem(org.killbill.billing.invoice.model.TaxInvoiceItem) TaxInvoiceItem(org.killbill.billing.invoice.model.TaxInvoiceItem) 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) CreditAdjInvoiceItem(org.killbill.billing.invoice.model.CreditAdjInvoiceItem) 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) AccountApiException(org.killbill.billing.account.api.AccountApiException) UUID(java.util.UUID) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice) InvoiceStatus(org.killbill.billing.invoice.api.InvoiceStatus)

Example 28 with DefaultInvoice

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);
}
Also used : Invoice(org.killbill.billing.invoice.api.Invoice) HtmlInvoice(org.killbill.billing.invoice.template.HtmlInvoice) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice)

Example 29 with DefaultInvoice

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));
}
Also used : InternalTenantContext(org.killbill.billing.callcontext.InternalTenantContext) InvoiceModelDao(org.killbill.billing.invoice.dao.InvoiceModelDao) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice)

Example 30 with DefaultInvoice

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);
}
Also used : SubscriptionFutureNotificationDates(org.killbill.billing.invoice.generator.InvoiceWithMetadata.SubscriptionFutureNotificationDates) Invoice(org.killbill.billing.invoice.api.Invoice) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice) HashMap(java.util.HashMap) UUID(java.util.UUID) InvoiceGeneratorResult(org.killbill.billing.invoice.generator.InvoiceItemGenerator.InvoiceGeneratorResult) LocalDate(org.joda.time.LocalDate) InvoiceStatus(org.killbill.billing.invoice.api.InvoiceStatus) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice)

Aggregations

DefaultInvoice (org.killbill.billing.invoice.model.DefaultInvoice)92 Invoice (org.killbill.billing.invoice.api.Invoice)81 LocalDate (org.joda.time.LocalDate)64 Test (org.testng.annotations.Test)63 UUID (java.util.UUID)51 BigDecimal (java.math.BigDecimal)46 RecurringInvoiceItem (org.killbill.billing.invoice.model.RecurringInvoiceItem)46 InvoiceItem (org.killbill.billing.invoice.api.InvoiceItem)38 FixedPriceInvoiceItem (org.killbill.billing.invoice.model.FixedPriceInvoiceItem)37 RepairAdjInvoiceItem (org.killbill.billing.invoice.model.RepairAdjInvoiceItem)28 LinkedList (java.util.LinkedList)25 HashMap (java.util.HashMap)24 ItemAdjInvoiceItem (org.killbill.billing.invoice.model.ItemAdjInvoiceItem)24 MockBillingEventSet (org.killbill.billing.invoice.MockBillingEventSet)20 AccountInvoices (org.killbill.billing.invoice.optimizer.InvoiceOptimizerBase.AccountInvoices)20 BillingEventSet (org.killbill.billing.junction.BillingEventSet)20 MockPlan (org.killbill.billing.catalog.MockPlan)18 MockPlanPhase (org.killbill.billing.catalog.MockPlanPhase)18 BillingEvent (org.killbill.billing.junction.BillingEvent)18 Plan (org.killbill.billing.catalog.api.Plan)17