killbill-uncached

Details

diff --git a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessAccount.java b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessAccount.java
index b3cc61c..116597e 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessAccount.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessAccount.java
@@ -24,6 +24,8 @@ import org.joda.time.LocalDate;
 
 import com.ning.billing.analytics.utils.Rounder;
 
+import com.google.common.base.Objects;
+
 public class BusinessAccount {
     // Populated by the database
     private DateTime createdDt = null;
@@ -72,7 +74,7 @@ public class BusinessAccount {
     }
 
     public BigDecimal getBalance() {
-        return balance;
+        return Objects.firstNonNull(balance, BigDecimal.ZERO);
     }
 
     public Double getRoundedBalance() {
@@ -140,7 +142,7 @@ public class BusinessAccount {
     }
 
     public BigDecimal getTotalInvoiceBalance() {
-        return totalInvoiceBalance;
+        return Objects.firstNonNull(totalInvoiceBalance, BigDecimal.ZERO);
     }
 
     public Double getRoundedTotalInvoiceBalance() {
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessAccount.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessAccount.java
index bdd1a7a..251072d 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessAccount.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessAccount.java
@@ -50,4 +50,16 @@ public class TestBusinessAccount extends AnalyticsTestSuite {
                                                                  BigDecimal.TEN, "ERROR_NOT_ENOUGH_FUNDS", "CreditCard", "Visa", "");
         Assert.assertFalse(account.equals(otherAccount));
     }
+
+    @Test(groups = "fast")
+    public void testDefaultBigDecimalValues() throws Exception {
+        final BusinessAccount bac = new BusinessAccount(UUID.randomUUID());
+        Assert.assertEquals(bac.getBalance(), BigDecimal.ZERO);
+        Assert.assertEquals(bac.getTotalInvoiceBalance(), BigDecimal.ZERO);
+
+        bac.setBalance(BigDecimal.ONE);
+        bac.setTotalInvoiceBalance(BigDecimal.TEN);
+        Assert.assertEquals(bac.getBalance(), BigDecimal.ONE);
+        Assert.assertEquals(bac.getTotalInvoiceBalance(), BigDecimal.TEN);
+    }
 }
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 8842d3d..2a6d781 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
@@ -20,9 +20,11 @@ import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.UUID;
 
 import javax.annotation.Nullable;
@@ -56,6 +58,8 @@ import com.ning.billing.invoice.model.RepairAdjInvoiceItem;
 import com.ning.billing.junction.api.BillingEventSet;
 import com.ning.billing.util.clock.Clock;
 
+import com.google.common.collect.Sets;
+import com.google.common.collect.Sets.SetView;
 import com.google.inject.Inject;
 
 public class DefaultInvoiceGenerator implements InvoiceGenerator {
@@ -231,19 +235,11 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
      */
     void removeDuplicatedInvoiceItems(final List<InvoiceItem> proposedItems,
                                       final List<InvoiceItem> existingInvoiceItems) {
-        final Iterator<InvoiceItem> proposedItemIterator = proposedItems.iterator();
-        while (proposedItemIterator.hasNext()) {
-            final InvoiceItem proposedItem = proposedItemIterator.next();
-
-            final Iterator<InvoiceItem> existingItemIterator = existingInvoiceItems.iterator();
-            while (existingItemIterator.hasNext()) {
-                final InvoiceItem existingItem = existingItemIterator.next();
-                if (existingItem.equals(proposedItem)) {
-                    existingItemIterator.remove();
-                    proposedItemIterator.remove();
-                }
-            }
-        }
+        final Set<InvoiceItem> proposedSet = new HashSet<InvoiceItem>(proposedItems);
+        final Set<InvoiceItem> existingSet = new HashSet<InvoiceItem>(existingInvoiceItems);
+        final SetView<InvoiceItem> intersection = Sets.intersection(proposedSet, existingSet);
+        proposedItems.removeAll(intersection);
+        existingInvoiceItems.removeAll(intersection);
     }
 
     void removeCancellingInvoiceItems(final List<InvoiceItem> items) {
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 2f119e3..95cb8c7 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
@@ -131,6 +131,29 @@ public class TestDefaultInvoiceGeneratorUnit extends InvoicingTestBase {
     }
 
     @Test(groups = "fast")
+    public void testRemoveDuplicatedInvoiceItemsShouldNotThrowIllegalStateException() {
+        final LocalDate startDate = clock.getUTCToday();
+        final BigDecimal amount = new BigDecimal("12.00");
+
+        // Create a state with multiple duplicates
+
+        final List<InvoiceItem> existing = new LinkedList<InvoiceItem>();
+        final InvoiceItem item1 = new FixedPriceInvoiceItem(invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, startDate, amount, currency);
+        existing.add(item1);
+        existing.add(item1);
+
+        final List<InvoiceItem> proposed = new LinkedList<InvoiceItem>();
+        final InvoiceItem other1 = new FixedPriceInvoiceItem(invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, startDate, amount, currency);
+        proposed.add(item1);
+        proposed.add(other1);
+        proposed.add(other1);
+
+        gen.removeDuplicatedInvoiceItems(proposed, existing);
+        assertEquals(existing.size(), 0);
+        assertEquals(proposed.size(), 0);
+    }
+
+    @Test(groups = "fast")
     public void testRemoveDuplicatedInvoiceItemsFixedPrice() {
         final LocalDate startDate = clock.getUTCToday();
         final LocalDate endDate = startDate.plusDays(30);