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