killbill-aplcache

Changes

overdue/pom.xml 21(+5 -16)

pom.xml 4(+4 -0)

Details

diff --git a/api/src/main/java/com/ning/billing/catalog/api/overdue/OverdueState.java b/api/src/main/java/com/ning/billing/catalog/api/overdue/OverdueState.java
index d4faaff..715317e 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/overdue/OverdueState.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/overdue/OverdueState.java
@@ -25,4 +25,6 @@ public interface OverdueState<T extends Overdueable> {
 
     public boolean applyCancel();
 
+    public boolean isClearState();
+
 }
\ No newline at end of file
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoiceItem.java b/api/src/main/java/com/ning/billing/invoice/api/InvoiceItem.java
index 1abcf83..4082403 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoiceItem.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoiceItem.java
@@ -28,6 +28,8 @@ public interface InvoiceItem extends Entity, Comparable<InvoiceItem> {
 
     UUID getSubscriptionId();
 
+    UUID getBundleId();
+
     String getPlanName();
 
     String getPhaseName();
diff --git a/catalog/src/main/java/com/ning/billing/catalog/overdue/DefaultOverdueState.java b/catalog/src/main/java/com/ning/billing/catalog/overdue/DefaultOverdueState.java
index 7e73da9..8e0981e 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/overdue/DefaultOverdueState.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/overdue/DefaultOverdueState.java
@@ -21,7 +21,6 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlID;
-import javax.xml.bind.annotation.XmlIDREF;
 
 import com.ning.billing.catalog.api.overdue.OverdueState;
 import com.ning.billing.catalog.api.overdue.Overdueable;
@@ -29,6 +28,8 @@ import com.ning.billing.catalog.api.overdue.Overdueable;
 @XmlAccessorType(XmlAccessType.NONE)
 public class DefaultOverdueState<T extends Overdueable> implements OverdueState<T> {
 
+    // TODO - need to implement Clear states
+    
     @XmlElement(required=false, name="condition")
 	private DefaultCondition<T> condition;
 
@@ -99,4 +100,9 @@ public class DefaultOverdueState<T extends Overdueable> implements OverdueState<
 		return this;
 	}
 
+    @Override
+    public boolean isClearState() {
+        return false;
+    }
+
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/FixedPriceInvoiceItemSqlDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/FixedPriceInvoiceItemSqlDao.java
index 6fdd74d..27b41ba 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/FixedPriceInvoiceItemSqlDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/FixedPriceInvoiceItemSqlDao.java
@@ -16,10 +16,17 @@
 
 package com.ning.billing.invoice.dao;
 
-import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.invoice.api.InvoiceItem;
-import com.ning.billing.invoice.model.FixedPriceInvoiceItem;
-import com.ning.billing.util.entity.EntityDao;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.math.BigDecimal;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.UUID;
+
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.SQLStatement;
 import org.skife.jdbi.v2.StatementContext;
@@ -34,16 +41,10 @@ import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import java.lang.annotation.Annotation;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.math.BigDecimal;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.List;
-import java.util.UUID;
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.invoice.api.InvoiceItem;
+import com.ning.billing.invoice.model.FixedPriceInvoiceItem;
+import com.ning.billing.util.entity.EntityDao;
 
 @ExternalizedSqlViaStringTemplate3()
 @RegisterMapper(FixedPriceInvoiceItemSqlDao.FixedPriceInvoiceItemMapper.class)
@@ -77,6 +78,7 @@ public interface FixedPriceInvoiceItemSqlDao extends EntityDao<InvoiceItem> {
                     public void bind(SQLStatement q, FixedPriceInvoiceItemBinder bind, FixedPriceInvoiceItem item) {
                         q.bind("id", item.getId().toString());
                         q.bind("invoiceId", item.getInvoiceId().toString());
+                        q.bind("bundleId", item.getBundleId().toString());
                         q.bind("subscriptionId", item.getSubscriptionId().toString());
                         q.bind("planName", item.getPlanName());
                         q.bind("phaseName", item.getPhaseName());
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/RecurringInvoiceItemSqlDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/RecurringInvoiceItemSqlDao.java
index d588cb1..1b38769 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/RecurringInvoiceItemSqlDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/RecurringInvoiceItemSqlDao.java
@@ -77,6 +77,7 @@ public interface RecurringInvoiceItemSqlDao extends EntityDao<InvoiceItem> {
                         q.bind("id", item.getId().toString());
                         q.bind("invoiceId", item.getInvoiceId().toString());
                         q.bind("subscriptionId", item.getSubscriptionId().toString());
+                        q.bind("bundleId", item.getBundleId().toString());
                         q.bind("planName", item.getPlanName());
                         q.bind("phaseName", item.getPhaseName());
                         q.bind("startDate", item.getStartDate().toDate());
@@ -98,6 +99,7 @@ public interface RecurringInvoiceItemSqlDao extends EntityDao<InvoiceItem> {
             UUID id = UUID.fromString(result.getString("id"));
             UUID invoiceId = UUID.fromString(result.getString("invoice_id"));
             UUID subscriptionId = UUID.fromString(result.getString("subscription_id"));
+            UUID bundleId = UUID.fromString(result.getString("bundle_id"));
             String planName = result.getString("plan_name");
             String phaseName = result.getString("phase_name");
             DateTime startDate = new DateTime(result.getTimestamp("start_date"));
@@ -109,7 +111,7 @@ public interface RecurringInvoiceItemSqlDao extends EntityDao<InvoiceItem> {
             UUID reversedItemId = (reversedItemString == null) ? null : UUID.fromString(reversedItemString);
             DateTime createdDate = new DateTime(result.getTimestamp("created_date"));
 
-            return new RecurringInvoiceItem(id, invoiceId, subscriptionId, planName, phaseName, startDate, endDate,
+            return new RecurringInvoiceItem(id, invoiceId, subscriptionId, bundleId, planName, phaseName, startDate, endDate,
                     amount, rate, currency, reversedItemId, createdDate);
         }
     }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java
index 66c71bd..9b9a83f 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java
@@ -210,7 +210,9 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
                     if (rate != null) {
                         BigDecimal amount = itemDatum.getNumberOfCycles().multiply(rate).setScale(NUMBER_OF_DECIMALS, ROUNDING_MODE);
 
-                        RecurringInvoiceItem recurringItem = new RecurringInvoiceItem(invoiceId, thisEvent.getSubscription().getId(),
+                        RecurringInvoiceItem recurringItem = new RecurringInvoiceItem(invoiceId, 
+                                thisEvent.getSubscription().getId(),
+                                thisEvent.getSubscription().getBundleId(), 
                                 thisEvent.getPlan().getName(),
                                 thisEvent.getPlanPhase().getName(),
                                 itemDatum.getStartDate(), itemDatum.getEndDate(),
@@ -245,6 +247,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
                 DateTime endDate = duration.addToDateTime(thisEvent.getEffectiveDate());
 
                 return new FixedPriceInvoiceItem(invoiceId, thisEvent.getSubscription().getId(),
+                                                thisEvent.getSubscription().getBundleId(),
                                                  thisEvent.getPlan().getName(), thisEvent.getPlanPhase().getName(),
                                                  thisEvent.getEffectiveDate(), endDate, fixedPrice, currency,
                                                  clock.getUTCNow());
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/FixedPriceInvoiceItem.java b/invoice/src/main/java/com/ning/billing/invoice/model/FixedPriceInvoiceItem.java
index 4a1bc1d..492e69c 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/FixedPriceInvoiceItem.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/FixedPriceInvoiceItem.java
@@ -24,16 +24,16 @@ import java.math.BigDecimal;
 import java.util.UUID;
 
 public class FixedPriceInvoiceItem extends InvoiceItemBase {
-    public FixedPriceInvoiceItem(UUID invoiceId, UUID subscriptionId, String planName, String phaseName,
+    public FixedPriceInvoiceItem(UUID invoiceId, UUID subscriptionId, UUID bundleId, String planName, String phaseName,
                                  DateTime startDate, DateTime endDate, BigDecimal amount, Currency currency,
                                  DateTime createdDate) {
-        super(invoiceId, subscriptionId, planName, phaseName, startDate, endDate, amount, currency, createdDate);
+        super(invoiceId, subscriptionId, bundleId, planName, phaseName, startDate, endDate, amount, currency, createdDate);
     }
 
-    public FixedPriceInvoiceItem(UUID id, UUID invoiceId, UUID subscriptionId, String planName, String phaseName,
+    public FixedPriceInvoiceItem(UUID id, UUID invoiceId, UUID subscriptionId, UUID bundleId, String planName, String phaseName,
                                  DateTime startDate, DateTime endDate, BigDecimal amount, Currency currency,
                                  DateTime createdDate) {
-        super(id, invoiceId, subscriptionId, planName, phaseName, startDate, endDate, amount, currency, createdDate);
+        super(id, invoiceId, subscriptionId, bundleId, planName, phaseName, startDate, endDate, amount, currency, createdDate);
     }
 
     @Override
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemBase.java b/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemBase.java
index 6f69e33..71d8a0b 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemBase.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemBase.java
@@ -27,6 +27,7 @@ public abstract class InvoiceItemBase implements InvoiceItem {
     protected final UUID id;
     protected final UUID invoiceId;
     protected final UUID subscriptionId;
+    protected final UUID bundleId;
     protected final String planName;
     protected final String phaseName;
     protected final DateTime startDate;
@@ -35,19 +36,20 @@ public abstract class InvoiceItemBase implements InvoiceItem {
     protected final Currency currency;
     protected final DateTime createdDate;
 
-    public InvoiceItemBase(UUID invoiceId, UUID subscriptionId, String planName, String phaseName,
+    public InvoiceItemBase(UUID invoiceId, UUID subscriptionId, UUID bundleId, String planName, String phaseName,
                            DateTime startDate, DateTime endDate, BigDecimal amount, Currency currency,
                            DateTime createdDate) {
-        this(UUID.randomUUID(), invoiceId, subscriptionId, planName, phaseName,
+        this(UUID.randomUUID(), invoiceId, subscriptionId, bundleId, planName, phaseName,
                 startDate, endDate, amount, currency, createdDate);
     }
 
-    public InvoiceItemBase(UUID id, UUID invoiceId, UUID subscriptionId, String planName, String phaseName,
+    public InvoiceItemBase(UUID id, UUID invoiceId, UUID subscriptionId, UUID bundleId, String planName, String phaseName,
                            DateTime startDate, DateTime endDate, BigDecimal amount, Currency currency,
                            DateTime createdDate) {
         this.id = id;
         this.invoiceId = invoiceId;
         this.subscriptionId = subscriptionId;
+        this.bundleId = bundleId;
         this.planName = planName;
         this.phaseName = phaseName;
         this.startDate = startDate;
@@ -72,6 +74,11 @@ public abstract class InvoiceItemBase implements InvoiceItem {
     }
 
     @Override
+    public UUID getBundleId() {
+        return bundleId;
+    }
+
+    @Override
     public UUID getSubscriptionId() {
         return subscriptionId;
     }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/MigrationInvoiceItem.java b/invoice/src/main/java/com/ning/billing/invoice/model/MigrationInvoiceItem.java
index 3910ad7..0feb08d 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/MigrationInvoiceItem.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/MigrationInvoiceItem.java
@@ -26,10 +26,11 @@ import com.ning.billing.catalog.api.MigrationPlan;
 import com.ning.billing.util.clock.Clock;
 
 public class MigrationInvoiceItem extends FixedPriceInvoiceItem {
-	private final static UUID MIGRATION_SUBSCRIPTION_ID = UUID.fromString("ed25f954-3aa2-4422-943b-c3037ad7257c"); //new UUID(0L,0L);
+    private final static UUID MIGRATION_SUBSCRIPTION_ID = UUID.fromString("ed25f954-3aa2-4422-943b-c3037ad7257c"); 
+    private final static UUID MIGRATION_BUNDLE_ID = UUID.fromString("ed25f954-3aa2-4422-943b-c3037ad7257d"); // Going away anyway
 
 	public MigrationInvoiceItem(UUID invoiceId, DateTime startDate, BigDecimal amount, Currency currency, Clock clock) {
-		super(invoiceId, MIGRATION_SUBSCRIPTION_ID, MigrationPlan.MIGRATION_PLAN_NAME, MigrationPlan.MIGRATION_PLAN_PHASE_NAME, startDate, startDate,
+		super(invoiceId, MIGRATION_SUBSCRIPTION_ID, MIGRATION_BUNDLE_ID, MigrationPlan.MIGRATION_PLAN_NAME, MigrationPlan.MIGRATION_PLAN_PHASE_NAME, startDate, startDate,
 				amount, currency, clock.getUTCNow());
 	}
 
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/RecurringInvoiceItem.java b/invoice/src/main/java/com/ning/billing/invoice/model/RecurringInvoiceItem.java
index 8c7517e..3e32f09 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/RecurringInvoiceItem.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/RecurringInvoiceItem.java
@@ -27,41 +27,41 @@ public class RecurringInvoiceItem extends InvoiceItemBase {
     private final BigDecimal rate;
     private final UUID reversedItemId;
 
-    public RecurringInvoiceItem(UUID invoiceId, UUID subscriptionId, String planName, String phaseName,
+    public RecurringInvoiceItem(UUID invoiceId, UUID subscriptionId, UUID bundleId,String planName, String phaseName,
                                 DateTime startDate, DateTime endDate,
                                 BigDecimal amount, BigDecimal rate,
                                 Currency currency,
                                 DateTime createdDate) {
-        this(UUID.randomUUID(), invoiceId, subscriptionId, planName, phaseName, startDate, endDate,
+        this(UUID.randomUUID(), invoiceId, subscriptionId, bundleId, planName, phaseName, startDate, endDate,
                 amount, rate, currency, createdDate);
     }
 
-    public RecurringInvoiceItem(UUID invoiceId, UUID subscriptionId, String planName, String phaseName,
+    public RecurringInvoiceItem(UUID invoiceId, UUID subscriptionId, UUID bundleId, String planName, String phaseName,
                                 DateTime startDate, DateTime endDate,
                                 BigDecimal amount, BigDecimal rate,
                                 Currency currency, UUID reversedItemId,
                                 DateTime createdDate) {
-        this(UUID.randomUUID(), invoiceId, subscriptionId, planName, phaseName, startDate, endDate,
+        this(UUID.randomUUID(), invoiceId, subscriptionId, bundleId, planName, phaseName, startDate, endDate,
                 amount, rate, currency, reversedItemId, createdDate);
     }
 
-    public RecurringInvoiceItem(UUID id, UUID invoiceId, UUID subscriptionId, String planName, String phaseName,
+    public RecurringInvoiceItem(UUID id, UUID invoiceId, UUID subscriptionId, UUID bundleId,String planName, String phaseName,
                                 DateTime startDate, DateTime endDate,
                                 BigDecimal amount, BigDecimal rate,
                                 Currency currency,
                                 DateTime createdDate) {
-        super(id, invoiceId, subscriptionId, planName, phaseName, startDate, endDate, amount, currency, createdDate);
+        super(id, invoiceId, subscriptionId, bundleId, planName, phaseName, startDate, endDate, amount, currency, createdDate);
 
         this.rate = rate;
         this.reversedItemId = null;
     }
 
-    public RecurringInvoiceItem(UUID id, UUID invoiceId, UUID subscriptionId, String planName, String phaseName,
+    public RecurringInvoiceItem(UUID id, UUID invoiceId, UUID subscriptionId, UUID bundleId,String planName, String phaseName,
                                 DateTime startDate, DateTime endDate,
                                 BigDecimal amount, BigDecimal rate,
                                 Currency currency, UUID reversedItemId,
                                 DateTime createdDate) {
-        super(id, invoiceId, subscriptionId, planName, phaseName, startDate, endDate, amount, currency, createdDate);
+        super(id, invoiceId, subscriptionId, bundleId, planName, phaseName, startDate, endDate, amount, currency, createdDate);
 
         this.rate = rate;
         this.reversedItemId = reversedItemId;
@@ -70,7 +70,7 @@ public class RecurringInvoiceItem extends InvoiceItemBase {
     @Override
     public InvoiceItem asCredit() {
         BigDecimal amountNegated = amount == null ? null : amount.negate();
-        return new RecurringInvoiceItem(invoiceId, subscriptionId, planName, phaseName, startDate, endDate,
+        return new RecurringInvoiceItem(invoiceId, subscriptionId, bundleId, planName, phaseName, startDate, endDate,
                 amountNegated, rate, currency, id, createdDate);
     }
 
diff --git a/invoice/src/main/resources/com/ning/billing/invoice/dao/FixedPriceInvoiceItemSqlDao.sql.stg b/invoice/src/main/resources/com/ning/billing/invoice/dao/FixedPriceInvoiceItemSqlDao.sql.stg
index 61f5e68..0b5d43a 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/dao/FixedPriceInvoiceItemSqlDao.sql.stg
+++ b/invoice/src/main/resources/com/ning/billing/invoice/dao/FixedPriceInvoiceItemSqlDao.sql.stg
@@ -4,6 +4,7 @@ fields(prefix) ::= <<
   <prefix>id,
   <prefix>invoice_id,
   <prefix>subscription_id,
+  <prefix>bundle_id,
   <prefix>plan_name,
   <prefix>phase_name,
   <prefix>start_date,
diff --git a/invoice/src/main/resources/com/ning/billing/invoice/dao/RecurringInvoiceItemSqlDao.sql.stg b/invoice/src/main/resources/com/ning/billing/invoice/dao/RecurringInvoiceItemSqlDao.sql.stg
index e703d0b..45dbc9d 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/dao/RecurringInvoiceItemSqlDao.sql.stg
+++ b/invoice/src/main/resources/com/ning/billing/invoice/dao/RecurringInvoiceItemSqlDao.sql.stg
@@ -4,6 +4,7 @@ fields(prefix) ::= <<
   <prefix>id,
   <prefix>invoice_id,
   <prefix>subscription_id,
+  <prefix>bundle_id,
   <prefix>plan_name,
   <prefix>phase_name,
   <prefix>start_date,
diff --git a/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql b/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql
index 88f7595..51087db 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql
+++ b/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql
@@ -4,6 +4,7 @@ CREATE TABLE recurring_invoice_items (
   id char(36) NOT NULL,
   invoice_id char(36) NOT NULL,
   subscription_id char(36) NOT NULL,
+  bundle_id char(36) NOT NULL,
   plan_name varchar(50) NOT NULL,
   phase_name varchar(50) NOT NULL,
   start_date datetime NOT NULL,
@@ -23,6 +24,7 @@ CREATE TABLE fixed_invoice_items (
   id char(36) NOT NULL,
   invoice_id char(36) NOT NULL,
   subscription_id char(36) NOT NULL,
+  bundle_id char(36) NOT NULL,
   plan_name varchar(50) NOT NULL,
   phase_name varchar(50) NOT NULL,
   start_date datetime NOT NULL,
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java
index 9249420..2224ede 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java
@@ -47,7 +47,7 @@ public abstract class InvoiceDaoTestBase extends InvoicingTestBase {
     @BeforeClass(alwaysRun = true)
     protected void setup() throws IOException {
         // Health check test to make sure MySQL is setup properly
-        try {
+       
             module = new InvoiceModuleWithEmbeddedDb();
             final String accountDdl = IOUtils.toString(DefaultInvoiceDao.class.getResourceAsStream("/com/ning/billing/account/ddl.sql"));
             final String invoiceDdl = IOUtils.toString(DefaultInvoiceDao.class.getResourceAsStream("/com/ning/billing/invoice/ddl.sql"));
@@ -71,10 +71,7 @@ public abstract class InvoiceDaoTestBase extends InvoicingTestBase {
             ((DefaultBusService) busService).startBus();
 
             assertTrue(true);
-        }
-        catch (Throwable t) {
-            fail(t.toString());
-        }
+       
     }
 
     @BeforeMethod(alwaysRun = true)
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
index ef70c33..1408656 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
@@ -90,9 +90,10 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
         Invoice invoice = new DefaultInvoice(accountId, clock.getUTCNow(), Currency.USD, clock);
         UUID invoiceId = invoice.getId();
         UUID subscriptionId = UUID.randomUUID();
+        UUID bundleId = UUID.randomUUID();
         DateTime startDate = new DateTime(2010, 1, 1, 0, 0, 0, 0);
         DateTime endDate = new DateTime(2010, 4, 1, 0, 0, 0, 0);
-        InvoiceItem invoiceItem = new RecurringInvoiceItem(invoiceId, subscriptionId, "test plan", "test phase", startDate, endDate,
+        InvoiceItem invoiceItem = new RecurringInvoiceItem(invoiceId, subscriptionId, bundleId,"test plan", "test phase", startDate, endDate,
                 new BigDecimal("21.00"), new BigDecimal("7.00"), Currency.USD, clock.getUTCNow());
         invoice.addInvoiceItem(invoiceItem);
         invoiceDao.create(invoice);
@@ -173,6 +174,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
     @Test
     public void testGetInvoicesBySubscription() {
         UUID accountId = UUID.randomUUID();
+        UUID bundleId = UUID.randomUUID();
 
         UUID subscriptionId1 = UUID.randomUUID();
         BigDecimal rate1 = new BigDecimal("17.0");
@@ -195,19 +197,19 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
         DateTime startDate = new DateTime(2011, 3, 1, 0, 0, 0, 0);
         DateTime endDate = startDate.plusMonths(1);
 
-        RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoiceId1, subscriptionId1, "test plan", "test A", startDate, endDate,
+        RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoiceId1, subscriptionId1, bundleId,"test plan", "test A", startDate, endDate,
                 rate1, rate1, Currency.USD, clock.getUTCNow());
         recurringInvoiceItemDao.create(item1);
 
-        RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoiceId1, subscriptionId2, "test plan", "test B", startDate, endDate,
+        RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoiceId1, subscriptionId2, bundleId,"test plan", "test B", startDate, endDate,
                 rate2, rate2, Currency.USD, clock.getUTCNow());
         recurringInvoiceItemDao.create(item2);
 
-        RecurringInvoiceItem item3 = new RecurringInvoiceItem(invoiceId1, subscriptionId3, "test plan", "test C", startDate, endDate,
+        RecurringInvoiceItem item3 = new RecurringInvoiceItem(invoiceId1, subscriptionId3, bundleId,"test plan", "test C", startDate, endDate,
                 rate3, rate3, Currency.USD, clock.getUTCNow());
         recurringInvoiceItemDao.create(item3);
 
-        RecurringInvoiceItem item4 = new RecurringInvoiceItem(invoiceId1, subscriptionId4, "test plan", "test D", startDate, endDate,
+        RecurringInvoiceItem item4 = new RecurringInvoiceItem(invoiceId1, subscriptionId4, bundleId, "test plan", "test D", startDate, endDate,
                 rate4, rate4, Currency.USD, clock.getUTCNow());
         recurringInvoiceItemDao.create(item4);
 
@@ -220,15 +222,15 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
         startDate = endDate;
         endDate = startDate.plusMonths(1);
 
-        RecurringInvoiceItem item5 = new RecurringInvoiceItem(invoiceId2, subscriptionId1, "test plan", "test phase A", startDate, endDate,
+        RecurringInvoiceItem item5 = new RecurringInvoiceItem(invoiceId2, subscriptionId1, bundleId,"test plan", "test phase A", startDate, endDate,
                 rate1, rate1, Currency.USD, clock.getUTCNow());
         recurringInvoiceItemDao.create(item5);
 
-        RecurringInvoiceItem item6 = new RecurringInvoiceItem(invoiceId2, subscriptionId2, "test plan", "test phase B", startDate, endDate,
+        RecurringInvoiceItem item6 = new RecurringInvoiceItem(invoiceId2, subscriptionId2, bundleId,"test plan", "test phase B", startDate, endDate,
                 rate2, rate2, Currency.USD, clock.getUTCNow());
         recurringInvoiceItemDao.create(item6);
 
-        RecurringInvoiceItem item7 = new RecurringInvoiceItem(invoiceId2, subscriptionId3, "test plan", "test phase C", startDate, endDate,
+        RecurringInvoiceItem item7 = new RecurringInvoiceItem(invoiceId2, subscriptionId3, bundleId, "test plan", "test phase C", startDate, endDate,
                 rate3, rate3, Currency.USD, clock.getUTCNow());
         recurringInvoiceItemDao.create(item7);
 
@@ -278,6 +280,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
     @Test
     public void testAccountBalance() {
         UUID accountId = UUID.randomUUID();
+        UUID bundleId = UUID.randomUUID();
         DateTime targetDate1 = new DateTime(2011, 10, 6, 0, 0, 0, 0);
         Invoice invoice1 = new DefaultInvoice(accountId, targetDate1, Currency.USD, clock);
         invoiceDao.create(invoice1);
@@ -288,11 +291,11 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
         BigDecimal rate1 = new BigDecimal("17.0");
         BigDecimal rate2 = new BigDecimal("42.0");
 
-        RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoice1.getId(), UUID.randomUUID(), "test plan", "test phase A", startDate,
+        RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoice1.getId(), UUID.randomUUID(), bundleId,"test plan", "test phase A", startDate,
                 endDate, rate1, rate1, Currency.USD, clock.getUTCNow());
         recurringInvoiceItemDao.create(item1);
 
-        RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), UUID.randomUUID(), "test plan", "test phase B", startDate,
+        RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), UUID.randomUUID(), bundleId,"test plan", "test phase B", startDate,
                 endDate, rate2, rate2, Currency.USD, clock.getUTCNow());
         recurringInvoiceItemDao.create(item2);
 
@@ -307,6 +310,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
     @Test
     public void testAccountBalanceWithNoPayments() {
         UUID accountId = UUID.randomUUID();
+        UUID bundleId = UUID.randomUUID();
         DateTime targetDate1 = new DateTime(2011, 10, 6, 0, 0, 0, 0);
         Invoice invoice1 = new DefaultInvoice(accountId, targetDate1, Currency.USD, clock);
         invoiceDao.create(invoice1);
@@ -317,11 +321,11 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
         BigDecimal rate1 = new BigDecimal("17.0");
         BigDecimal rate2 = new BigDecimal("42.0");
 
-        RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoice1.getId(), UUID.randomUUID(), "test plan", "test phase A", startDate, endDate,
+        RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoice1.getId(), UUID.randomUUID(), bundleId,"test plan", "test phase A", startDate, endDate,
                 rate1, rate1, Currency.USD, clock.getUTCNow());
         recurringInvoiceItemDao.create(item1);
 
-        RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), UUID.randomUUID(), "test plan", "test phase B", startDate, endDate,
+        RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), UUID.randomUUID(), bundleId,"test plan", "test phase B", startDate, endDate,
                 rate2, rate2, Currency.USD, clock.getUTCNow());
         recurringInvoiceItemDao.create(item2);
 
@@ -347,6 +351,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
     @Test
     public void testGetUnpaidInvoicesByAccountId() {
         UUID accountId = UUID.randomUUID();
+        UUID bundleId = UUID.randomUUID();
         DateTime targetDate1 = new DateTime(2011, 10, 6, 0, 0, 0, 0);
         Invoice invoice1 = new DefaultInvoice(accountId, targetDate1, Currency.USD, clock);
         invoiceDao.create(invoice1);
@@ -357,11 +362,11 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
         BigDecimal rate1 = new BigDecimal("17.0");
         BigDecimal rate2 = new BigDecimal("42.0");
 
-        RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoice1.getId(), UUID.randomUUID(), "test plan", "test phase A", startDate, endDate,
+        RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoice1.getId(), UUID.randomUUID(), bundleId, "test plan", "test phase A", startDate, endDate,
                 rate1, rate1, Currency.USD, clock.getUTCNow());
         recurringInvoiceItemDao.create(item1);
 
-        RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), UUID.randomUUID(), "test plan", "test phase B", startDate, endDate,
+        RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), UUID.randomUUID(), bundleId,"test plan", "test phase B", startDate, endDate,
                 rate2, rate2, Currency.USD, clock.getUTCNow());
         recurringInvoiceItemDao.create(item2);
 
@@ -385,7 +390,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
 
         BigDecimal rate3 = new BigDecimal("21.0");
 
-        RecurringInvoiceItem item3 = new RecurringInvoiceItem(invoice2.getId(), UUID.randomUUID(), "test plan", "test phase C", startDate2, endDate2,
+        RecurringInvoiceItem item3 = new RecurringInvoiceItem(invoice2.getId(), UUID.randomUUID(), bundleId,"test plan", "test phase C", startDate2, endDate2,
                 rate3, rate3, Currency.USD, clock.getUTCNow());
         recurringInvoiceItemDao.create(item3);
 
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceItemDaoTests.java b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceItemDaoTests.java
index 63ad021..9d625bd 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceItemDaoTests.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceItemDaoTests.java
@@ -39,13 +39,14 @@ public class InvoiceItemDaoTests extends InvoiceDaoTestBase {
     @Test(groups = "slow")
     public void testInvoiceItemCreation() {
         UUID invoiceId = UUID.randomUUID();
+        UUID bundleId = UUID.randomUUID();
         UUID subscriptionId = UUID.randomUUID();
         DateTime startDate = new DateTime(2011, 10, 1, 0, 0, 0, 0);
         DateTime endDate = new DateTime(2011, 11, 1, 0, 0, 0, 0);
         BigDecimal rate = new BigDecimal("20.00");
 
         final DateTime expectedCreatedDate = clock.getUTCNow();
-        RecurringInvoiceItem item = new RecurringInvoiceItem(invoiceId, subscriptionId, "test plan", "test phase", startDate, endDate,
+        RecurringInvoiceItem item = new RecurringInvoiceItem(invoiceId, subscriptionId, bundleId, "test plan", "test phase", startDate, endDate,
                 rate, rate, Currency.USD, expectedCreatedDate);
         recurringInvoiceItemDao.create(item);
 
@@ -65,12 +66,13 @@ public class InvoiceItemDaoTests extends InvoiceDaoTestBase {
     @Test(groups = "slow")
     public void testGetInvoiceItemsBySubscriptionId() {
         UUID subscriptionId = UUID.randomUUID();
+        UUID bundleId = UUID.randomUUID();
         DateTime startDate = new DateTime(2011, 3, 1, 0, 0, 0, 0);
         BigDecimal rate = new BigDecimal("20.00");
 
         for (int i = 0; i < 3; i++) {
             UUID invoiceId = UUID.randomUUID();
-            RecurringInvoiceItem item = new RecurringInvoiceItem(invoiceId, subscriptionId, "test plan", "test phase", startDate.plusMonths(i), startDate.plusMonths(i + 1),
+            RecurringInvoiceItem item = new RecurringInvoiceItem(invoiceId, subscriptionId, bundleId, "test plan", "test phase", startDate.plusMonths(i), startDate.plusMonths(i + 1),
                     rate, rate, Currency.USD, clock.getUTCNow());
             recurringInvoiceItemDao.create(item);
         }
@@ -82,13 +84,14 @@ public class InvoiceItemDaoTests extends InvoiceDaoTestBase {
     @Test(groups = "slow")
     public void testGetInvoiceItemsByInvoiceId() {
         UUID invoiceId = UUID.randomUUID();
+        UUID bundleId = UUID.randomUUID();
         DateTime startDate = new DateTime(2011, 3, 1, 0, 0, 0, 0);
         BigDecimal rate = new BigDecimal("20.00");
 
         for (int i = 0; i < 5; i++) {
             UUID subscriptionId = UUID.randomUUID();
             BigDecimal amount = rate.multiply(new BigDecimal(i + 1));
-            RecurringInvoiceItem item = new RecurringInvoiceItem(invoiceId, subscriptionId, "test plan", "test phase", startDate, startDate.plusMonths(1),
+            RecurringInvoiceItem item = new RecurringInvoiceItem(invoiceId, subscriptionId, bundleId, "test plan", "test phase", startDate, startDate.plusMonths(1),
                     amount, amount, Currency.USD, clock.getUTCNow());
             recurringInvoiceItemDao.create(item);
         }
@@ -100,6 +103,7 @@ public class InvoiceItemDaoTests extends InvoiceDaoTestBase {
     @Test(groups = "slow")
     public void testGetInvoiceItemsByAccountId() {
         UUID accountId = UUID.randomUUID();
+        UUID bundleId = UUID.randomUUID();
         DateTime targetDate = new DateTime(2011, 5, 23, 0, 0, 0, 0);
         DefaultInvoice invoice = new DefaultInvoice(accountId, targetDate, Currency.USD, clock);
 
@@ -110,7 +114,7 @@ public class InvoiceItemDaoTests extends InvoiceDaoTestBase {
         BigDecimal rate = new BigDecimal("20.00");
 
         UUID subscriptionId = UUID.randomUUID();
-        RecurringInvoiceItem item = new RecurringInvoiceItem(invoiceId, subscriptionId, "test plan", "test phase", startDate, startDate.plusMonths(1),
+        RecurringInvoiceItem item = new RecurringInvoiceItem(invoiceId, subscriptionId, bundleId, "test plan", "test phase", startDate, startDate.plusMonths(1),
                 rate, rate, Currency.USD, clock.getUTCNow());
         recurringInvoiceItemDao.create(item);
 

overdue/pom.xml 21(+5 -16)

diff --git a/overdue/pom.xml b/overdue/pom.xml
index fc9a803..93f2878 100644
--- a/overdue/pom.xml
+++ b/overdue/pom.xml
@@ -25,6 +25,10 @@
             <artifactId>killbill-api</artifactId>
         </dependency>
         <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-util</artifactId>
+        </dependency>
+         <dependency>
             <groupId>com.google.inject</groupId>
             <artifactId>guice</artifactId>
             <scope>provided</scope>
@@ -37,12 +41,7 @@
             <groupId>joda-time</groupId>
             <artifactId>joda-time</artifactId>
         </dependency>
-        <dependency>
-            <groupId>com.ning.jdbi</groupId>
-            <artifactId>jdbi-metrics</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
+         <dependency>
             <groupId>org.jdbi</groupId>
             <artifactId>jdbi</artifactId>
             <scope>test</scope>
@@ -64,16 +63,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>com.mysql</groupId>
-            <artifactId>management</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.mysql</groupId>
-            <artifactId>management-dbfiles</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
             <scope>runtime</scope>
diff --git a/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicatorBundle.java b/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicatorBundle.java
index 8f16dc0..da9aa11 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicatorBundle.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicatorBundle.java
@@ -19,22 +19,66 @@ package com.ning.billing.overdue.applicator;
 import org.apache.commons.lang.NotImplementedException;
 import org.joda.time.DateTime;
 
+import com.google.inject.Inject;
 import com.ning.billing.catalog.api.overdue.OverdueState;
+import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 
-public class OverdueStateApplicatorBundle implements OverdueStateApplicator<SubscriptionBundle>{
+public class OverdueStateApplicatorBundle implements OverdueStateApplicator<SubscriptionBundle>{    
+    private EntitlementUserApi entitlementApi;
+
+    @Inject
+    public OverdueStateApplicatorBundle(EntitlementUserApi entitlementApi){
+        this.entitlementApi = entitlementApi;   
+    }
 
     @Override
     public void apply(SubscriptionBundle overdueable,
             OverdueState<SubscriptionBundle> previousOverdueState,
             OverdueState<SubscriptionBundle> nextOverdueState, DateTime timeOfNextCheck) {
-        //  Create immediate notification with this data
-        //  Make changes to apply the state
-        //  Record new state in DAO
-        // Create notification for future check
+        
+        if(previousOverdueState.getName().equals(nextOverdueState.getName())) {
+            return; // nothing to do
+        }
+        
+        cancelBundle(overdueable, previousOverdueState, nextOverdueState);
+        storeNewState(overdueable, nextOverdueState);
+  
+        if(timeOfNextCheck != null && !nextOverdueState.isClearState()) {
+            createFutureNotification(overdueable, timeOfNextCheck);
+        }
+
+        if(nextOverdueState.isClearState()) {
+            clear(overdueable);
+        }
         
         //If new state is clear state reset next events and override table
         throw new NotImplementedException();
     }
 
+    private void cancelBundle(SubscriptionBundle overdueable,
+            OverdueState<SubscriptionBundle> previousOverdueState,
+            OverdueState<SubscriptionBundle> nextOverdueState) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    private void storeNewState(SubscriptionBundle overdueable,
+            OverdueState<SubscriptionBundle> nextOverdueState) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    private void createFutureNotification(SubscriptionBundle overdueable,
+            DateTime timeOfNextCheck) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    private void clear(SubscriptionBundle overdueable) {
+        // TODO Clear any future events plus overrides
+        
+    }
+
+
 }
diff --git a/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculator.java b/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculator.java
index 1ccf2eb..1ec10a8 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculator.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculator.java
@@ -17,31 +17,63 @@
 package com.ning.billing.overdue.calculator;
 
 import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
 import java.util.SortedSet;
+import java.util.TreeSet;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
 
+import com.google.inject.Inject;
 import com.ning.billing.catalog.api.overdue.BillingState;
 import com.ning.billing.catalog.api.overdue.Overdueable;
 import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.invoice.api.InvoiceUserApi;
+import com.ning.billing.util.clock.Clock;
 
 public abstract class BillingStateCalculator<T extends Overdueable> {
 
+    private final InvoiceUserApi invoiceApi;
+    private final Clock clock;
+
+    @Inject 
+    public BillingStateCalculator(InvoiceUserApi invoiceApi, Clock clock) {
+        this.invoiceApi = invoiceApi;
+        this.clock = clock;
+    }
+    
     public abstract BillingState<T> calculateBillingState(T overdueable);
     
     protected DateTime earliest(SortedSet<Invoice> unpaidInvoices) {
-        // TODO Auto-generated method stub
-        return null;
+        return unpaidInvoices.first().getInvoiceDate();
     }
 
     protected BigDecimal sumBalance(SortedSet<Invoice> unpaidInvoices) {
-        // TODO Auto-generated method stub
-        return null;
+        BigDecimal sum = BigDecimal.ZERO;
+        Iterator<Invoice> it = unpaidInvoices.iterator();
+        while(it.hasNext()) {
+            sum = sum.add(it.next().getBalance());
+        }
+        return sum;
     }
 
     protected SortedSet<Invoice> unpaidInvoicesFor(UUID id) {
-        // TODO Auto-generated method stub
-        return null;
+        Collection<Invoice> invoices = invoiceApi.getUnpaidInvoicesByAccountId(id, clock.getUTCNow());
+        SortedSet<Invoice> sortedInvoices = new TreeSet<Invoice>(new Comparator<Invoice>() {
+            @Override
+            public int compare(Invoice i1, Invoice i2) {
+                DateTime d1 = i1.getInvoiceDate();
+                DateTime d2 = i2.getInvoiceDate();
+                if(d1.compareTo(d2) == 0) {
+                    return i1.hashCode() - i2.hashCode(); // consistent (arbitrary) resolution for tied dates
+                }
+                return d1.compareTo(d2);
+            }
+            
+        });
+        sortedInvoices.addAll(invoices);
+        return sortedInvoices;
     }
 }
diff --git a/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java b/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java
index 75c6a60..d7bbdd7 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java
@@ -35,31 +35,32 @@ import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceUserApi;
+import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.tag.Tag;
 
 public class BillingStateCalculatorBundle  extends BillingStateCalculator<SubscriptionBundle>{
 
     private EntitlementOverdueApi entitlementApi;
-    private InvoiceUserApi invoiceApi;
 
     @Inject 
-    public BillingStateCalculatorBundle(EntitlementOverdueApi entitlementApi, InvoiceUserApi invoiceApi) {
+    public BillingStateCalculatorBundle(EntitlementOverdueApi entitlementApi, InvoiceUserApi invoiceApi, Clock clock) {
+        super(invoiceApi, clock);
         this.entitlementApi = entitlementApi;
-        this.invoiceApi = invoiceApi;
     }
     
     @Override
     public BillingState<SubscriptionBundle> calculateBillingState(SubscriptionBundle bundle) {
         
         SortedSet<Invoice> unpaidInvoices = unpaidInvoicesFor(bundle.getId());
+ 
         Subscription basePlan = entitlementApi.getBaseSubscription(bundle.getId());
         
         UUID id = bundle.getId();
         int numberOfUnpaidInvoices = unpaidInvoices.size(); 
         BigDecimal unpaidInvoiceBalance = sumBalance(unpaidInvoices);
         DateTime dateOfEarliestUnpaidInvoice = earliest(unpaidInvoices);
-        PaymentResponse responseForLastFailedPayment = null; //TODO
-        Tag[] tags = new Tag[]{}; //TODO
+        PaymentResponse responseForLastFailedPayment = PaymentResponse.INSUFFICIENT_FUNDS; //TODO MDW
+        Tag[] tags = new Tag[]{}; //TODO MDW
         Product basePlanProduct = basePlan.getCurrentPlan().getProduct();
         BillingPeriod basePlanBillingPeriod = basePlan.getCurrentPlan().getBillingPeriod();
         PriceList basePlanPriceList = basePlan.getCurrentPriceList();
diff --git a/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculator.java b/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculator.java
new file mode 100644
index 0000000..0ccbd7d
--- /dev/null
+++ b/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculator.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.overdue.calculator;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.SortedSet;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.catalog.api.overdue.BillingState;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.invoice.api.InvoiceUserApi;
+import com.ning.billing.mock.BrainDeadProxyFactory;
+import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.clock.ClockMock;
+
+public class TestBillingStateCalculator {
+    Clock clock = new ClockMock();
+    InvoiceUserApi invoiceApi = BrainDeadProxyFactory.createBrainDeadProxyFor(InvoiceUserApi.class);
+    private int hash = 0;
+    DateTime now;
+    
+    public BillingStateCalculator<SubscriptionBundle> createBSCalc() {
+        now = new DateTime();
+        Collection<Invoice> invoices = new ArrayList<Invoice>();
+        invoices.add(createInvoice(now, BigDecimal.ZERO));
+        invoices.add(createInvoice(now.plusDays(1), BigDecimal.TEN));
+        invoices.add(createInvoice(now.plusDays(2), new BigDecimal("100.0")));
+     
+        ((ZombieControl)invoiceApi).addResult("getUnpaidInvoicesByAccountId", invoices);
+            
+        return new BillingStateCalculator<SubscriptionBundle>(invoiceApi, clock) {
+            @Override
+            public BillingState<SubscriptionBundle> calculateBillingState(
+                    SubscriptionBundle overdueable) {
+               return null;
+            }};
+    }
+    
+    public Invoice createInvoice(DateTime date, BigDecimal balance) {
+        Invoice invoice = BrainDeadProxyFactory.createBrainDeadProxyFor(Invoice.class);
+        ((ZombieControl)invoice).addResult("getBalance", balance);
+        ((ZombieControl)invoice).addResult("getInvoiceDate", date);
+        ((ZombieControl)invoice).addResult("hashCode", hash++);
+        
+        return invoice;
+    }
+    
+    @Test(groups={"fast"}, enabled=true)
+    public void testUnpaidInvoices() {
+        BillingStateCalculator<SubscriptionBundle> calc = createBSCalc();
+        SortedSet<Invoice> invoices = calc.unpaidInvoicesFor(new UUID(0L,0L));
+        
+        Assert.assertEquals(invoices.size(), 3);
+        Assert.assertEquals(BigDecimal.ZERO.compareTo(invoices.first().getBalance()), 0);
+        Assert.assertEquals(new BigDecimal("100.0").compareTo(invoices.last().getBalance()), 0);
+    }
+    
+    @Test(groups={"fast"}, enabled=true)
+    public void testSum() {
+        
+        BillingStateCalculator<SubscriptionBundle> calc = createBSCalc();
+        SortedSet<Invoice> invoices = calc.unpaidInvoicesFor(new UUID(0L,0L));
+        Assert.assertEquals(new BigDecimal("110.0").compareTo(calc.sumBalance(invoices)), 0);
+    }
+
+    @Test(groups={"fast"}, enabled=true)
+    public void testEarliest() {
+        
+        BillingStateCalculator<SubscriptionBundle> calc = createBSCalc();
+        SortedSet<Invoice> invoices = calc.unpaidInvoicesFor(new UUID(0L,0L));
+        Assert.assertEquals(calc.earliest(invoices), now);
+    }
+
+    
+    
+    
+}
diff --git a/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java b/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
index 0fda201..ad42504 100644
--- a/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
+++ b/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
@@ -26,7 +26,6 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.UUID;
 
-import com.ning.billing.util.entity.EntityPersistenceException;
 import org.apache.commons.lang.RandomStringUtils;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
@@ -44,6 +43,7 @@ import com.ning.billing.invoice.model.RecurringInvoiceItem;
 import com.ning.billing.payment.TestHelper;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.bus.Bus.EventBusException;
+import com.ning.billing.util.entity.EntityPersistenceException;
 
 public abstract class TestPaymentApi {
     @Inject
@@ -70,9 +70,11 @@ public abstract class TestPaymentApi {
         final Invoice invoice = testHelper.createTestInvoice(account, now, Currency.USD);
         final BigDecimal amount = new BigDecimal("10.00");
         final UUID subscriptionId = UUID.randomUUID();
+        final UUID bundleId = UUID.randomUUID();
 
         invoice.addInvoiceItem(new RecurringInvoiceItem(invoice.getId(),
                                                        subscriptionId,
+                                                       bundleId,
                                                        "test plan", "test phase",
                                                        now,
                                                        now.plusMonths(1),
diff --git a/payment/src/test/java/com/ning/billing/payment/TestHelper.java b/payment/src/test/java/com/ning/billing/payment/TestHelper.java
index d868c9b..da5d4b4 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestHelper.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestHelper.java
@@ -86,7 +86,8 @@ public class TestHelper {
             if (item instanceof RecurringInvoiceItem) {
                 RecurringInvoiceItem recurringInvoiceItem = (RecurringInvoiceItem) item;
                 invoice.addInvoiceItem(new RecurringInvoiceItem(invoice.getId(),
-                                                               recurringInvoiceItem.getSubscriptionId(),
+                        recurringInvoiceItem.getSubscriptionId(),
+                        recurringInvoiceItem.getBundleId(),
                                                                recurringInvoiceItem.getPlanName(),
                                                                recurringInvoiceItem.getPhaseName(),
                                                                recurringInvoiceItem.getStartDate(),
@@ -104,8 +105,9 @@ public class TestHelper {
     public Invoice createTestInvoice(Account account) {
         final DateTime now = new DateTime(DateTimeZone.UTC);
         final UUID subscriptionId = UUID.randomUUID();
+        final UUID bundleId = UUID.randomUUID();
         final BigDecimal amount = new BigDecimal("10.00");
-        final InvoiceItem item = new RecurringInvoiceItem(null, subscriptionId, "test plan", "test phase", now, now.plusMonths(1),
+        final InvoiceItem item = new RecurringInvoiceItem(null, subscriptionId, bundleId, "test plan", "test phase", now, now.plusMonths(1),
                 amount, new BigDecimal("1.0"), Currency.USD, now);
 
         return createTestInvoice(account, now, Currency.USD, item);
diff --git a/payment/src/test/java/com/ning/billing/payment/TestRetryService.java b/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
index ac33d99..c71915c 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
@@ -111,11 +111,13 @@ public class TestRetryService {
         final Invoice invoice = testHelper.createTestInvoice(account, clock.getUTCNow(), Currency.USD);
         final BigDecimal amount = new BigDecimal("10.00");
         final UUID subscriptionId = UUID.randomUUID();
+        final UUID bundleId = UUID.randomUUID();
 
         final DateTime startDate = clock.getUTCNow();
         final DateTime endDate = startDate.plusMonths(1);
         invoice.addInvoiceItem(new RecurringInvoiceItem(invoice.getId(),
                                                        subscriptionId,
+                                                       bundleId,
                                                        "test plan", "test phase",
                                                        startDate,
                                                        endDate,
@@ -152,11 +154,13 @@ public class TestRetryService {
         final Invoice invoice = testHelper.createTestInvoice(account, clock.getUTCNow(), Currency.USD);
         final BigDecimal amount = new BigDecimal("10.00");
         final UUID subscriptionId = UUID.randomUUID();
+        final UUID bundleId = UUID.randomUUID();
 
         final DateTime now = clock.getUTCNow();
 
         invoice.addInvoiceItem(new RecurringInvoiceItem(invoice.getId(),
                                                        subscriptionId,
+                                                       bundleId,
                                                        "test plan", "test phase",
                                                        now,
                                                        now.plusMonths(1),

pom.xml 4(+4 -0)

diff --git a/pom.xml b/pom.xml
index c0c46a2..647ed92 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,6 +46,7 @@
         <module>entitlement</module>
         <module>invoice</module>
         <module>payment</module>
+        <module>overdue</module>
         <module>util</module>
     </modules>
     <dependencyManagement>
@@ -374,6 +375,7 @@
                                 <exclude>**/.project</exclude>
                                 <exclude>.git/**</exclude>
                                 <exclude>.gitignore</exclude>
+                                <exclude>**/.classpath</exclude>
                                 <exclude>ignore/**</exclude>
                                 <exclude>API.txt</exclude>
                                 <exclude>RELEASE.sh</exclude>
@@ -395,6 +397,8 @@
                                 <exclude>**/*.dont-let-git-remove-this-directory</exclude>
                                 <exclude>**/test-output/**</exclude>
                                 <exclude>**/bin/**</exclude>
+                                <exclude>**/target/**</exclude>
+                                <exclude>**/.settings/**</exclude>
                                 <exclude>.travis.yml</exclude>
                             </excludes>
                         </configuration>
diff --git a/util/src/test/java/com/ning/billing/mock/BrainDeadProxyFactory.java b/util/src/test/java/com/ning/billing/mock/BrainDeadProxyFactory.java
index 7404331..9cfbe9f 100644
--- a/util/src/test/java/com/ning/billing/mock/BrainDeadProxyFactory.java
+++ b/util/src/test/java/com/ning/billing/mock/BrainDeadProxyFactory.java
@@ -68,7 +68,7 @@ public class BrainDeadProxyFactory {
                     		throw ((Throwable) result);
                     	}
                         return result;
-                    } else {
+                    }  else {
                         log.error(String.format("No result for Method: '%s' on Class '%s'",method.getName(), method.getDeclaringClass().getName()));
                         throw new UnsupportedOperationException();
                     }