diff --git a/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java b/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java
index fa8da71..a46c4d0 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2019 Groupon, Inc
+ * Copyright 2014-2019 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -19,7 +19,6 @@
package org.killbill.billing.invoice.generator;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -34,7 +33,6 @@ import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.invoice.api.Invoice;
import org.killbill.billing.invoice.api.InvoiceApiException;
-import org.killbill.billing.invoice.api.InvoiceItem;
import org.killbill.billing.invoice.api.InvoiceStatus;
import org.killbill.billing.invoice.generator.InvoiceItemGenerator.InvoiceGeneratorResult;
import org.killbill.billing.invoice.generator.InvoiceWithMetadata.SubscriptionFutureNotificationDates;
@@ -42,6 +40,8 @@ import org.killbill.billing.invoice.model.DefaultInvoice;
import org.killbill.billing.junction.BillingEventSet;
import org.killbill.billing.util.config.definition.InvoiceConfig;
import org.killbill.clock.Clock;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
@@ -52,6 +52,8 @@ import com.google.inject.Inject;
public class DefaultInvoiceGenerator implements InvoiceGenerator {
+ private static final Logger logger = LoggerFactory.getLogger(DefaultInvoiceGenerator.class);
+
private final Clock clock;
private final InvoiceConfig config;
@@ -134,6 +136,11 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
maxDate = invoice.getTargetDate();
}
}
+
+ if (targetDate.compareTo(maxDate) != 0) {
+ logger.warn("Adjusting target date from {} to {}", targetDate, maxDate);
+ }
+
return maxDate;
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java b/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
index cc874e1..cf4deb0 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
@@ -526,12 +526,12 @@ public class InvoiceDispatcher {
}
private InvoiceWithFutureNotifications processAccountWithLockAndInputTargetDate(final UUID accountId,
- final LocalDate targetDate,
- final BillingEventSet billingEvents,
- final List<Invoice> existingInvoices,
- final boolean isDryRun,
- final boolean isRescheduled,
- final InternalCallContext internalCallContext) throws InvoiceApiException {
+ final LocalDate originalTargetDate,
+ final BillingEventSet billingEvents,
+ final List<Invoice> existingInvoices,
+ final boolean isDryRun,
+ final boolean isRescheduled,
+ final InternalCallContext internalCallContext) throws InvoiceApiException {
final CallContext callContext = buildCallContext(internalCallContext);
final ImmutableAccountData account;
@@ -539,11 +539,11 @@ public class InvoiceDispatcher {
account = accountApi.getImmutableAccountDataById(accountId, internalCallContext);
} catch (final AccountApiException e) {
log.error("Unable to generate invoice for accountId='{}', a future notification has NOT been recorded", accountId, e);
- invoicePluginDispatcher.onFailureCall(targetDate, null, existingInvoices, isDryRun, isRescheduled, callContext, ImmutableList.<PluginProperty>of(), internalCallContext);
+ invoicePluginDispatcher.onFailureCall(originalTargetDate, null, existingInvoices, isDryRun, isRescheduled, callContext, ImmutableList.<PluginProperty>of(), internalCallContext);
return null;
}
- final DateTime rescheduleDate = invoicePluginDispatcher.priorCall(targetDate, existingInvoices, isDryRun, isRescheduled, callContext, ImmutableList.<PluginProperty>of(), internalCallContext);
+ final DateTime rescheduleDate = invoicePluginDispatcher.priorCall(originalTargetDate, existingInvoices, isDryRun, isRescheduled, callContext, ImmutableList.<PluginProperty>of(), internalCallContext);
if (rescheduleDate != null) {
if (isDryRun) {
log.warn("Ignoring rescheduleDate='{}', delayed scheduling is unsupported in dry-run", rescheduleDate);
@@ -554,7 +554,7 @@ public class InvoiceDispatcher {
return null;
}
- final InvoiceWithMetadata invoiceWithMetadata = generateKillBillInvoice(account, targetDate, billingEvents, existingInvoices, internalCallContext);
+ final InvoiceWithMetadata invoiceWithMetadata = generateKillBillInvoice(account, originalTargetDate, billingEvents, existingInvoices, internalCallContext);
final DefaultInvoice invoice = invoiceWithMetadata.getInvoice();
// Compute future notifications
@@ -562,12 +562,12 @@ public class InvoiceDispatcher {
// If invoice comes back null, there is nothing new to generate, we can bail early
if (invoice == null) {
- invoicePluginDispatcher.onSuccessCall(targetDate, null, existingInvoices, isDryRun, isRescheduled, callContext, ImmutableList.<PluginProperty>of(), internalCallContext);
+ invoicePluginDispatcher.onSuccessCall(originalTargetDate, null, existingInvoices, isDryRun, isRescheduled, callContext, ImmutableList.<PluginProperty>of(), internalCallContext);
if (isDryRun) {
- log.info("Generated null dryRun invoice for accountId='{}', targetDate='{}'", accountId, targetDate);
+ log.info("Generated null dryRun invoice for accountId='{}', targetDate='{}'", accountId, originalTargetDate);
} else {
- log.info("Generated null invoice for accountId='{}', targetDate='{}'", accountId, targetDate);
+ log.info("Generated null invoice for accountId='{}', targetDate='{}'", accountId, originalTargetDate);
final BusInternalEvent event = new DefaultNullInvoiceEvent(accountId, clock.getUTCToday(),
internalCallContext.getAccountRecordId(), internalCallContext.getTenantRecordId(), internalCallContext.getUserToken());
@@ -578,6 +578,7 @@ public class InvoiceDispatcher {
return null;
}
+ final LocalDate actualTargetDate = invoice.getTargetDate();
boolean success = false;
try {
// Generate missing credit (> 0 for generation and < 0 for use) prior we call the plugin(s)
@@ -609,7 +610,7 @@ public class InvoiceDispatcher {
final boolean isRealInvoiceWithItems = uniqueInvoiceIds.remove(invoice.getId());
final Set<UUID> adjustedUniqueOtherInvoiceId = uniqueInvoiceIds;
- logInvoiceWithItems(account, invoice, targetDate, adjustedUniqueOtherInvoiceId, isRealInvoiceWithItems);
+ logInvoiceWithItems(account, invoice, actualTargetDate, adjustedUniqueOtherInvoiceId, isRealInvoiceWithItems);
// Transformation to Invoice -> InvoiceModelDao
final InvoiceModelDao invoiceModelDao = new InvoiceModelDao(invoice);
@@ -642,9 +643,9 @@ public class InvoiceDispatcher {
if (isDryRun || success) {
final DefaultInvoice refreshedInvoice = isDryRun ? invoice : new DefaultInvoice(invoiceDao.getById(invoice.getId(), internalCallContext));
- invoicePluginDispatcher.onSuccessCall(targetDate, refreshedInvoice, existingInvoices, isDryRun, isRescheduled, callContext, ImmutableList.<PluginProperty>of(),internalCallContext);
+ invoicePluginDispatcher.onSuccessCall(actualTargetDate, refreshedInvoice, existingInvoices, isDryRun, isRescheduled, callContext, ImmutableList.<PluginProperty>of(),internalCallContext);
} else {
- invoicePluginDispatcher.onFailureCall(targetDate, invoice, existingInvoices, isDryRun, isRescheduled, callContext, ImmutableList.<PluginProperty>of(), internalCallContext);
+ invoicePluginDispatcher.onFailureCall(actualTargetDate, invoice, existingInvoices, isDryRun, isRescheduled, callContext, ImmutableList.<PluginProperty>of(), internalCallContext);
}
}