killbill-memoizeit

invoice: refactor invoice item adjustment in DefaultInvoiceDao This

8/1/2012 8:26:11 PM

Details

diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
index 0de61e7..c3a5cd5 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
@@ -453,7 +453,7 @@ public class DefaultInvoiceDao implements InvoiceDao {
 
                 // Note! The amount is negated here!
                 final InvoiceItem credit = new CreditAdjInvoiceItem(invoiceIdForCredit, accountId, effectiveDate, positiveCreditAmount.negate(), currency);
-                createItemAndAddCBAIfNeeded(transactional, credit, context);
+                insertItemAndAddCBAIfNeeded(transactional, credit, context);
                 return credit;
             }
         });
@@ -466,28 +466,9 @@ public class DefaultInvoiceDao implements InvoiceDao {
         return invoiceSqlDao.inTransaction(new Transaction<InvoiceItem, InvoiceSqlDao>() {
             @Override
             public InvoiceItem inTransaction(final InvoiceSqlDao transactional, final TransactionStatus status) throws Exception {
-                // First, retrieve the invoice item in question
-                final InvoiceItemSqlDao invoiceItemSqlDao = transactional.become(InvoiceItemSqlDao.class);
-                final InvoiceItem invoiceItemToBeAdjusted = invoiceItemSqlDao.getById(invoiceItemId.toString());
-                if (invoiceItemToBeAdjusted == null) {
-                    throw new InvoiceApiException(ErrorCode.INVOICE_ITEM_NOT_FOUND, invoiceItemId);
-                }
-
-                // Validate the invoice it belongs to
-                if (!invoiceItemToBeAdjusted.getInvoiceId().equals(invoiceId)) {
-                    throw new InvoiceApiException(ErrorCode.INVOICE_INVALID_FOR_INVOICE_ITEM_ADJUSTMENT, invoiceItemId, invoiceId);
-                }
-
-                // Retrieve the amount and currency if needed
-                final BigDecimal amountToRefund = Objects.firstNonNull(positiveAdjAmount, invoiceItemToBeAdjusted.getAmount());
-                // TODO - should we enforce the currency (and respect the original one) here if the amount passed was null?
-                final Currency currencyForAdjustment = Objects.firstNonNull(currency, invoiceItemToBeAdjusted.getCurrency());
-
-                // Finally, create the adjustment
-                // Note! The amount is negated here!
-                final InvoiceItem invoiceItemAdjustment = new ItemAdjInvoiceItem(invoiceItemToBeAdjusted, effectiveDate,
-                                                                                 amountToRefund.negate(), currencyForAdjustment);
-                createItemAndAddCBAIfNeeded(transactional, invoiceItemAdjustment, context);
+                final InvoiceItem invoiceItemAdjustment = createAdjustmentItem(transactional, invoiceId, invoiceItemId, positiveAdjAmount,
+                                                                               currency, effectiveDate);
+                insertItemAndAddCBAIfNeeded(transactional, invoiceItemAdjustment, context);
                 return invoiceItemAdjustment;
             }
         });
@@ -499,25 +480,70 @@ public class DefaultInvoiceDao implements InvoiceDao {
     }
 
     /**
+     * Create an adjustment for a given invoice item. This just creates the object in memory, it doesn't write it to disk.
+     *
+     * @param invoiceId         the invoice id
+     * @param invoiceItemId     the invoice item id to adjust
+     * @param effectiveDate     adjustment effective date, in the account timezone
+     * @param positiveAdjAmount the amount to adjust. Pass null to adjust the full amount of the original item
+     * @param currency          the currency of the amount. Pass null to default to the original currency used
+     * @return the adjustment item
+     */
+    private InvoiceItem createAdjustmentItem(final InvoiceSqlDao transactional, final UUID invoiceId, final UUID invoiceItemId,
+                                             final BigDecimal positiveAdjAmount, final Currency currency, final LocalDate effectiveDate) throws InvoiceApiException {// First, retrieve the invoice item in question
+        final InvoiceItemSqlDao invoiceItemSqlDao = transactional.become(InvoiceItemSqlDao.class);
+        final InvoiceItem invoiceItemToBeAdjusted = invoiceItemSqlDao.getById(invoiceItemId.toString());
+        if (invoiceItemToBeAdjusted == null) {
+            throw new InvoiceApiException(ErrorCode.INVOICE_ITEM_NOT_FOUND, invoiceItemId);
+        }
+
+        // Validate the invoice it belongs to
+        if (!invoiceItemToBeAdjusted.getInvoiceId().equals(invoiceId)) {
+            throw new InvoiceApiException(ErrorCode.INVOICE_INVALID_FOR_INVOICE_ITEM_ADJUSTMENT, invoiceItemId, invoiceId);
+        }
+
+        // Retrieve the amount and currency if needed
+        final BigDecimal amountToRefund = Objects.firstNonNull(positiveAdjAmount, invoiceItemToBeAdjusted.getAmount());
+        // TODO - should we enforce the currency (and respect the original one) here if the amount passed was null?
+        final Currency currencyForAdjustment = Objects.firstNonNull(currency, invoiceItemToBeAdjusted.getCurrency());
+
+        // Finally, create the adjustment
+        // Note! The amount is negated here!
+        return new ItemAdjInvoiceItem(invoiceItemToBeAdjusted, effectiveDate, amountToRefund.negate(), currencyForAdjustment);
+    }
+
+    /**
      * Create an invoice item and adjust the invoice with a CBA item if the new invoice balance is negative.
      *
      * @param transactional the InvoiceSqlDao
      * @param item          the invoice item to create
      * @param context       the call context
      */
-    private void createItemAndAddCBAIfNeeded(final InvoiceSqlDao transactional, final InvoiceItem item, final CallContext context) {
+    private void insertItemAndAddCBAIfNeeded(final InvoiceSqlDao transactional, final InvoiceItem item, final CallContext context) {
         final InvoiceItemSqlDao transInvoiceItemDao = transactional.become(InvoiceItemSqlDao.class);
         transInvoiceItemDao.create(item, context);
 
-        final Invoice invoice = transactional.getById(item.getInvoiceId().toString());
+        addCBAIfNeeded(transactional, item.getInvoiceId(), context);
+    }
+
+    /**
+     * Adjust the invoice with a CBA item if the new invoice balance is negative.
+     *
+     * @param transactional the InvoiceSqlDao
+     * @param invoiceId     the invoice id to adjust
+     * @param context       the call context
+     */
+    private void addCBAIfNeeded(final InvoiceSqlDao transactional, final UUID invoiceId, final CallContext context) {
+        final Invoice invoice = transactional.getById(invoiceId.toString());
         if (invoice != null) {
             populateChildren(invoice, transactional);
         } else {
-            throw new IllegalStateException("Invoice shouldn't be null for this item at this stage " + item.getInvoiceId());
+            throw new IllegalStateException("Invoice shouldn't be null for this item at this stage " + invoiceId);
         }
 
         // If invoice balance becomes negative we add some CBA item
         if (invoice.getBalance().compareTo(BigDecimal.ZERO) < 0) {
+            final InvoiceItemSqlDao transInvoiceItemDao = transactional.become(InvoiceItemSqlDao.class);
             final InvoiceItem cbaAdjItem = new CreditBalanceAdjInvoiceItem(invoice.getId(), invoice.getAccountId(), context.getCreatedDate().toLocalDate(),
                                                                            invoice.getBalance().negate(), invoice.getCurrency());
             transInvoiceItemDao.create(cbaAdjItem, context);