Search in sources :

Example 1 with InvoicePluginApi

use of org.killbill.billing.invoice.plugin.api.InvoicePluginApi in project killbill by killbill.

the class InvoicePluginDispatcher method getAdditionalInvoiceItems.

//
// If we have multiple plugins there is a question of plugin ordering and also a 'product' questions to decide whether
// subsequent plugins should have access to items added by previous plugins
//
public List<InvoiceItem> getAdditionalInvoiceItems(final Invoice originalInvoice, final boolean isDryRun, final CallContext callContext) throws InvoiceApiException {
    // We clone the original invoice so plugins don't remove/add items
    final Invoice clonedInvoice = (Invoice) ((DefaultInvoice) originalInvoice).clone();
    final List<InvoiceItem> additionalInvoiceItems = new LinkedList<InvoiceItem>();
    final List<InvoicePluginApi> invoicePlugins = getInvoicePlugins();
    for (final InvoicePluginApi invoicePlugin : invoicePlugins) {
        final List<InvoiceItem> items = invoicePlugin.getAdditionalInvoiceItems(clonedInvoice, isDryRun, ImmutableList.<PluginProperty>of(), callContext);
        if (items != null) {
            for (final InvoiceItem item : items) {
                validateInvoiceItemFromPlugin(item, invoicePlugin);
                additionalInvoiceItems.add(item);
            }
        }
    }
    return additionalInvoiceItems;
}
Also used : InvoicePluginApi(org.killbill.billing.invoice.plugin.api.InvoicePluginApi) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice) Invoice(org.killbill.billing.invoice.api.Invoice) InvoiceItem(org.killbill.billing.invoice.api.InvoiceItem) LinkedList(java.util.LinkedList)

Example 2 with InvoicePluginApi

use of org.killbill.billing.invoice.plugin.api.InvoicePluginApi in project killbill by killbill.

the class InvoicePluginDispatcher method getInvoicePlugins.

@VisibleForTesting
Map<String, InvoicePluginApi> getInvoicePlugins(final InternalTenantContext tenantContext) {
    final Collection<String> resultingPluginList = getResultingPluginNameList(tenantContext);
    // Keys ordering matters!
    final Map<String, InvoicePluginApi> invoicePlugins = new LinkedHashMap<String, InvoicePluginApi>();
    for (final String name : resultingPluginList) {
        final InvoicePluginApi serviceForName = pluginRegistry.getServiceForName(name);
        invoicePlugins.put(name, serviceForName);
    }
    return invoicePlugins;
}
Also used : InvoicePluginApi(org.killbill.billing.invoice.plugin.api.InvoicePluginApi) LinkedHashMap(java.util.LinkedHashMap) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 3 with InvoicePluginApi

use of org.killbill.billing.invoice.plugin.api.InvoicePluginApi in project killbill by killbill.

the class InvoicePluginDispatcher method onCompletionCall.

private void onCompletionCall(final boolean isSuccess, final LocalDate targetDate, @Nullable final DefaultInvoice originalInvoice, final List<Invoice> existingInvoices, final boolean isDryRun, final boolean isRescheduled, final CallContext callContext, // The pluginProperties list passed to plugins is mutable by the plugins
@SuppressWarnings("TypeMayBeWeakened") final LinkedList<PluginProperty> properties, final InternalTenantContext internalTenantContext) {
    final Collection<InvoicePluginApi> invoicePlugins = getInvoicePlugins(internalTenantContext).values();
    if (invoicePlugins.isEmpty()) {
        return;
    }
    // We clone the original invoice so plugins don't remove/add items
    final Invoice clonedInvoice = originalInvoice == null ? null : (Invoice) originalInvoice.clone();
    final InvoiceContext invoiceContext = new DefaultInvoiceContext(targetDate, clonedInvoice, existingInvoices, isDryRun, isRescheduled, callContext);
    for (final InvoicePluginApi invoicePlugin : invoicePlugins) {
        if (isSuccess) {
            invoicePlugin.onSuccessCall(invoiceContext, properties);
        } else {
            invoicePlugin.onFailureCall(invoiceContext, properties);
        }
    }
}
Also used : InvoicePluginApi(org.killbill.billing.invoice.plugin.api.InvoicePluginApi) InvoiceContext(org.killbill.billing.invoice.plugin.api.InvoiceContext) DefaultInvoiceContext(org.killbill.billing.invoice.api.DefaultInvoiceContext) Invoice(org.killbill.billing.invoice.api.Invoice) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice) DefaultInvoiceContext(org.killbill.billing.invoice.api.DefaultInvoiceContext)

Example 4 with InvoicePluginApi

use of org.killbill.billing.invoice.plugin.api.InvoicePluginApi in project killbill by killbill.

the class InvoicePluginDispatcher method updateOriginalInvoiceWithPluginInvoiceItems.

public boolean updateOriginalInvoiceWithPluginInvoiceItems(final DefaultInvoice originalInvoice, final boolean isDryRun, final CallContext callContext, // The pluginProperties list passed to plugins is mutable by the plugins
@SuppressWarnings("TypeMayBeWeakened") final LinkedList<PluginProperty> properties, final InternalTenantContext tenantContext) throws InvoiceApiException {
    log.debug("Invoking invoice plugins getAdditionalInvoiceItems: isDryRun='{}', originalInvoice='{}'", isDryRun, originalInvoice);
    final Collection<InvoicePluginApi> invoicePlugins = getInvoicePlugins(tenantContext).values();
    if (invoicePlugins.isEmpty()) {
        return false;
    }
    // Look-up map for performance
    final Map<UUID, InvoiceItem> invoiceItemsByItemId = new HashMap<UUID, InvoiceItem>();
    for (final InvoiceItem invoiceItem : originalInvoice.getInvoiceItems()) {
        invoiceItemsByItemId.put(invoiceItem.getId(), invoiceItem);
    }
    boolean invoiceUpdated = false;
    for (final InvoicePluginApi invoicePlugin : invoicePlugins) {
        // We clone the original invoice so plugins don't remove/add items
        final Invoice clonedInvoice = (Invoice) originalInvoice.clone();
        final List<InvoiceItem> additionalInvoiceItemsForPlugin = invoicePlugin.getAdditionalInvoiceItems(clonedInvoice, isDryRun, properties, callContext);
        if (additionalInvoiceItemsForPlugin != null && !additionalInvoiceItemsForPlugin.isEmpty()) {
            final Collection<InvoiceItem> additionalInvoiceItems = new LinkedList<InvoiceItem>();
            for (final InvoiceItem additionalInvoiceItem : additionalInvoiceItemsForPlugin) {
                final InvoiceItem sanitizedInvoiceItem = validateAndSanitizeInvoiceItemFromPlugin(originalInvoice.getId(), invoiceItemsByItemId, additionalInvoiceItem, invoicePlugin);
                additionalInvoiceItems.add(sanitizedInvoiceItem);
            }
            invoiceUpdated = updateOriginalInvoiceWithPluginInvoiceItems(originalInvoice, additionalInvoiceItems) || invoiceUpdated;
        }
    }
    return invoiceUpdated;
}
Also used : InvoicePluginApi(org.killbill.billing.invoice.plugin.api.InvoicePluginApi) FixedPriceInvoiceItem(org.killbill.billing.invoice.model.FixedPriceInvoiceItem) UsageInvoiceItem(org.killbill.billing.invoice.model.UsageInvoiceItem) RecurringInvoiceItem(org.killbill.billing.invoice.model.RecurringInvoiceItem) TaxInvoiceItem(org.killbill.billing.invoice.model.TaxInvoiceItem) InvoiceItem(org.killbill.billing.invoice.api.InvoiceItem) ExternalChargeInvoiceItem(org.killbill.billing.invoice.model.ExternalChargeInvoiceItem) Invoice(org.killbill.billing.invoice.api.Invoice) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) UUID(java.util.UUID) LinkedList(java.util.LinkedList)

Example 5 with InvoicePluginApi

use of org.killbill.billing.invoice.plugin.api.InvoicePluginApi in project killbill by killbill.

the class InvoicePluginDispatcher method priorCall.

public DateTime priorCall(final LocalDate targetDate, final List<Invoice> existingInvoices, final boolean isDryRun, final boolean isRescheduled, final CallContext callContext, // The pluginProperties list passed to plugins is mutable by the plugins
@SuppressWarnings("TypeMayBeWeakened") final LinkedList<PluginProperty> properties, final InternalTenantContext internalTenantContext) throws InvoiceApiException {
    log.debug("Invoking invoice plugins priorCall: targetDate='{}', isDryRun='{}', isRescheduled='{}'", targetDate, isDryRun, isRescheduled);
    final Map<String, InvoicePluginApi> invoicePlugins = getInvoicePlugins(internalTenantContext);
    if (invoicePlugins.isEmpty()) {
        return null;
    }
    DateTime earliestRescheduleDate = null;
    final InvoiceContext invoiceContext = new DefaultInvoiceContext(targetDate, null, existingInvoices, isDryRun, isRescheduled, callContext);
    for (final Entry<String, InvoicePluginApi> entry : invoicePlugins.entrySet()) {
        final String invoicePluginName = entry.getKey();
        final PriorInvoiceResult priorInvoiceResult = entry.getValue().priorCall(invoiceContext, properties);
        log.debug("Invoice plugin {} returned priorInvoiceResult='{}'", invoicePluginName, priorInvoiceResult);
        if (priorInvoiceResult == null) {
            // Naughty plugin...
            continue;
        }
        if (priorInvoiceResult.getRescheduleDate() != null && (earliestRescheduleDate == null || earliestRescheduleDate.compareTo(priorInvoiceResult.getRescheduleDate()) > 0)) {
            earliestRescheduleDate = priorInvoiceResult.getRescheduleDate();
            log.info("Invoice plugin {} rescheduled invoice generation to {} for targetDate {}", invoicePluginName, earliestRescheduleDate, targetDate);
        }
        if (priorInvoiceResult.isAborted()) {
            log.info("Invoice plugin {} aborted invoice generation for targetDate {}", invoicePluginName, targetDate);
            throw new InvoiceApiException(ErrorCode.INVOICE_PLUGIN_API_ABORTED, invoicePluginName);
        }
    }
    return earliestRescheduleDate;
}
Also used : InvoicePluginApi(org.killbill.billing.invoice.plugin.api.InvoicePluginApi) InvoiceContext(org.killbill.billing.invoice.plugin.api.InvoiceContext) DefaultInvoiceContext(org.killbill.billing.invoice.api.DefaultInvoiceContext) InvoiceApiException(org.killbill.billing.invoice.api.InvoiceApiException) DefaultInvoiceContext(org.killbill.billing.invoice.api.DefaultInvoiceContext) PriorInvoiceResult(org.killbill.billing.invoice.plugin.api.PriorInvoiceResult) DateTime(org.joda.time.DateTime)

Aggregations

InvoicePluginApi (org.killbill.billing.invoice.plugin.api.InvoicePluginApi)5 Invoice (org.killbill.billing.invoice.api.Invoice)3 DefaultInvoice (org.killbill.billing.invoice.model.DefaultInvoice)3 LinkedHashMap (java.util.LinkedHashMap)2 LinkedList (java.util.LinkedList)2 DefaultInvoiceContext (org.killbill.billing.invoice.api.DefaultInvoiceContext)2 InvoiceItem (org.killbill.billing.invoice.api.InvoiceItem)2 InvoiceContext (org.killbill.billing.invoice.plugin.api.InvoiceContext)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 HashMap (java.util.HashMap)1 UUID (java.util.UUID)1 DateTime (org.joda.time.DateTime)1 InvoiceApiException (org.killbill.billing.invoice.api.InvoiceApiException)1 ExternalChargeInvoiceItem (org.killbill.billing.invoice.model.ExternalChargeInvoiceItem)1 FixedPriceInvoiceItem (org.killbill.billing.invoice.model.FixedPriceInvoiceItem)1 RecurringInvoiceItem (org.killbill.billing.invoice.model.RecurringInvoiceItem)1 TaxInvoiceItem (org.killbill.billing.invoice.model.TaxInvoiceItem)1 UsageInvoiceItem (org.killbill.billing.invoice.model.UsageInvoiceItem)1 PriorInvoiceResult (org.killbill.billing.invoice.plugin.api.PriorInvoiceResult)1