killbill-aplcache

invoice: fix inconsistencies in invoice dates This fixes

12/14/2016 12:32:39 PM

Details

diff --git a/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java b/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
index 908e709..0baf924 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
@@ -270,6 +270,9 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
 
             @Override
             public Iterable<Invoice> prepareInvoices() throws InvoiceApiException {
+                final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(accountId, context);
+                final LocalDate invoiceDate = internalTenantContext.toLocalDate(context.getCreatedDate());
+
                 // Group all new external charges on the same invoice (per currency)
                 final Map<Currency, Invoice> newInvoicesForExternalCharges = new HashMap<Currency, Invoice>();
                 final Map<UUID, Invoice> existingInvoicesForExternalCharges = new HashMap<UUID, Invoice>();
@@ -282,7 +285,7 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
                         final Currency currency = charge.getCurrency();
                         if (newInvoicesForExternalCharges.get(currency) == null) {
                             final InvoiceStatus status = autoCommit ? InvoiceStatus.COMMITTED : InvoiceStatus.DRAFT;
-                            final Invoice newInvoiceForExternalCharge = new DefaultInvoice(accountId, effectiveDate, effectiveDate, currency, status);
+                            final Invoice newInvoiceForExternalCharge = new DefaultInvoice(accountId, invoiceDate, effectiveDate, currency, status);
                             newInvoicesForExternalCharges.put(currency, newInvoiceForExternalCharge);
                         }
                         invoiceForExternalCharge = newInvoicesForExternalCharges.get(currency);
@@ -348,11 +351,14 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
 
             @Override
             public List<Invoice> prepareInvoices() throws InvoiceApiException {
+                final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(accountId, context);
+                final LocalDate invoiceDate = internalTenantContext.toLocalDate(context.getCreatedDate());
+
                 // Create an invoice for that credit if it doesn't exist
                 final Invoice invoiceForCredit;
                 if (invoiceId == null) {
                     final InvoiceStatus status = autoCommit ? InvoiceStatus.COMMITTED : InvoiceStatus.DRAFT;
-                    invoiceForCredit = new DefaultInvoice(accountId, effectiveDate, effectiveDate, currency, status);
+                    invoiceForCredit = new DefaultInvoice(accountId, invoiceDate, effectiveDate, currency, status);
                 } else {
                     invoiceForCredit = getInvoiceAndCheckCurrency(invoiceId, currency, context);
                     if (InvoiceStatus.COMMITTED.equals(invoiceForCredit.getStatus())) {
@@ -468,9 +474,8 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
     @Override
     public UUID createMigrationInvoice(final UUID accountId, final LocalDate targetDate, final Iterable<InvoiceItem> items, final CallContext context) {
         final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(accountId, context);
-        final LocalDate createdDate = internalCallContext.toLocalDate(internalCallContext.getCreatedDate());
-        final InvoiceModelDao migrationInvoice = new InvoiceModelDao(accountId, createdDate, targetDate, items.iterator().next().getCurrency(), true);
-
+        final LocalDate invoiceDate = internalCallContext.toLocalDate(internalCallContext.getCreatedDate());
+        final InvoiceModelDao migrationInvoice = new InvoiceModelDao(accountId, invoiceDate, targetDate, items.iterator().next().getCurrency(), true);
 
         final List<InvoiceItemModelDao> itemModelDaos = ImmutableList.copyOf(Iterables.transform(items, new Function<InvoiceItem, InvoiceItemModelDao>() {
             @Override
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
index 204a0e5..fc59743 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
@@ -1120,34 +1120,41 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
 
                 // create child and parent invoices
 
-                final DateTime effectiveDate = childAccountContext.getCreatedDate();
+                final DateTime childCreatedDate = childAccountContext.getCreatedDate();
                 final BigDecimal accountCBA = getAccountCBA(childAccount.getId(), childAccountContext);
 
                 // create external charge to child account
-                final Invoice invoiceForExternalCharge = new DefaultInvoice(childAccount.getId(), effectiveDate.toLocalDate(),
-                                                                            effectiveDate.toLocalDate(),
-                                                                            childAccount.getCurrency(), InvoiceStatus.COMMITTED);
+                final LocalDate childInvoiceDate = childAccountContext.toLocalDate(childAccountContext.getCreatedDate());
+                final Invoice invoiceForExternalCharge = new DefaultInvoice(childAccount.getId(),
+                                                                            childInvoiceDate,
+                                                                            childCreatedDate.toLocalDate(),
+                                                                            childAccount.getCurrency(),
+                                                                            InvoiceStatus.COMMITTED);
                 final String chargeDescription = "Charge to move credit from child to parent account";
                 final InvoiceItem externalChargeItem = new ExternalChargeInvoiceItem(UUIDs.randomUUID(),
-                                                                                 effectiveDate,
+                                                                                 childCreatedDate,
                                                                                  invoiceForExternalCharge.getId(),
                                                                                  childAccount.getId(),
                                                                                  null,
                                                                                  chargeDescription,
-                                                                                 effectiveDate.toLocalDate(),
+                                                                                 childCreatedDate.toLocalDate(),
                                                                                  accountCBA,
                                                                                  childAccount.getCurrency());
                 invoiceForExternalCharge.addInvoiceItem(externalChargeItem);
 
                 // create credit to parent account
-                final Invoice invoiceForCredit = new DefaultInvoice(childAccount.getParentAccountId(), effectiveDate.toLocalDate(), effectiveDate.toLocalDate(),
-                                                                    childAccount.getCurrency(), InvoiceStatus.COMMITTED);
+                final LocalDate parentInvoiceDate = parentAccountContext.toLocalDate(parentAccountContext.getCreatedDate());
+                final Invoice invoiceForCredit = new DefaultInvoice(childAccount.getParentAccountId(),
+                                                                    parentInvoiceDate,
+                                                                    childCreatedDate.toLocalDate(),
+                                                                    childAccount.getCurrency(),
+                                                                    InvoiceStatus.COMMITTED);
                 final String creditDescription = "Credit migrated from child account " + childAccount.getId();
                 final InvoiceItem creditItem = new CreditAdjInvoiceItem(UUIDs.randomUUID(),
-                                                                        effectiveDate,
+                                                                        childCreatedDate,
                                                                         invoiceForCredit.getId(),
                                                                         childAccount.getParentAccountId(),
-                                                                        effectiveDate.toLocalDate(),
+                                                                        childCreatedDate.toLocalDate(),
                                                                         creditDescription,
                                                                         // Note! The amount is negated here!
                                                                         accountCBA.negate(),
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceModelDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceModelDao.java
index 589d1c7..8043b07 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceModelDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceModelDao.java
@@ -78,10 +78,6 @@ public class InvoiceModelDao extends EntityModelDaoBase implements EntityModelDa
         this(UUIDs.randomUUID(), null, accountId, null, invoiceDate, targetDate, currency, migrated, status, false);
     }
 
-    public InvoiceModelDao(final UUID accountId, final LocalDate invoiceDate, final LocalDate targetDate, final Currency currency) {
-        this(UUIDs.randomUUID(), null, accountId, null, invoiceDate, targetDate, currency, false, InvoiceStatus.COMMITTED, false);
-    }
-
     public InvoiceModelDao(final UUID accountId, final LocalDate invoiceDate, final Currency currency, final InvoiceStatus status, final boolean isParentInvoice) {
         this(UUIDs.randomUUID(), invoiceDate.toDateTimeAtCurrentTime(), accountId, null, invoiceDate, null, currency, false, status, isParentInvoice);
     }
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 f35087b..1e64bb6 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
@@ -76,7 +76,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
         validateTargetDate(targetDate, context);
         final LocalDate adjustedTargetDate = adjustTargetDate(existingInvoices, targetDate);
 
-        final LocalDate invoiceDate = context.toLocalDate(clock.getUTCNow());
+        final LocalDate invoiceDate = context.toLocalDate(context.getCreatedDate());
         final Invoice invoice = new DefaultInvoice(account.getId(), invoiceDate, adjustedTargetDate, targetCurrency);
         final UUID invoiceId = invoice.getId();
         final Map<UUID, SubscriptionFutureNotificationDates> perSubscriptionFutureNotificationDates = new HashMap<UUID, SubscriptionFutureNotificationDates>();
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 01d03b7..cd2c7da 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
@@ -723,7 +723,6 @@ public class InvoiceDispatcher {
         BigDecimal childInvoiceAmount = InvoiceCalculatorUtils.computeChildInvoiceAmount(childInvoice.getCurrency(), childInvoice.getInvoiceItems());
         InvoiceModelDao draftParentInvoice = invoiceDao.getParentDraftInvoice(account.getParentAccountId(), parentContext);
 
-        final DateTime today = clock.getNow(account.getTimeZone());
         final String description = account.getExternalKey().concat(" summary");
         if (draftParentInvoice != null) {
 
@@ -737,7 +736,7 @@ public class InvoiceDispatcher {
             }
 
             // new item when the parent invoices does not have this child item yet
-            final ParentInvoiceItem newParentInvoiceItem = new ParentInvoiceItem(UUID.randomUUID(), today, draftParentInvoice.getId(), account.getParentAccountId(), account.getId(), childInvoiceAmount, account.getCurrency(), description);
+            final ParentInvoiceItem newParentInvoiceItem = new ParentInvoiceItem(UUID.randomUUID(), context.getCreatedDate(), draftParentInvoice.getId(), account.getParentAccountId(), account.getId(), childInvoiceAmount, account.getCurrency(), description);
             draftParentInvoice.addInvoiceItem(new InvoiceItemModelDao(newParentInvoiceItem));
 
             List<InvoiceModelDao> invoices = new ArrayList<InvoiceModelDao>();
@@ -748,8 +747,9 @@ public class InvoiceDispatcher {
                 return;
             }
 
-            draftParentInvoice = new InvoiceModelDao(account.getParentAccountId(), today.toLocalDate(), account.getCurrency(), InvoiceStatus.DRAFT, true);
-            InvoiceItem parentInvoiceItem = new ParentInvoiceItem(UUID.randomUUID(), today, draftParentInvoice.getId(), account.getParentAccountId(), account.getId(), childInvoiceAmount, account.getCurrency(), description);
+            final LocalDate invoiceDate = context.toLocalDate(context.getCreatedDate());
+            draftParentInvoice = new InvoiceModelDao(account.getParentAccountId(), invoiceDate, account.getCurrency(), InvoiceStatus.DRAFT, true);
+            final InvoiceItem parentInvoiceItem = new ParentInvoiceItem(UUID.randomUUID(), context.getCreatedDate(), draftParentInvoice.getId(), account.getParentAccountId(), account.getId(), childInvoiceAmount, account.getCurrency(), description);
             draftParentInvoice.addInvoiceItem(new InvoiceItemModelDao(parentInvoiceItem));
 
             // build account date time zone
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/DefaultInvoice.java b/invoice/src/main/java/org/killbill/billing/invoice/model/DefaultInvoice.java
index 6db52ff..5b200f4 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/DefaultInvoice.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/DefaultInvoice.java
@@ -73,7 +73,6 @@ public class DefaultInvoice extends EntityBase implements Invoice, Cloneable {
         this(invoiceId, null, accountId, invoiceNumber, invoiceDate, targetDate, currency, currency, isMigrationInvoice, false, status, false, null);
     }
 
-
     // This CTOR is used to return an existing invoice and must include everything (items, payments, tags,..)
     public DefaultInvoice(final InvoiceModelDao invoiceModelDao) {
         this(invoiceModelDao.getId(), invoiceModelDao.getCreatedDate(), invoiceModelDao.getAccountId(),
@@ -95,7 +94,6 @@ public class DefaultInvoice extends EntityBase implements Invoice, Cloneable {
         }));
     }
 
-    // Used to create a new parent invoice
     public DefaultInvoice(final UUID accountId, final LocalDate invoiceDate, final Currency currency) {
         this(UUID.randomUUID(), null, accountId, null, invoiceDate, null, currency, currency, false, false, InvoiceStatus.DRAFT, true, null);
     }
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java b/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java
index b26dbbb..1bf8600 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java
@@ -818,7 +818,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
         createCredit(accountId, clock.getUTCToday(), new BigDecimal("20.0"));
 
         final String description = UUID.randomUUID().toString();
-        final InvoiceModelDao invoiceForExternalCharge = new InvoiceModelDao(accountId, clock.getUTCToday(), clock.getUTCToday(), Currency.USD);
+        final InvoiceModelDao invoiceForExternalCharge = new InvoiceModelDao(accountId, clock.getUTCToday(), clock.getUTCToday(), Currency.USD, false);
         final InvoiceItemModelDao externalCharge = new InvoiceItemModelDao(new ExternalChargeInvoiceItem(invoiceForExternalCharge.getId(), accountId, bundleId, description, clock.getUTCToday(), new BigDecimal("15.0"), Currency.USD));
         invoiceForExternalCharge.addInvoiceItem(externalCharge);
         final InvoiceItemModelDao charge = invoiceDao.createInvoices(ImmutableList.<InvoiceModelDao>of(invoiceForExternalCharge), context).get(0);
@@ -1704,7 +1704,6 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
         final InvoiceModelDao invoiceModelDao;
         if (invoiceId == null) {
             invoiceModelDao = new InvoiceModelDao(accountId, effectiveDate, effectiveDate, Currency.USD, false, InvoiceStatus.DRAFT);
-
         } else {
             invoiceModelDao = invoiceDao.getById(invoiceId, context);
         }
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/template/formatters/TestDefaultInvoiceFormatter.java b/invoice/src/test/java/org/killbill/billing/invoice/template/formatters/TestDefaultInvoiceFormatter.java
index 34b3004..f072706 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/template/formatters/TestDefaultInvoiceFormatter.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/template/formatters/TestDefaultInvoiceFormatter.java
@@ -366,7 +366,7 @@ public class TestDefaultInvoiceFormatter extends InvoiceTestSuiteNoDB {
     public void testProcessedCurrencyExists() throws Exception {
 
         // Use InvoiceModelDao to build the invoice to be able to set the processedCurrency (No suitable CTOR for DefaultInvoice on purpose)
-        final InvoiceModelDao invoiceModelDao = new InvoiceModelDao(UUID.randomUUID(), new LocalDate(), new LocalDate(), Currency.BRL);
+        final InvoiceModelDao invoiceModelDao = new InvoiceModelDao(UUID.randomUUID(), new LocalDate(), new LocalDate(), Currency.BRL, false);
         invoiceModelDao.setProcessedCurrency(Currency.USD);
 
         final Invoice invoice = new DefaultInvoice(invoiceModelDao);