killbill-memoizeit

Merge remote-tracking branch 'origin/invoice-rework' into

4/25/2013 7:16:06 PM

Details

diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/BeatrixIntegrationModule.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/BeatrixIntegrationModule.java
index 66f3169..df8c64a 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/BeatrixIntegrationModule.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/BeatrixIntegrationModule.java
@@ -94,7 +94,7 @@ public class BeatrixIntegrationModule extends AbstractModule {
     @Override
     protected void configure() {
 
-        loadSystemPropertiesFromClasspath("/resource.properties");
+        loadSystemPropertiesFromClasspath("/beatrix.properties");
 
         bind(Lifecycle.class).to(SubsetDefaultLifecycle.class).asEagerSingleton();
 
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
index 94f8e77..be1cbf9 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
@@ -174,16 +174,13 @@ public class TestOverdueIntegration extends TestOverdueBase {
         invoiceChecker.checkRepairedInvoice(account.getId(), 3,
                                             callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")),
                                             // We paid up to 07-31, hence the adjustment
-                                            new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-249.95")),
-                                            new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 23), new LocalDate(2012, 7, 23), InvoiceItemType.CBA_ADJ, new BigDecimal("249.95")));
+                                            new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 10), new LocalDate(2012, 7, 31), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-166.64")),
+                                            new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 23), new LocalDate(2012, 7, 23), InvoiceItemType.CBA_ADJ, new BigDecimal("166.64")));
         invoiceChecker.checkInvoice(account.getId(), 4, callContext,
-                                    // Note the end date here is not 07-25, but 07-10. The overdue configuration disabled invoicing between 07-10 and 07-23 (e.g. the bundle
-                                    // was inaccessible, hence we didn't want to charge the customer for that period, even though the account was overdue).
-                                    new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 10), InvoiceItemType.RECURRING, new BigDecimal("83.31")),
                                     // Item for the upgraded recurring plan
                                     new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 23), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("154.85")),
                                     // Credits consumed
-                                    new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 23), new LocalDate(2012, 7, 23), InvoiceItemType.CBA_ADJ, new BigDecimal("-238.16")));
+                                    new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 23), new LocalDate(2012, 7, 23), InvoiceItemType.CBA_ADJ, new BigDecimal("-154.85")));
         invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 7, 31), callContext);
 
         // Verify the account balance: 249.95 - 74.99 - 154.85
@@ -270,16 +267,13 @@ public class TestOverdueIntegration extends TestOverdueBase {
         invoiceChecker.checkRepairedInvoice(account.getId(), 3,
                                             callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")),
                                             // We paid up to 07-31, hence the adjustment
-                                            new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-249.95")),
-                                            new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 25), new LocalDate(2012, 7, 25), InvoiceItemType.CBA_ADJ, new BigDecimal("249.95")));
+                                            new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 15), new LocalDate(2012, 7, 31), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-124.97")),
+                                            new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 25), new LocalDate(2012, 7, 25), InvoiceItemType.CBA_ADJ, new BigDecimal("124.97")));
         invoiceChecker.checkInvoice(account.getId(), 4, callContext,
-                                    // Note the end date here is not 07-25, but 07-15. The overdue configuration disabled invoicing between 07-15 and 07-25 (e.g. the bundle
-                                    // was inaccessible, hence we didn't want to charge the customer for that period, even though the account was overdue).
-                                    new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 15), InvoiceItemType.RECURRING, new BigDecimal("124.98")),
                                     // Item for the upgraded recurring plan
                                     new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 25), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("116.09")),
                                     // Credits consumed
-                                    new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 25), new LocalDate(2012, 7, 25), InvoiceItemType.CBA_ADJ, new BigDecimal("-241.07")));
+                                    new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 25), new LocalDate(2012, 7, 25), InvoiceItemType.CBA_ADJ, new BigDecimal("-116.09")));
         invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 7, 31), callContext);
 
         // Verify the account balance: 249.95 - 124.98 - 116.09
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestBundleTransfer.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestBundleTransfer.java
index 2c6b654..1acafee 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestBundleTransfer.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestBundleTransfer.java
@@ -216,27 +216,22 @@ public class TestBundleTransfer extends TestIntegrationBase {
         busHandler.pushExpectedEvent(NextEvent.CANCEL);
         busHandler.pushExpectedEvent(NextEvent.TRANSFER);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
-        busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
         transferApi.transferBundle(account.getId(), newAccount.getId(), "mycutebundle", clock.getUTCNow(), false, true, callContext);
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
 
         List<Invoice> invoices =invoiceUserApi.getInvoicesByAccount(account.getId(), callContext);
-        assertEquals(invoices.size(), 3);
+        assertEquals(invoices.size(), 2);
 
 
         // CHECK OLD ACCOUNTS ITEMS
         ImmutableList<ExpectedInvoiceItemCheck> toBeChecked = ImmutableList.<ExpectedInvoiceItemCheck>of(
                 new ExpectedInvoiceItemCheck(new LocalDate(2012,5,1), new LocalDate(2012,5,9), InvoiceItemType.RECURRING, new BigDecimal("66.66")),
-                new ExpectedInvoiceItemCheck(new LocalDate(2012,5,1), new LocalDate(2012,5,9), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-66.66")),
-                new ExpectedInvoiceItemCheck(new LocalDate(2012,5,3), new LocalDate(2012,5,3), InvoiceItemType.CBA_ADJ, new BigDecimal("66.66")));
+                new ExpectedInvoiceItemCheck(new LocalDate(2012,5,3), new LocalDate(2012,5,9), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-49.99")),
+                new ExpectedInvoiceItemCheck(new LocalDate(2012,5,3), new LocalDate(2012,5,3), InvoiceItemType.CBA_ADJ, new BigDecimal("49.99")));
         invoiceChecker.checkInvoice(invoices.get(1).getId(), callContext, toBeChecked);
 
-        toBeChecked = ImmutableList.<ExpectedInvoiceItemCheck>of(
-                new ExpectedInvoiceItemCheck(new LocalDate(2012,5,1), new LocalDate(2012,5,3), InvoiceItemType.RECURRING, new BigDecimal("16.67")),
-                new ExpectedInvoiceItemCheck(new LocalDate(2012,5,3), new LocalDate(2012,5,3), InvoiceItemType.CBA_ADJ, new BigDecimal("-16.67")));
-        invoiceChecker.checkInvoice(invoices.get(2).getId(), callContext, toBeChecked);
 
         // CHECK NEW ACCOUNT ITEMS
         invoices =invoiceUserApi.getInvoicesByAccount(newAccount.getId(), callContext);
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestEntitlement.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestEntitlement.java
index adea394..96dc921 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestEntitlement.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestEntitlement.java
@@ -93,6 +93,7 @@ public class TestEntitlement extends TestIntegrationBase {
         busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE);
         assertTrue(bpSubscription.changePlanWithPolicy(productName, BillingPeriod.MONTHLY, planSetName, clock.getUTCNow(), ActionPolicy.IMMEDIATE, callContext));
         assertEquals(entitlementUserApi.getSubscriptionFromId(bpSubscription.getId(), callContext).getCurrentPlan().getBillingPeriod(), BillingPeriod.MONTHLY);
+
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
 
@@ -100,14 +101,13 @@ public class TestEntitlement extends TestIntegrationBase {
         assertEquals(invoices.size(), 3);
         toBeChecked = ImmutableList.<ExpectedInvoiceItemCheck>of(
                 new ExpectedInvoiceItemCheck(new LocalDate(2012,5,1), new LocalDate(2013,5,1), InvoiceItemType.RECURRING, new BigDecimal("2399.95")),
-                new ExpectedInvoiceItemCheck(new LocalDate(2012,5,1), new LocalDate(2013,5,1), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-2399.95")),
-                new ExpectedInvoiceItemCheck(new LocalDate(2012,5,11), new LocalDate(2012,5,11), InvoiceItemType.CBA_ADJ, new BigDecimal("2399.95")));
+                new ExpectedInvoiceItemCheck(new LocalDate(2012,5,11), new LocalDate(2013,5,1), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-2334.19")),
+                new ExpectedInvoiceItemCheck(new LocalDate(2012,5,11), new LocalDate(2012,5,11), InvoiceItemType.CBA_ADJ, new BigDecimal("2334.19")));
         invoiceChecker.checkInvoice(invoices.get(1).getId(), callContext, toBeChecked);
 
         toBeChecked = ImmutableList.<ExpectedInvoiceItemCheck>of(
-                new ExpectedInvoiceItemCheck(new LocalDate(2012,5,1), new LocalDate(2012,5,11), InvoiceItemType.RECURRING, new BigDecimal("65.76")),
                 new ExpectedInvoiceItemCheck(new LocalDate(2012,5,11), new LocalDate(2012,6,1), InvoiceItemType.RECURRING, new BigDecimal("169.32")),
-                new ExpectedInvoiceItemCheck(new LocalDate(2012,5,11), new LocalDate(2012,5,11), InvoiceItemType.CBA_ADJ, new BigDecimal("-235.08")));
+                new ExpectedInvoiceItemCheck(new LocalDate(2012,5,11), new LocalDate(2012,5,11), InvoiceItemType.CBA_ADJ, new BigDecimal("-169.32")));
         invoiceChecker.checkInvoice(invoices.get(2).getId(), callContext, toBeChecked);
 
 
@@ -126,9 +126,8 @@ public class TestEntitlement extends TestIntegrationBase {
 
 
         toBeChecked = ImmutableList.<ExpectedInvoiceItemCheck>of(
-                new ExpectedInvoiceItemCheck(new LocalDate(2012,5,1), new LocalDate(2012,5,11), InvoiceItemType.RECURRING, new BigDecimal("65.76")),
                 new ExpectedInvoiceItemCheck(new LocalDate(2012,5,11), new LocalDate(2012,6,1), InvoiceItemType.RECURRING, new BigDecimal("169.32")),
-                new ExpectedInvoiceItemCheck(new LocalDate(2012,5,11), new LocalDate(2012,5,11), InvoiceItemType.CBA_ADJ, new BigDecimal("-235.08")),
+                new ExpectedInvoiceItemCheck(new LocalDate(2012,5,11), new LocalDate(2012,5,11), InvoiceItemType.CBA_ADJ, new BigDecimal("-169.32")),
                 new ExpectedInvoiceItemCheck(new LocalDate(2012,5,11), new LocalDate(2012,6,1), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-169.32")),
                 new ExpectedInvoiceItemCheck(new LocalDate(2012,5,11), new LocalDate(2012,5,11), InvoiceItemType.CBA_ADJ, new BigDecimal("169.32")));
         invoiceChecker.checkInvoice(invoices.get(2).getId(), callContext, toBeChecked);
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/CBADao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/CBADao.java
index a4a8b9c..2d25c6e 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/CBADao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/CBADao.java
@@ -57,10 +57,11 @@ public class CBADao {
 
     public void doCBAComplexity(final UUID accountId, final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory, final InternalCallContext context) throws EntityPersistenceException, InvoiceApiException {
 
-        final List<InvoiceModelDao> invoiceItemModelDaos = invoiceDaoHelper.getAllInvoicesByAccountFromTransaction(accountId, entitySqlDaoWrapperFactory, context);
+        List<InvoiceModelDao> invoiceItemModelDaos = invoiceDaoHelper.getAllInvoicesByAccountFromTransaction(accountId, entitySqlDaoWrapperFactory, context);
         for (InvoiceModelDao cur : invoiceItemModelDaos) {
             addCBAIfNeeded(entitySqlDaoWrapperFactory, cur, context);
         }
+        invoiceItemModelDaos = invoiceDaoHelper.getAllInvoicesByAccountFromTransaction(accountId, entitySqlDaoWrapperFactory, context);
         useExistingCBAFromTransaction(invoiceItemModelDaos, entitySqlDaoWrapperFactory, context);
     }
 
diff --git a/invoice/src/main/java/com/ning/billing/invoice/generator/DefaultInvoiceGenerator.java b/invoice/src/main/java/com/ning/billing/invoice/generator/DefaultInvoiceGenerator.java
index 19c14f2..ac10e99 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/generator/DefaultInvoiceGenerator.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/generator/DefaultInvoiceGenerator.java
@@ -19,10 +19,8 @@ package com.ning.billing.invoice.generator;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 import java.util.UUID;
 
 import javax.annotation.Nullable;
@@ -40,7 +38,6 @@ import com.ning.billing.invoice.api.InvoiceApiException;
 import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoiceItemType;
 import com.ning.billing.invoice.model.BillingMode;
-import com.ning.billing.invoice.model.CreditBalanceAdjInvoiceItem;
 import com.ning.billing.invoice.model.DefaultInvoice;
 import com.ning.billing.invoice.model.FixedPriceInvoiceItem;
 import com.ning.billing.invoice.model.InAdvanceBillingMode;
@@ -59,6 +56,37 @@ import com.google.common.base.Predicate;
 import com.google.common.collect.Collections2;
 import com.google.inject.Inject;
 
+
+/**
+ * Terminology for repair scenarii:
+ *
+ * - A 'repaired' item is an item that was generated and that needs to be repaired because the plan changed for that subscription on that period of time
+ * - The 'repair' item is the item that cancels the (to be) repaired item; the repair item amount might not match (to be) repaired item because:
+ *   * the (to be) repaired item was already adjusted so we will only repair what is left
+ *   * in case of partial repair we only repair the part that is not used
+ * - The 'reparee' item is only present on disk-- in the existing item list -- in case of full repair; in that case it represents the portion of the item that should still
+ *   be invoiced for the plan of the repaired item. In case of partial repair it is merged with the repair item and does not exist except as a virtual item in the proposed list
+ *
+ *
+ *
+ * Example. We had a 20 subscription for a given period; we charged that amount and later discovered that only 3/4 of the time period were used after which the subscription was cancelled (immediate canellation)
+ *
+ * Full repair logic:
+ *
+ * Invoice 1:                   Invoice 2:
+ *           +20 (repaired)             +5 (reparee)
+ *           -20 (repair)
+ *
+ * Partial repair logic:
+ *
+ * Invoice 1:                   Invoice 2: (N/A)
+ *           +20 (repaired)
+ *           -15 (repair)
+ *
+ * The current version of the code uses partial repair logic but is able to deal with 'full repair' scenarii.
+ *
+ */
+
 public class DefaultInvoiceGenerator implements InvoiceGenerator {
 
     private static final Logger log = LoggerFactory.getLogger(DefaultInvoiceGenerator.class);
@@ -110,52 +138,18 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
         final List<InvoiceItem> proposedItems = generateInvoiceItems(invoiceId, accountId, events, adjustedTargetDate, targetCurrency);
 
         // Remove repaired and repair items -- since they never change and can't be regenerated
-        removeRepairedAndRepairInvoiceItems(existingItems);
+        removeRepairedAndRepairInvoiceItems(existingItems, proposedItems);
 
         // Remove from both lists the items in common
-        removeMatchingInvoiceItems(proposedItems, existingItems);
+        removeMatchingInvoiceItems(existingItems, proposedItems);
 
         // Add repair items based on what is left in existing items
         addRepairItems(existingItems, proposedItems);
 
-        // Go through each invoice and if balance is negative, generate CBA of opposite amount -- which could happen if there was some repair
-        // TODO Should this be merged with existing CBA logic in the dao layer ?
-        generateCBAForExistingInvoices(accountId, existingInvoices, proposedItems, targetCurrency);
-
-        // Finally add thos new items on the new invoice
+        // Finally add this new items on the new invoice
         invoice.addInvoiceItems(proposedItems);
 
-        return proposedItems.size() != 0 ?  invoice : null;
-    }
-
-    void generateCBAForExistingInvoices(final UUID accountId, final List<Invoice> existingInvoices,
-                                        final List<InvoiceItem> proposedItems, final Currency currency) {
-        // Determine most accurate invoice balances up to this point
-        final Map<UUID, BigDecimal> amountOwedByInvoice = new HashMap<UUID, BigDecimal>();
-
-        if (existingInvoices != null) {
-            for (final Invoice invoice : existingInvoices) {
-                amountOwedByInvoice.put(invoice.getId(), invoice.getBalance());
-            }
-        }
-
-        for (final InvoiceItem item : proposedItems) {
-            final UUID invoiceId = item.getInvoiceId();
-            if (amountOwedByInvoice.containsKey(invoiceId)) {
-                amountOwedByInvoice.put(invoiceId, amountOwedByInvoice.get(invoiceId).add(item.getAmount()));
-            } else {
-                amountOwedByInvoice.put(invoiceId, item.getAmount());
-            }
-        }
-
-        for (final UUID invoiceId : amountOwedByInvoice.keySet()) {
-            final BigDecimal invoiceBalance = amountOwedByInvoice.get(invoiceId);
-            if (invoiceBalance.compareTo(BigDecimal.ZERO) < 0) {
-                final LocalDate creditDate = clock.getUTCToday();
-                final CreditBalanceAdjInvoiceItem creditInvoiceItem = new CreditBalanceAdjInvoiceItem(invoiceId, accountId, creditDate, invoiceBalance.negate(), currency);
-                proposedItems.add(creditInvoiceItem);
-            }
-        }
+        return proposedItems.size() != 0 ? invoice : null;
     }
 
     /**
@@ -171,13 +165,74 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
                 final BigDecimal existingAdjustedPositiveAmount = getAdjustedPositiveAmount(existingItems, existingItem.getId());
                 final BigDecimal amountNegated = existingItem.getAmount() == null ? null : existingItem.getAmount().subtract(existingAdjustedPositiveAmount).negate();
                 if (amountNegated != null && amountNegated.compareTo(BigDecimal.ZERO) < 0) {
-                    final RepairAdjInvoiceItem repairItem = new RepairAdjInvoiceItem(existingItem.getInvoiceId(), existingItem.getAccountId(), existingItem.getStartDate(), existingItem.getEndDate(), amountNegated, existingItem.getCurrency(), existingItem.getId());
-                    proposedItems.add(repairItem);
+                    final RepairAdjInvoiceItem candidateRepairItem = new RepairAdjInvoiceItem(existingItem.getInvoiceId(), existingItem.getAccountId(), existingItem.getStartDate(), existingItem.getEndDate(), amountNegated, existingItem.getCurrency(), existingItem.getId());
+                    addRepairItem(existingItem, candidateRepairItem, proposedItems);
                 }
             }
         }
     }
 
+    /**
+     * Add the repair item for the (yet to be) repairedItem. It will merge the candidateRepairItem with reparee item
+     *
+     * @param repairedItem        the item being repaired
+     * @param candidateRepairItem the repair item we would have if we were to repair the full period
+     * @param proposedItems       the list of proposed items
+     */
+    void addRepairItem(final InvoiceItem repairedItem, final RepairAdjInvoiceItem candidateRepairItem, final List<InvoiceItem> proposedItems) {
+
+        final boolean withPartialRepair = true; // (System.getProperty("InvoiceWithPartialRepair") != null);
+
+        if (!withPartialRepair) {
+            proposedItems.add(candidateRepairItem);
+            return;
+        }
+
+        InvoiceItem repareeItem = null;
+        for (final InvoiceItem cur : proposedItems) {
+            if (isRepareeItemForRepairedItem(repairedItem, cur)) {
+                if (repareeItem == null) {
+                    repareeItem = cur;
+                } else {
+                    log.warn("Found multiple reparee item for repaired invoice item " + repairedItem.getId());
+                }
+            }
+        }
+        // If we repaired the full period there is no repairee item
+        if (repareeItem == null) {
+            proposedItems.add(candidateRepairItem);
+            return;
+        }
+
+        final BigDecimal partialRepairAmount = candidateRepairItem.getAmount().add(repareeItem.getAmount());
+        if (partialRepairAmount.compareTo(BigDecimal.ZERO) < 0) {
+            final RepairAdjInvoiceItem repairItem = new RepairAdjInvoiceItem(candidateRepairItem.getInvoiceId(), candidateRepairItem.getAccountId(), repareeItem.getEndDate(), candidateRepairItem.getEndDate(), partialRepairAmount, candidateRepairItem.getCurrency(), candidateRepairItem.getLinkedItemId());
+            proposedItems.remove(repareeItem);
+            proposedItems.add(repairItem);
+        }
+
+    }
+
+    /**
+     * Check whether or not the invoiceItem passed is the reparee for that repaired invoice item
+     *
+     * @param repairedInvoiceItem the repaired invoice item
+     * @param invoiceItem         any invoice item to compare to
+     * @return true if invoiceItem is the reparee for that repaired invoice item
+     */
+    private boolean isRepareeItemForRepairedItem(final InvoiceItem repairedInvoiceItem, final InvoiceItem invoiceItem) {
+        return repairedInvoiceItem.getInvoiceItemType().equals(invoiceItem.getInvoiceItemType()) &&
+               repairedInvoiceItem.getSubscriptionId().equals(invoiceItem.getSubscriptionId()) &&
+               repairedInvoiceItem.getStartDate().compareTo(invoiceItem.getStartDate()) == 0 &&
+               // FIXED items have a null end date
+               ((repairedInvoiceItem.getEndDate() == null && invoiceItem.getEndDate() == null) ||
+                (repairedInvoiceItem.getEndDate() != null && invoiceItem.getEndDate() != null &&
+                 // We need to look for stricly after otherwsie we could return thew new item for that period in case of a complete repair
+                 repairedInvoiceItem.getEndDate().isAfter(invoiceItem.getEndDate()))) &&
+               !repairedInvoiceItem.getId().equals(invoiceItem.getId());
+    }
+
+
     // We check to see if there are any adjustments that point to the item we are trying to repair
     // If we did any CREDIT_ADJ or REFUND_ADJ, then we unfortunately we can't know what is the intent
     // was as it applies to the full Invoice, so we ignore it. That might result in an extra positive CBA
@@ -226,8 +281,8 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
     /*
      * Removes all matching items from both submitted collections
      */
-    void removeMatchingInvoiceItems(final List<InvoiceItem> proposedItems,
-                                    final List<InvoiceItem> existingInvoiceItems) {
+    void removeMatchingInvoiceItems(final List<InvoiceItem> existingInvoiceItems,
+                                    final List<InvoiceItem> proposedItems) {
         // We can't just use sets here as order matters (we want to keep duplicated in existingInvoiceItems)
         final Iterator<InvoiceItem> proposedItemIterator = proposedItems.iterator();
         while (proposedItemIterator.hasNext()) {
@@ -246,21 +301,29 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
     }
 
     /**
-     * Remove from the existing item list all repaired items-- both
-     * repaired and repair
+     * Remove from the existing item list all repaired items-- both repaired and repair
+     * If this is a partial repair, we also need to find the reparee from the proposed list
+     * and remove it.
      *
-     * @param existingItems
+     * @param existingItems input list of existing items
+     * @param proposedItems input list of proposed item
      */
-    void removeRepairedAndRepairInvoiceItems(final List<InvoiceItem> existingItems) {
+    void removeRepairedAndRepairInvoiceItems(final List<InvoiceItem> existingItems, final List<InvoiceItem> proposedItems) {
 
         final List<UUID> itemsToRemove = new ArrayList<UUID>();
         for (final InvoiceItem item : existingItems) {
             if (item.getInvoiceItemType() == InvoiceItemType.REPAIR_ADJ) {
                 itemsToRemove.add(item.getId());
                 itemsToRemove.add(item.getLinkedItemId());
+
+                final InvoiceItem repairedInvoiceItem = getRepairedInvoiceItem(item.getLinkedItemId(), existingItems);
+                // if this is a full repair there is no reparee so nothing to remove; if not reparee needs to be removed from proposed list
+                if (!isFullRepair(repairedInvoiceItem, item, existingItems)) {
+                    removeProposedRepareeForPartialrepair(repairedInvoiceItem, proposedItems);
+
+                }
             }
         }
-
         final Iterator<InvoiceItem> iterator = existingItems.iterator();
         while (iterator.hasNext()) {
             final InvoiceItem item = iterator.next();
@@ -270,6 +333,51 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
         }
     }
 
+    /**
+     * A full repair is one when the whole period was repaired. we reconstruct all the adjustment + repair pointing to the repaired item
+     * and if the amount matches this is a full repair.
+     *
+     * @param repairedItem  the repaired item
+     * @param repairItem    the repair item
+     * @param existingItems the list of existing items
+     * @return true if this is a full repair.
+     */
+    private boolean isFullRepair(final InvoiceItem repairedItem, final InvoiceItem repairItem, final List<InvoiceItem> existingItems) {
+
+        final BigDecimal adjustedPositiveAmount = getAdjustedPositiveAmount(existingItems, repairedItem.getId());
+        final BigDecimal repairAndAdjustedPositiveAmount = repairItem.getAmount().negate().add(adjustedPositiveAmount);
+        return (repairedItem.getAmount().compareTo(repairAndAdjustedPositiveAmount) == 0);
+    }
+
+    /**
+     * Removes the reparee from proposed list of items if it exists.
+     *
+     * @param repairedItem  the repaired item
+     * @param proposedItems the list of existing items
+     */
+    private void removeProposedRepareeForPartialrepair(final InvoiceItem repairedItem, final List<InvoiceItem> proposedItems) {
+        final Iterator<InvoiceItem> it = proposedItems.iterator();
+        while (it.hasNext()) {
+            final InvoiceItem cur = it.next();
+            if (isRepareeItemForRepairedItem(repairedItem, cur)) {
+                it.remove();
+                break;
+            }
+        }
+    }
+
+
+    private InvoiceItem getRepairedInvoiceItem(final UUID repairedInvoiceItemId, final List<InvoiceItem> existingItems) {
+        for (InvoiceItem cur : existingItems) {
+            if (cur.getId().equals(repairedInvoiceItemId)) {
+                return cur;
+            }
+        }
+        log.warn("Cannot find repaired invoice item " + repairedInvoiceItemId);
+        return null;
+    }
+
+
     private List<InvoiceItem> generateInvoiceItems(final UUID invoiceId, final UUID accountId, final BillingEventSet events,
                                                    final LocalDate targetDate, final Currency currency) throws InvoiceApiException {
         final List<InvoiceItem> items = new ArrayList<InvoiceItem>();
diff --git a/invoice/src/test/java/com/ning/billing/invoice/api/user/TestDefaultInvoiceUserApi.java b/invoice/src/test/java/com/ning/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
index 24a3618..364a4b6 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
@@ -121,7 +121,7 @@ public class TestDefaultInvoiceUserApi extends InvoiceTestSuiteWithEmbeddedDB {
         verifyExternalChargeOnExistingInvoice(invoiceBalance, null, externalChargeAmount, externalChargeInvoiceItem);
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", enabled= false)
     public void testOriginalAmountCharged() throws Exception {
 
         final Invoice initialInvoice = invoiceUserApi.getInvoice(invoiceId, callContext);
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java b/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java
index f4dc8fe..b6a73fd 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java
@@ -1059,10 +1059,10 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
         invoiceUtil.createInvoice(invoice2, true, internalCallContext);
 
         final InvoiceModelDao savedInvoice1 = invoiceDao.getById(invoice1.getId(), internalCallContext);
-        assertEquals(InvoiceModelDaoHelper.getBalance(savedInvoice1), ZERO);
+        assertEquals(InvoiceModelDaoHelper.getBalance(savedInvoice1), FIVE);
 
         final InvoiceModelDao savedInvoice2 = invoiceDao.getById(invoice2.getId(), internalCallContext);
-        assertEquals(InvoiceModelDaoHelper.getBalance(savedInvoice2), FIFTEEN);
+        assertEquals(InvoiceModelDaoHelper.getBalance(savedInvoice2), TEN);
     }
 
     @Test(groups = "slow")
diff --git a/invoice/src/test/java/com/ning/billing/invoice/generator/TestDefaultInvoiceGenerator.java b/invoice/src/test/java/com/ning/billing/invoice/generator/TestDefaultInvoiceGenerator.java
index 847d1a1..a6786c8 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/generator/TestDefaultInvoiceGenerator.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/generator/TestDefaultInvoiceGenerator.java
@@ -62,7 +62,6 @@ import com.ning.billing.util.svcapi.junction.BillingEventSet;
 import com.ning.billing.util.svcapi.junction.BillingModeType;
 
 import static com.ning.billing.invoice.TestInvoiceHelper.EIGHT;
-import static com.ning.billing.invoice.TestInvoiceHelper.ELEVEN;
 import static com.ning.billing.invoice.TestInvoiceHelper.FIFTEEN;
 import static com.ning.billing.invoice.TestInvoiceHelper.FIVE;
 import static com.ning.billing.invoice.TestInvoiceHelper.FORTY;
@@ -80,7 +79,6 @@ import static com.ning.billing.invoice.TestInvoiceHelper.TWELVE;
 import static com.ning.billing.invoice.TestInvoiceHelper.TWENTY;
 import static com.ning.billing.invoice.TestInvoiceHelper.TWENTY_FIVE;
 import static com.ning.billing.invoice.TestInvoiceHelper.TWENTY_FOUR;
-import static com.ning.billing.invoice.TestInvoiceHelper.TWENTY_SEVEN;
 import static com.ning.billing.invoice.TestInvoiceHelper.TWO;
 import static com.ning.billing.invoice.TestInvoiceHelper.ZERO;
 import static org.testng.Assert.assertEquals;
@@ -112,17 +110,14 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
     public void testWithNullEventSetAndNullInvoiceSet() throws InvoiceApiException {
         final UUID accountId = UUID.randomUUID();
         final Invoice invoice = generator.generateInvoice(accountId, null, null, clock.getUTCToday(), Currency.USD);
-
         assertNull(invoice);
     }
 
     @Test(groups = "fast")
     public void testWithEmptyEventSet() throws InvoiceApiException {
         final BillingEventSet events = new MockBillingEventSet();
-
         final UUID accountId = UUID.randomUUID();
         final Invoice invoice = generator.generateInvoice(accountId, events, null, clock.getUTCToday(), Currency.USD);
-
         assertNull(invoice);
     }
 
@@ -137,7 +132,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final BigDecimal rate1 = TEN;
         final PlanPhase phase = createMockMonthlyPlanPhase(rate1);
 
-        final BillingEvent event = createBillingEvent(sub.getId(), startDate, plan, phase, 1);
+        final BillingEvent event = createBillingEvent(sub.getId(), sub.getBundleId(), startDate, plan, phase, 1);
         events.add(event);
 
         final LocalDate targetDate = invoiceUtil.buildDate(2011, 10, 3);
@@ -151,13 +146,13 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
     }
 
     private Subscription createZombieSubscription() {
-        return createZombieSubscription(UUID.randomUUID());
+        return createZombieSubscription(UUID.randomUUID(), UUID.randomUUID());
     }
 
-    private Subscription createZombieSubscription(final UUID subscriptionId) {
+    private Subscription createZombieSubscription(final UUID subscriptionId, final UUID bundleId) {
         final Subscription sub = Mockito.mock(Subscription.class);
         Mockito.when(sub.getId()).thenReturn(subscriptionId);
-        Mockito.when(sub.getBundleId()).thenReturn(UUID.randomUUID());
+        Mockito.when(sub.getBundleId()).thenReturn(bundleId);
 
         return sub;
     }
@@ -175,7 +170,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final LocalDate startDate = invoiceUtil.buildDate(2012, 7, bcdLocal);
 
         final BillingEventSet events = new MockBillingEventSet();
-        final BillingEvent event = createBillingEvent(sub.getId(), startDate, plan, phase, bcdLocal);
+        final BillingEvent event = createBillingEvent(sub.getId(), sub.getBundleId(), startDate, plan, phase, bcdLocal);
         events.add(event);
 
         // Target date is the next BCD, in local time
@@ -200,7 +195,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final LocalDate startDate = invoiceUtil.buildDate(2012, 7, 16);
 
         final BillingEventSet events = new MockBillingEventSet();
-        events.add(createBillingEvent(sub.getId(), startDate, plan, phaseEvergreen, bcdLocal));
+        events.add(createBillingEvent(sub.getId(), sub.getBundleId(), startDate, plan, phaseEvergreen, bcdLocal));
 
         // Set a target date of today (start date)
         final LocalDate targetDate = startDate;
@@ -222,7 +217,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final Plan plan = new MockPlan();
         final BigDecimal rate = TEN;
         final PlanPhase phase = createMockMonthlyPlanPhase(rate);
-        final BillingEvent event = createBillingEvent(sub.getId(), startDate, plan, phase, 15);
+        final BillingEvent event = createBillingEvent(sub.getId(), sub.getBundleId(), startDate, plan, phase, 15);
         events.add(event);
 
         final LocalDate targetDate = invoiceUtil.buildDate(2011, 10, 3);
@@ -252,10 +247,10 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
 
         final Subscription sub = createZombieSubscription();
 
-        final BillingEvent event1 = createBillingEvent(sub.getId(), invoiceUtil.buildDate(2011, 9, 1), plan1, phase1, 1);
+        final BillingEvent event1 = createBillingEvent(sub.getId(), sub.getBundleId(), invoiceUtil.buildDate(2011, 9, 1), plan1, phase1, 1);
         events.add(event1);
 
-        final BillingEvent event2 = createBillingEvent(sub.getId(), invoiceUtil.buildDate(2011, 10, 1), plan2, phase2, 1);
+        final BillingEvent event2 = createBillingEvent(sub.getId(), sub.getBundleId(), invoiceUtil.buildDate(2011, 10, 1), plan2, phase2, 1);
         events.add(event2);
 
         final LocalDate targetDate = invoiceUtil.buildDate(2011, 10, 3);
@@ -276,12 +271,12 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final PlanPhase phase1 = createMockMonthlyPlanPhase(rate1);
 
         final Subscription sub = createZombieSubscription();
-        final BillingEvent event1 = createBillingEvent(sub.getId(), invoiceUtil.buildDate(2011, 9, 1), plan1, phase1, 1);
+        final BillingEvent event1 = createBillingEvent(sub.getId(), sub.getBundleId(), invoiceUtil.buildDate(2011, 9, 1), plan1, phase1, 1);
         events.add(event1);
 
         final BigDecimal rate2 = TEN;
         final PlanPhase phase2 = createMockMonthlyPlanPhase(rate2);
-        final BillingEvent event2 = createBillingEvent(sub.getId(), invoiceUtil.buildDate(2011, 10, 15), plan1, phase2, 15);
+        final BillingEvent event2 = createBillingEvent(sub.getId(), sub.getBundleId(), invoiceUtil.buildDate(2011, 10, 15), plan1, phase2, 15);
         events.add(event2);
 
         final LocalDate targetDate = invoiceUtil.buildDate(2011, 12, 3);
@@ -313,17 +308,17 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final PlanPhase phase1 = createMockMonthlyPlanPhase(rate1);
 
         final Subscription sub = createZombieSubscription();
-        final BillingEvent event1 = createBillingEvent(sub.getId(), invoiceUtil.buildDate(2011, 9, 1), plan1, phase1, 1);
+        final BillingEvent event1 = createBillingEvent(sub.getId(), sub.getBundleId(), invoiceUtil.buildDate(2011, 9, 1), plan1, phase1, 1);
         events.add(event1);
 
         final BigDecimal rate2 = TEN;
         final PlanPhase phase2 = createMockMonthlyPlanPhase(rate2);
-        final BillingEvent event2 = createBillingEvent(sub.getId(), invoiceUtil.buildDate(2011, 10, 1), plan1, phase2, 1);
+        final BillingEvent event2 = createBillingEvent(sub.getId(), sub.getBundleId(), invoiceUtil.buildDate(2011, 10, 1), plan1, phase2, 1);
         events.add(event2);
 
         final BigDecimal rate3 = THIRTY;
         final PlanPhase phase3 = createMockMonthlyPlanPhase(rate3);
-        final BillingEvent event3 = createBillingEvent(sub.getId(), invoiceUtil.buildDate(2011, 11, 1), plan1, phase3, 1);
+        final BillingEvent event3 = createBillingEvent(sub.getId(), sub.getBundleId(), invoiceUtil.buildDate(2011, 11, 1), plan1, phase3, 1);
         events.add(event3);
 
         final LocalDate targetDate = invoiceUtil.buildDate(2011, 12, 3);
@@ -346,7 +341,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final BigDecimal rate = FIVE;
         final PlanPhase phase1 = createMockMonthlyPlanPhase(rate);
 
-        final BillingEvent event1 = createBillingEvent(sub.getId(), startDate, plan1, phase1, 1);
+        final BillingEvent event1 = createBillingEvent(sub.getId(), sub.getBundleId(), startDate, plan1, phase1, 1);
         events.add(event1);
 
         LocalDate targetDate = invoiceUtil.buildDate(2011, 12, 1);
@@ -370,6 +365,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         // plan 4: change of plan, effective EOT, BCD = 7 (covers change of plan)
         // plan 5: addon to plan 2, with bill cycle alignment to plan; immediate cancellation
         final UUID accountId = UUID.randomUUID();
+        final UUID bundleId = UUID.randomUUID();
         final UUID subscriptionId1 = UUID.randomUUID();
         final UUID subscriptionId2 = UUID.randomUUID();
         final UUID subscriptionId3 = UUID.randomUUID();
@@ -417,7 +413,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final BillingEventSet events = new MockBillingEventSet();
 
         // on 1/5/2011, create subscription 1 (trial)
-        events.add(createBillingEvent(subscriptionId1, plan1StartDate, plan1, plan1Phase1, 5));
+        events.add(createBillingEvent(subscriptionId1, bundleId, plan1StartDate, plan1, plan1Phase1, 5));
         expectedAmount = EIGHT;
         testInvoiceGeneration(accountId, events, invoices, plan1StartDate, 1, expectedAmount);
 
@@ -430,12 +426,12 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         testInvoiceGeneration(accountId, events, invoices, invoiceUtil.buildDate(2011, 3, 5), 1, expectedAmount);
 
         // on 3/10/2011, create subscription 2 (trial)
-        events.add(createBillingEvent(subscriptionId2, plan2StartDate, plan2, plan2Phase1, 10));
+        events.add(createBillingEvent(subscriptionId2, bundleId, plan2StartDate, plan2, plan2Phase1, 10));
         expectedAmount = TWENTY;
         testInvoiceGeneration(accountId, events, invoices, plan2StartDate, 1, expectedAmount);
 
         // on 4/5/2011, invoice subscription 1 (discount)
-        events.add(createBillingEvent(subscriptionId1, plan1PhaseChangeDate, plan1, plan1Phase2, 5));
+        events.add(createBillingEvent(subscriptionId1, bundleId, plan1PhaseChangeDate, plan1, plan1Phase2, 5));
         expectedAmount = TWELVE;
         testInvoiceGeneration(accountId, events, invoices, plan1PhaseChangeDate, 1, expectedAmount);
 
@@ -444,27 +440,27 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         testInvoiceGeneration(accountId, events, invoices, invoiceUtil.buildDate(2011, 4, 10), 1, expectedAmount);
 
         // on 4/29/2011, cancel subscription 1
-        events.add(createBillingEvent(subscriptionId1, plan1CancelDate, plan1, plan1Phase3, 5));
-        // previous invoices are adjusted; this is the pro-ration amount only
-        expectedAmount = TWELVE.multiply(TWENTY_FOUR.divide(THIRTY, NUMBER_OF_DECIMALS, ROUNDING_METHOD)).setScale(NUMBER_OF_DECIMALS);
-        testInvoiceGeneration(accountId, events, invoices, plan1CancelDate, 2, expectedAmount);
+        events.add(createBillingEvent(subscriptionId1, bundleId, plan1CancelDate, plan1, plan1Phase3, 5));
+
+        expectedAmount = ZERO;
+        testInvoiceGeneration(accountId, events, invoices, plan1CancelDate, 1, expectedAmount);
 
         // on 5/10/2011, invoice subscription 2 (trial)
         expectedAmount = TWENTY;
         testInvoiceGeneration(accountId, events, invoices, invoiceUtil.buildDate(2011, 5, 10), 1, expectedAmount);
 
         // on 5/20/2011, create subscription 3 (monthly)
-        events.add(createBillingEvent(subscriptionId3, plan3StartDate, plan3, plan3Phase1, 20));
+        events.add(createBillingEvent(subscriptionId3, bundleId, plan3StartDate, plan3, plan3Phase1, 20));
         expectedAmount = TEN;
         testInvoiceGeneration(accountId, events, invoices, plan3StartDate, 1, expectedAmount);
 
         // on 6/7/2011, create subscription 4
-        events.add(createBillingEvent(subscriptionId4, plan4StartDate, plan4a, plan4aPhase1, 7));
+        events.add(createBillingEvent(subscriptionId4, bundleId, plan4StartDate, plan4a, plan4aPhase1, 7));
         expectedAmount = FIFTEEN;
         testInvoiceGeneration(accountId, events, invoices, plan4StartDate, 1, expectedAmount);
 
         // on 6/10/2011, invoice subscription 2 (discount)
-        events.add(createBillingEvent(subscriptionId2, plan2PhaseChangeToDiscountDate, plan2, plan2Phase2, 10));
+        events.add(createBillingEvent(subscriptionId2, bundleId, plan2PhaseChangeToDiscountDate, plan2, plan2Phase2, 10));
         expectedAmount = THIRTY;
         testInvoiceGeneration(accountId, events, invoices, plan2PhaseChangeToDiscountDate, 1, expectedAmount);
 
@@ -473,7 +469,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         testInvoiceGeneration(accountId, events, invoices, invoiceUtil.buildDate(2011, 6, 20), 1, expectedAmount);
 
         // on 6/21/2011, create add-on (subscription 5)
-        events.add(createBillingEvent(subscriptionId5, plan5StartDate, plan5, plan5Phase1, 10));
+        events.add(createBillingEvent(subscriptionId5, bundleId, plan5StartDate, plan5, plan5Phase1, 10));
         expectedAmount = TWENTY.multiply(NINETEEN).divide(THIRTY, NUMBER_OF_DECIMALS, ROUNDING_METHOD);
         testInvoiceGeneration(accountId, events, invoices, plan5StartDate, 1, expectedAmount);
 
@@ -490,13 +486,11 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         testInvoiceGeneration(accountId, events, invoices, invoiceUtil.buildDate(2011, 7, 20), 1, expectedAmount);
 
         // on 7/31/2011, convert subscription 3 to annual
-        events.add(createBillingEvent(subscriptionId3, plan3UpgradeToAnnualDate, plan3, plan3Phase2, 31));
-        expectedAmount = ONE_HUNDRED.add(TEN.multiply(ELEVEN.divide(THIRTY_ONE, 2 * NUMBER_OF_DECIMALS, ROUNDING_METHOD)));
-        expectedAmount = expectedAmount.setScale(NUMBER_OF_DECIMALS, ROUNDING_METHOD);
-        testInvoiceGeneration(accountId, events, invoices, plan3UpgradeToAnnualDate, 3, expectedAmount);
+        events.add(createBillingEvent(subscriptionId3, bundleId, plan3UpgradeToAnnualDate, plan3, plan3Phase2, 31));
+        testInvoiceGeneration(accountId, events, invoices, plan3UpgradeToAnnualDate, 2, ONE_HUNDRED);
 
         // on 8/7/2011, invoice subscription 4 (plan 2)
-        events.add(createBillingEvent(subscriptionId4, plan4ChangeOfPlanDate, plan4b, plan4bPhase1, 7));
+        events.add(createBillingEvent(subscriptionId4, bundleId, plan4ChangeOfPlanDate, plan4b, plan4bPhase1, 7));
         expectedAmount = TWENTY_FOUR;
         testInvoiceGeneration(accountId, events, invoices, plan4ChangeOfPlanDate, 1, expectedAmount);
 
@@ -509,14 +503,13 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         testInvoiceGeneration(accountId, events, invoices, invoiceUtil.buildDate(2011, 9, 7), 1, expectedAmount);
 
         // on 9/10/2011, invoice plan 2 (evergreen), invoice subscription 5
-        events.add(createBillingEvent(subscriptionId2, plan2PhaseChangeToEvergreenDate, plan2, plan2Phase3, 10));
+        events.add(createBillingEvent(subscriptionId2, bundleId, plan2PhaseChangeToEvergreenDate, plan2, plan2Phase3, 10));
         expectedAmount = FORTY.add(TWENTY);
         testInvoiceGeneration(accountId, events, invoices, plan2PhaseChangeToEvergreenDate, 2, expectedAmount);
 
         // on 10/7/2011, invoice subscription 4 (plan 2), cancel subscription 5
-        events.add(createBillingEvent(subscriptionId5, plan5CancelDate, plan5, plan5Phase2, 10));
-        expectedAmount = TWENTY_FOUR.add(TWENTY.multiply(TWENTY_SEVEN.divide(THIRTY)).setScale(NUMBER_OF_DECIMALS));
-        testInvoiceGeneration(accountId, events, invoices, plan5CancelDate, 3, expectedAmount);
+        events.add(createBillingEvent(subscriptionId5, bundleId, plan5CancelDate, plan5, plan5Phase2, 10));
+        testInvoiceGeneration(accountId, events, invoices, plan5CancelDate, 2, TWENTY_FOUR);
 
         // on 10/10/2011, invoice plan 2 (evergreen)
         expectedAmount = FORTY;
@@ -529,7 +522,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final PlanPhase planPhase = createMockMonthlyPlanPhase(ZERO);
         final BillingEventSet events = new MockBillingEventSet();
         final LocalDate targetDate = invoiceUtil.buildDate(2011, 1, 1);
-        events.add(createBillingEvent(UUID.randomUUID(), targetDate, plan, planPhase, 1));
+        events.add(createBillingEvent(UUID.randomUUID(), UUID.randomUUID(), targetDate, plan, planPhase, 1));
 
         final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, targetDate, Currency.USD);
 
@@ -544,7 +537,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final LocalDate startDate = clock.getUTCToday().minusDays(1);
         final LocalDate targetDate = startDate.plusDays(1);
 
-        events.add(createBillingEvent(UUID.randomUUID(), startDate, plan, planPhase, startDate.getDayOfMonth()));
+        events.add(createBillingEvent(UUID.randomUUID(), UUID.randomUUID(), startDate, plan, planPhase, startDate.getDayOfMonth()));
 
         final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, targetDate, Currency.USD);
         final RecurringInvoiceItem item = (RecurringInvoiceItem) invoice.getInvoiceItems().get(0);
@@ -606,10 +599,11 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
 
         final BillingEventSet events = new MockBillingEventSet();
         final UUID subscriptionId = UUID.randomUUID();
+        final UUID bundleId = UUID.randomUUID();
         final UUID accountId = UUID.randomUUID();
 
         final LocalDate startDate = new LocalDate(2011, 1, 1);
-        final BillingEvent event1 = createBillingEvent(subscriptionId, startDate, plan1, phase1, 1);
+        final BillingEvent event1 = createBillingEvent(subscriptionId, bundleId, startDate, plan1, phase1, 1);
         events.add(event1);
 
         // ensure both components are invoiced
@@ -643,9 +637,10 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final BillingEventSet events = new MockBillingEventSet();
         final UUID subscriptionId = UUID.randomUUID();
         final UUID accountId = UUID.randomUUID();
+        final UUID bundleId = UUID.randomUUID();
 
         final LocalDate startDate = new LocalDate(2011, 1, 1);
-        final BillingEvent event1 = createBillingEvent(subscriptionId, startDate, plan1, phase1, 1);
+        final BillingEvent event1 = createBillingEvent(subscriptionId, bundleId, startDate, plan1, phase1, 1);
         events.add(event1);
 
         // ensure that a single invoice item is generated for the fixed cost
@@ -659,7 +654,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
 
         // move forward in time one billing period
         final LocalDate phaseChangeDate = startDate.plusMonths(1);
-        final BillingEvent event2 = createBillingEvent(subscriptionId, phaseChangeDate, plan1, phase2, 1);
+        final BillingEvent event2 = createBillingEvent(subscriptionId, bundleId, phaseChangeDate, plan1, phase2, 1);
         events.add(event2);
 
         // ensure that a single invoice item is generated for the fixed cost
@@ -674,6 +669,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final BillingEventSet events = new MockBillingEventSet();
         final UUID subscriptionId = UUID.randomUUID();
         final UUID accountId = UUID.randomUUID();
+        final UUID bundleId = UUID.randomUUID();
         final int BILL_CYCLE_DAY = 15;
 
         // create subscription with a zero-dollar trial, a monthly discount period and a monthly evergreen
@@ -685,15 +681,15 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
 
         // set up billing events
         final LocalDate creationDate = new LocalDate(2012, 3, 6);
-        events.add(createBillingEvent(subscriptionId, creationDate, plan1, phase1, BILL_CYCLE_DAY));
+        events.add(createBillingEvent(subscriptionId, bundleId, creationDate, plan1, phase1, BILL_CYCLE_DAY));
 
         // trialPhaseEndDate = 2012/4/5
         final LocalDate trialPhaseEndDate = creationDate.plusDays(30);
-        events.add(createBillingEvent(subscriptionId, trialPhaseEndDate, plan1, phase2, BILL_CYCLE_DAY));
+        events.add(createBillingEvent(subscriptionId, bundleId, trialPhaseEndDate, plan1, phase2, BILL_CYCLE_DAY));
 
         // discountPhaseEndDate = 2012/10/5
         final LocalDate discountPhaseEndDate = trialPhaseEndDate.plusMonths(6);
-        events.add(createBillingEvent(subscriptionId, discountPhaseEndDate, plan1, phase3, BILL_CYCLE_DAY));
+        events.add(createBillingEvent(subscriptionId, bundleId, discountPhaseEndDate, plan1, phase3, BILL_CYCLE_DAY));
 
         final Invoice invoice1 = generator.generateInvoice(accountId, events, null, creationDate, Currency.USD);
         assertNotNull(invoice1);
@@ -730,7 +726,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final BillingEventSet events = new MockBillingEventSet();
         final Plan plan1 = new MockPlan();
         final PlanPhase phase1 = createMockMonthlyPlanPhase(null, ZERO, PhaseType.TRIAL);
-        events.add(createBillingEvent(UUID.randomUUID(), clock.getUTCToday(), plan1, phase1, 1));
+        events.add(createBillingEvent(UUID.randomUUID(), UUID.randomUUID(), clock.getUTCToday(), plan1, phase1, 1));
         generator.generateInvoice(UUID.randomUUID(), events, null, targetDate, Currency.USD);
     }
 
@@ -762,9 +758,9 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
                                  null, BillingPeriod.ANNUAL, phaseType);
     }
 
-    private BillingEvent createBillingEvent(final UUID subscriptionId, final LocalDate startDate,
+    private BillingEvent createBillingEvent(final UUID subscriptionId, final UUID bundleId, final LocalDate startDate,
                                             final Plan plan, final PlanPhase planPhase, final int billCycleDayLocal) throws CatalogApiException {
-        final Subscription sub = createZombieSubscription(subscriptionId);
+        final Subscription sub = createZombieSubscription(subscriptionId, bundleId);
         final Currency currency = Currency.USD;
 
         return invoiceUtil.createMockBillingEvent(null, sub, startDate.toDateTimeAtStartOfDay(), plan, planPhase,
@@ -788,7 +784,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
     }
 
     @Test(groups = "fast")
-    public void testAddOnInvoiceGeneration() throws CatalogApiException, InvoiceApiException {
+    public void testWithFullRepairInvoiceGeneration() throws CatalogApiException, InvoiceApiException {
         final LocalDate april25 = new LocalDate(2012, 4, 25);
 
         // create a base plan on April 25th
@@ -802,7 +798,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final PlanPhase basePlanEvergreen = new MockPlanPhase(price10, null, BillingPeriod.MONTHLY, PhaseType.EVERGREEN);
 
         final BillingEventSet events = new MockBillingEventSet();
-        events.add(createBillingEvent(baseSubscription.getId(), april25, basePlan, basePlanEvergreen, 25));
+        events.add(createBillingEvent(baseSubscription.getId(), baseSubscription.getBundleId(), april25, basePlan, basePlanEvergreen, 25));
 
         // generate invoice
         final Invoice invoice1 = generator.generateInvoice(accountId, events, null, april25, Currency.USD);
@@ -818,12 +814,12 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final Subscription addOnSubscription1 = createZombieSubscription();
         final Plan addOn1Plan = new MockPlan("add on 1");
         final PlanPhase addOn1PlanPhaseEvergreen = new MockPlanPhase(price5, null, BillingPeriod.MONTHLY, PhaseType.EVERGREEN);
-        events.add(createBillingEvent(addOnSubscription1.getId(), april28, addOn1Plan, addOn1PlanPhaseEvergreen, 25));
+        events.add(createBillingEvent(addOnSubscription1.getId(), baseSubscription.getBundleId(), april28, addOn1Plan, addOn1PlanPhaseEvergreen, 25));
 
         final Subscription addOnSubscription2 = createZombieSubscription();
         final Plan addOn2Plan = new MockPlan("add on 2");
         final PlanPhase addOn2PlanPhaseEvergreen = new MockPlanPhase(price20, null, BillingPeriod.MONTHLY, PhaseType.EVERGREEN);
-        events.add(createBillingEvent(addOnSubscription2.getId(), april28, addOn2Plan, addOn2PlanPhaseEvergreen, 25));
+        events.add(createBillingEvent(addOnSubscription2.getId(), baseSubscription.getBundleId(), april28, addOn2Plan, addOn2PlanPhaseEvergreen, 25));
 
         // generate invoice
         final Invoice invoice2 = generator.generateInvoice(accountId, events, invoices, april28, Currency.USD);
@@ -838,19 +834,20 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final Plan basePlan2 = new MockPlan("base plan 2");
         final MockInternationalPrice price13 = new MockInternationalPrice(new DefaultPrice(THIRTEEN, Currency.USD));
         final PlanPhase basePlan2Phase = new MockPlanPhase(price13, null, BillingPeriod.MONTHLY, PhaseType.EVERGREEN);
-        newEvents.add(createBillingEvent(baseSubscription.getId(), april25, basePlan2, basePlan2Phase, 25));
-        newEvents.add(createBillingEvent(addOnSubscription1.getId(), april28, addOn1Plan, addOn1PlanPhaseEvergreen, 25));
+        newEvents.add(createBillingEvent(baseSubscription.getId(), baseSubscription.getBundleId(), april25, basePlan2, basePlan2Phase, 25));
+        newEvents.add(createBillingEvent(addOnSubscription1.getId(), baseSubscription.getBundleId(), april28, addOn1Plan, addOn1PlanPhaseEvergreen, 25));
 
         // generate invoice
         final LocalDate may1 = new LocalDate(2012, 5, 1);
         final Invoice invoice3 = generator.generateInvoice(accountId, newEvents, invoices, may1, Currency.USD);
         assertNotNull(invoice3);
-        assertEquals(invoice3.getNumberOfItems(), 5);
+        assertEquals(invoice3.getNumberOfItems(), 3);
         // -4.50 -18 - 10 (to correct the previous 2 invoices) + 4.50 + 13
         assertEquals(invoice3.getBalance().compareTo(FIFTEEN.negate()), 0);
     }
 
-    @Test
+
+    @Test(groups = "fast")
     public void testRepairForPaidInvoice() throws CatalogApiException, InvoiceApiException {
         // create an invoice
         final LocalDate april25 = new LocalDate(2012, 4, 25);
@@ -864,7 +861,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final PlanPhase originalPlanEvergreen = new MockPlanPhase(price10, null, BillingPeriod.MONTHLY, PhaseType.EVERGREEN);
 
         final BillingEventSet events = new MockBillingEventSet();
-        events.add(createBillingEvent(originalSubscription.getId(), april25, originalPlan, originalPlanEvergreen, 25));
+        events.add(createBillingEvent(originalSubscription.getId(), originalSubscription.getBundleId(), april25, originalPlan, originalPlanEvergreen, 25));
 
         final Invoice invoice1 = generator.generateInvoice(accountId, events, null, april25, Currency.USD);
 
@@ -884,23 +881,23 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final Plan newPlan = new MockPlan("new plan");
         final MockInternationalPrice price5 = new MockInternationalPrice(new DefaultPrice(FIVE, Currency.USD));
         final PlanPhase newPlanEvergreen = new MockPlanPhase(price5, null, BillingPeriod.MONTHLY, PhaseType.EVERGREEN);
-        events.add(createBillingEvent(newSubscription.getId(), april25, newPlan, newPlanEvergreen, 25));
+        events.add(createBillingEvent(newSubscription.getId(), originalSubscription.getBundleId(), april25, newPlan, newPlanEvergreen, 25));
 
         // generate a new invoice
         final Invoice invoice2 = generator.generateInvoice(accountId, events, invoices, april25, Currency.USD);
 
         printDetailInvoice(invoice2);
-        assertEquals(invoice2.getNumberOfItems(), 4);
+        assertEquals(invoice2.getNumberOfItems(), 2);
         invoices.add(invoice2);
 
         // move items to the correct invoice (normally, the dao calls will sort that out)
         distributeItems(invoices);
 
         // ensure that the original invoice balance is zero
-        assertEquals(invoice1.getBalance().compareTo(ZERO), 0);
+        assertEquals(invoice1.getBalance().compareTo(new BigDecimal("-10.0")), 0);
 
         // ensure that the account balance is correct
-        assertEquals(invoice2.getBalance().compareTo(ZERO), 0);
+        assertEquals(invoice2.getBalance().compareTo(FIVE), 0);
 
         // ensure that the account has a credit balance
         final BigDecimal creditBalance = invoice1.getCreditedAmount().add(invoice2.getCreditedAmount());
@@ -945,7 +942,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final BigDecimal rate1 = TEN;
         final PlanPhase phase = createMockMonthlyPlanPhase(rate1);
 
-        final BillingEvent event = createBillingEvent(sub.getId(), startDate, plan, phase, 1);
+        final BillingEvent event = createBillingEvent(sub.getId(), sub.getBundleId(), startDate, plan, phase, 1);
         events.add(event);
 
         final LocalDate targetDate = invoiceUtil.buildDate(2011, 10, 3);
@@ -960,6 +957,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final List<Invoice> invoices = new ArrayList<Invoice>();
         final MockBillingEventSet eventSet = new MockBillingEventSet();
         final UUID accountId = UUID.randomUUID();
+        final UUID bundleId = UUID.randomUUID();
 
         final LocalDate startDate = new LocalDate(2012, 1, 1);
 
@@ -967,14 +965,14 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final UUID subscriptionId1 = UUID.randomUUID();
         final Plan plan1 = new MockPlan();
         final PlanPhase plan1phase1 = createMockMonthlyPlanPhase(FIFTEEN, null, PhaseType.DISCOUNT);
-        final BillingEvent subscription1creation = createBillingEvent(subscriptionId1, startDate, plan1, plan1phase1, 1);
+        final BillingEvent subscription1creation = createBillingEvent(subscriptionId1, bundleId, startDate, plan1, plan1phase1, 1);
         eventSet.add(subscription1creation);
 
         // add second subscription creation event
         final UUID subscriptionId2 = UUID.randomUUID();
         final Plan plan2 = new MockPlan();
         final PlanPhase plan2phase1 = createMockMonthlyPlanPhase(TWELVE, null, PhaseType.EVERGREEN);
-        eventSet.add(createBillingEvent(subscriptionId2, startDate, plan2, plan2phase1, 1));
+        eventSet.add(createBillingEvent(subscriptionId2, bundleId, startDate, plan2, plan2phase1, 1));
 
         // generate the first invoice
         final Invoice invoice1 = generator.generateInvoice(accountId, eventSet, invoices, startDate, currency);
diff --git a/invoice/src/test/java/com/ning/billing/invoice/generator/TestDefaultInvoiceGeneratorUnit.java b/invoice/src/test/java/com/ning/billing/invoice/generator/TestDefaultInvoiceGeneratorUnit.java
index b56a6d9..909ed5a 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/generator/TestDefaultInvoiceGeneratorUnit.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/generator/TestDefaultInvoiceGeneratorUnit.java
@@ -62,7 +62,7 @@ public class TestDefaultInvoiceGeneratorUnit extends InvoiceTestSuiteNoDB {
         items.add(item1);
         items.add(new RepairAdjInvoiceItem(invoiceId, accountId, startDate, endDate, amount.negate(), currency, item1.getId()));
         items.add(new RecurringInvoiceItem(invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, endDate, nextEndDate, amount2, rate2, currency));
-        ((DefaultInvoiceGenerator) generator).removeRepairedAndRepairInvoiceItems(items);
+        ((DefaultInvoiceGenerator) generator).removeRepairedAndRepairInvoiceItems(items, new LinkedList<InvoiceItem>());
         assertEquals(items.size(), 1);
         final InvoiceItem leftItem = items.get(0);
         assertEquals(leftItem.getInvoiceItemType(), InvoiceItemType.RECURRING);
@@ -84,7 +84,7 @@ public class TestDefaultInvoiceGeneratorUnit extends InvoiceTestSuiteNoDB {
         items.add(item1);
         items.add(new RepairAdjInvoiceItem(invoiceId, accountId, startDate, endDate, amount1.negate(), currency, item1.getId()));
         items.add(new RecurringInvoiceItem(invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, endDate, nextEndDate, amount2, rate2, currency));
-        ((DefaultInvoiceGenerator) generator).removeRepairedAndRepairInvoiceItems(items);
+        ((DefaultInvoiceGenerator) generator).removeRepairedAndRepairInvoiceItems(items, new LinkedList<InvoiceItem>());
         assertEquals(items.size(), 1);
         final InvoiceItem leftItem = items.get(0);
         assertEquals(leftItem.getInvoiceItemType(), InvoiceItemType.RECURRING);
@@ -259,52 +259,4 @@ public class TestDefaultInvoiceGeneratorUnit extends InvoiceTestSuiteNoDB {
 
     }
 
-    @Test(groups = "fast")
-    public void testGenerateCreditsForPastRepairedInvoices() {
-        final LocalDate startDate = clock.getUTCToday();
-        final LocalDate endDate = startDate.plusDays(30);
-        final LocalDate nextEndDate = startDate.plusMonths(1);
-
-        final BigDecimal rate1 = new BigDecimal("10.00");
-        final BigDecimal amount1 = rate1;
-
-        final List<InvoiceItem> existing = new LinkedList<InvoiceItem>();
-        final InvoiceItem item1 = new RecurringInvoiceItem(invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, startDate, endDate, amount1, rate1, currency);
-        existing.add(item1);
-
-        final UUID existingInvoiceId = UUID.randomUUID();
-        final List<Invoice> existingInvoices = new LinkedList<Invoice>();
-        final Invoice existingInvoice = mock(Invoice.class);
-        when(existingInvoice.getId()).thenReturn(existingInvoiceId);
-        when(existingInvoice.getBalance()).thenReturn(BigDecimal.ZERO);
-        when(existingInvoice.getInvoiceItems()).thenReturn(existing);
-
-        final BigDecimal rate2 = new BigDecimal("20.0");
-        final BigDecimal amount2 = rate2;
-
-        final List<InvoiceItem> proposed = new LinkedList<InvoiceItem>();
-        final InvoiceItem reversedItem1 = new RepairAdjInvoiceItem(existingInvoiceId, accountId, startDate, nextEndDate, item1.getAmount().negate(), currency, item1.getId());
-        final InvoiceItem newItem1 = new RecurringInvoiceItem(invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, startDate, endDate, amount2, rate2, currency);
-        proposed.add(reversedItem1);
-        proposed.add(newItem1);
-
-        ((DefaultInvoiceGenerator) generator).generateCBAForExistingInvoices(accountId, existingInvoices, proposed, currency);
-
-        assertEquals(proposed.size(), 3);
-        final InvoiceItem reversedItemCheck1 = proposed.get(0);
-        assertEquals(reversedItemCheck1.getInvoiceId(), existingInvoiceId);
-        assertEquals(reversedItemCheck1.getInvoiceItemType(), InvoiceItemType.REPAIR_ADJ);
-        assertEquals(reversedItemCheck1.getAmount(), item1.getAmount().negate());
-        assertEquals(reversedItemCheck1.getLinkedItemId(), item1.getId());
-
-        final InvoiceItem newItemCheck1 = proposed.get(1);
-        assertEquals(newItemCheck1.getInvoiceId(), invoiceId);
-        assertEquals(newItemCheck1.getInvoiceItemType(), InvoiceItemType.RECURRING);
-        assertEquals(newItemCheck1.getAmount(), amount2);
-
-        final InvoiceItem creditItemCheck = proposed.get(2);
-        assertEquals(creditItemCheck.getInvoiceId(), existingInvoiceId);
-        assertEquals(creditItemCheck.getInvoiceItemType(), InvoiceItemType.CBA_ADJ);
-        assertEquals(creditItemCheck.getAmount(), amount2.add(rate1.negate()));
-    }
 }