killbill-aplcache

Catalog updates for overdue. Included addint the concept of

4/6/2012 9:00:02 PM

Changes

Details

diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockIEntitlementUserApi.java b/analytics/src/test/java/com/ning/billing/analytics/MockIEntitlementUserApi.java
index bde1bcb..6f80e03 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockIEntitlementUserApi.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockIEntitlementUserApi.java
@@ -20,13 +20,12 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
+
 import org.joda.time.DateTime;
-import com.ning.billing.account.api.AccountData;
-import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.PhaseType;
+
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
+import com.ning.billing.catalog.api.overdue.OverdueState;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
-
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
@@ -73,6 +72,11 @@ public class MockIEntitlementUserApi implements EntitlementUserApi
             {
                 return key;
             }
+
+            @Override
+            public OverdueState<SubscriptionBundle> getOverdueState() {
+                throw new UnsupportedOperationException();
+            }
         };
     }
 
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 715317e..d9596e4 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
@@ -22,9 +22,12 @@ public interface OverdueState<T extends Overdueable> {
     public String getName();
 
     public String getExternalMessage();
+    
+    public int getDaysBetweenPaymentRetries();
 
-    public boolean applyCancel();
+    public boolean entitlementDisabledAndChangesBlocked();
 
+    public boolean changesBlocked();
+    
     public boolean isClearState();
-
 }
\ No newline at end of file
diff --git a/api/src/main/java/com/ning/billing/catalog/api/overdue/OverdueStateSet.java b/api/src/main/java/com/ning/billing/catalog/api/overdue/OverdueStateSet.java
index c7127d4..5b726c2 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/overdue/OverdueStateSet.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/overdue/OverdueStateSet.java
@@ -22,11 +22,11 @@ import com.ning.billing.catalog.api.CatalogApiException;
 
 public interface OverdueStateSet<T extends Overdueable> {
 
-    public abstract OverdueState<T> findClearState();
+    public abstract OverdueState<T> findClearState() throws CatalogApiException;
 
     public abstract OverdueState<T> findState(String stateName) throws CatalogApiException;
 
-    public abstract OverdueState<T> calculateOverdueState(BillingState<T> billingState, DateTime now);
+    public abstract OverdueState<T> calculateOverdueState(BillingState<T> billingState, DateTime now) throws CatalogApiException;
 
     public abstract DateTime dateOfNextCheck(BillingState<T> billingState, DateTime now);
 
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundle.java b/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundle.java
index baa6843..df32c58 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundle.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundle.java
@@ -20,6 +20,7 @@ import java.util.UUID;
 
 import org.joda.time.DateTime;
 
+import com.ning.billing.catalog.api.overdue.OverdueState;
 import com.ning.billing.catalog.api.overdue.Overdueable;
 
 public interface SubscriptionBundle extends Overdueable {
@@ -31,4 +32,6 @@ public interface SubscriptionBundle extends Overdueable {
     public DateTime getStartDate();
 
     public String getKey();
+
+    public OverdueState<SubscriptionBundle> getOverdueState();
 }
diff --git a/api/src/main/java/com/ning/billing/ErrorCode.java b/api/src/main/java/com/ning/billing/ErrorCode.java
index 36794e3..d51a16a 100644
--- a/api/src/main/java/com/ning/billing/ErrorCode.java
+++ b/api/src/main/java/com/ning/billing/ErrorCode.java
@@ -111,7 +111,7 @@ public enum ErrorCode {
      * Overdue
      */
     CAT_NO_SUCH_OVEDUE_STATE(2070, "No such overdue state '%s'"),
-
+    CAT_MISSING_CLEAR_STATE(2071, "Missing a clear state"),
    /*
     *
     * Range 3000 : ACCOUNT
@@ -162,7 +162,7 @@ public enum ErrorCode {
      * 
      */
     OVERDUE_OVERDUEABLE_NOT_SUPPORTED(5001, "The Overdueable type '%s' is not supported"), 
-    OVERDUE_CAT_ERROR_ENCOUNTERED(5002,"Catalog error encountered when attempting to refresh the state of Overdueable: id='%s', type='%s'")
+    OVERDUE_CAT_ERROR_ENCOUNTERED(5002,"Catalog error encountered when attempting to refresh the state of Overdueable: id='%s', type='%s'"), 
     
     
     ;
diff --git a/api/src/main/java/com/ning/billing/overdue/OverdueUserApi.java b/api/src/main/java/com/ning/billing/overdue/OverdueUserApi.java
index 0cfbb6b..006b18f 100644
--- a/api/src/main/java/com/ning/billing/overdue/OverdueUserApi.java
+++ b/api/src/main/java/com/ning/billing/overdue/OverdueUserApi.java
@@ -16,6 +16,7 @@
 
 package com.ning.billing.overdue;
 
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.overdue.BillingState;
 import com.ning.billing.catalog.api.overdue.OverdueError;
 import com.ning.billing.catalog.api.overdue.OverdueState;
@@ -23,7 +24,9 @@ import com.ning.billing.catalog.api.overdue.Overdueable;
 
 public interface OverdueUserApi {
 
-    public <T extends Overdueable> OverdueState<T> refreshOverdueStateFor(T overdueable) throws OverdueError;
+    public <T extends Overdueable> OverdueState<T> refreshOverdueStateFor(T overdueable) throws OverdueError, CatalogApiException;
 
     public <T extends Overdueable> void setOverrideBillingStateForAccount(T overdueable, BillingState<T> state) throws OverdueError;
+
+    public <T extends Overdueable> OverdueState<T> getOverdueStateFor(T overdueable) throws OverdueError;
 }
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 354782a..579b759 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
@@ -33,8 +33,6 @@ import com.ning.billing.util.config.ValidationErrors;
 public class DefaultOverdueState<T extends Overdueable> extends ValidatingConfig<StandaloneCatalog>  implements OverdueState<T> {
 
     private static final int MAX_NAME_LENGTH = 50;
-
-    // TODO - need to implement Clear states
     
     @XmlElement(required=false, name="condition")
 	private DefaultCondition<T> condition;
@@ -46,9 +44,15 @@ public class DefaultOverdueState<T extends Overdueable> extends ValidatingConfig
 	@XmlElement(required=false, name="externalMessage")
 	private String externalMessage = "";
 
-	@XmlElement(required=false, name="applyCancel")
-	private boolean applyCancel = false;
-	
+    @XmlElement(required=false, name="overrideEntitlementAndChangesBlocked")
+    private Boolean overrideEntitlement = false;
+    
+    @XmlElement(required=false, name="changesBlocked")
+    private Boolean changesBlocked = false;
+    
+    @XmlElement(required=false, name="daysBetweenPaymentRetries")
+    private Integer daysBetweenPaymentRetries = 8;
+    
 	//Other actions could include
 	// - send email
 	// - trigger payment retry?
@@ -73,12 +77,17 @@ public class DefaultOverdueState<T extends Overdueable> extends ValidatingConfig
 		return externalMessage;
 	}
 	
+    @Override
+    public boolean changesBlocked() {
+        return changesBlocked && overrideEntitlement;
+    }
+
 	/* (non-Javadoc)
      * @see com.ning.billing.catalog.overdue.OverdueState#applyCancel()
      */
 	@Override
-    public boolean applyCancel() {
-		return applyCancel;
+    public boolean entitlementDisabledAndChangesBlocked() {
+		return overrideEntitlement;
 	}
 	
 	
@@ -99,7 +108,7 @@ public class DefaultOverdueState<T extends Overdueable> extends ValidatingConfig
 	}
 
 	protected DefaultOverdueState<T> setCancel(boolean cancel) {
-		this.applyCancel = cancel;
+		this.overrideEntitlement = cancel;
 		return this;
 	}
 
@@ -122,4 +131,10 @@ public class DefaultOverdueState<T extends Overdueable> extends ValidatingConfig
         return errors;
     }
 
+    @Override
+    public int getDaysBetweenPaymentRetries() {
+         return daysBetweenPaymentRetries;
+    }
+
+
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/overdue/DefaultOverdueStateSet.java b/catalog/src/main/java/com/ning/billing/catalog/overdue/DefaultOverdueStateSet.java
index 77c691d..73fdbe1 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/overdue/DefaultOverdueStateSet.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/overdue/DefaultOverdueStateSet.java
@@ -19,25 +19,36 @@ package com.ning.billing.catalog.overdue;
 import org.apache.commons.lang.NotImplementedException;
 import org.joda.time.DateTime;
 
+import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.StandaloneCatalog;
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.overdue.BillingState;
 import com.ning.billing.catalog.api.overdue.OverdueStateSet;
 import com.ning.billing.catalog.api.overdue.Overdueable;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.util.config.ValidatingConfig;
+import com.ning.billing.util.config.ValidationErrors;
 
 public abstract class DefaultOverdueStateSet<T extends Overdueable> extends ValidatingConfig<StandaloneCatalog> implements OverdueStateSet<T> {
     private DefaultOverdueState<T> clearState;
     
     protected abstract DefaultOverdueState<T>[] getStates();
     
-    protected abstract DefaultOverdueState<T> getClearState();
+    private DefaultOverdueState<T> getClearState() throws CatalogApiException {
+        for(DefaultOverdueState<T> overdueState : getStates()) {
+            if(overdueState.isClearState()) {   
+                return overdueState;
+            }
+        }
+        throw new CatalogApiException(ErrorCode.CAT_MISSING_CLEAR_STATE);
+    }
     
     
     /* (non-Javadoc)
      * @see com.ning.billing.catalog.overdue.OverdueBillingState#findClearState()
      */
     @Override
-    public DefaultOverdueState<T> findClearState() {
+    public DefaultOverdueState<T> findClearState() throws CatalogApiException {
         if (clearState != null) {
             clearState = getClearState();
         }
@@ -48,7 +59,7 @@ public abstract class DefaultOverdueStateSet<T extends Overdueable> extends Vali
      * @see com.ning.billing.catalog.overdue.OverdueBillingState#calculateOverdueState(com.ning.billing.catalog.api.overdue.BillingState, org.joda.time.DateTime)
      */
     @Override
-    public DefaultOverdueState<T> calculateOverdueState(BillingState<T> billingState, DateTime now) {         
+    public DefaultOverdueState<T> calculateOverdueState(BillingState<T> billingState, DateTime now) throws CatalogApiException {         
             for(DefaultOverdueState<T> overdueState : getStates()) {
                 if(overdueState.getCondition().evaluate(billingState, now)) {   
                     return overdueState;
@@ -62,5 +73,23 @@ public abstract class DefaultOverdueStateSet<T extends Overdueable> extends Vali
         throw new NotImplementedException();
     }
         
+
+    @Override
+    public ValidationErrors validate(StandaloneCatalog root,
+            ValidationErrors errors) {
+        for(DefaultOverdueState<T> state: getStates()) {
+            state.validate(root, errors);
+        }
+        try {
+            getClearState();
+        } catch (CatalogApiException e) {
+            if(e.getCode() == ErrorCode.CAT_MISSING_CLEAR_STATE.getCode()) {
+                errors.add("Overdue state set is missing a clear state.", 
+                        root.getCatalogURI(), this.getClass(), "");
+                }
+        }
+        
+        return errors;
+    }
       
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/overdue/OverdueStatesBundle.java b/catalog/src/main/java/com/ning/billing/catalog/overdue/OverdueStatesBundle.java
index 24aee7d..b96f26c 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/overdue/OverdueStatesBundle.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/overdue/OverdueStatesBundle.java
@@ -35,20 +35,6 @@ public class OverdueStatesBundle extends DefaultOverdueStateSet<SubscriptionBund
     }
 
     @Override
-    protected DefaultOverdueState<SubscriptionBundle> getClearState() {
-        return null;
-    }
-
-    @Override
-    public ValidationErrors validate(StandaloneCatalog root,
-            ValidationErrors errors) {
-        for(DefaultOverdueState<SubscriptionBundle> state: bundleOverdueStates) {
-            state.validate(root, errors);
-        }
-        return errors;
-    }
-
-    @Override
     public OverdueState<SubscriptionBundle> findState(String stateName) throws CatalogApiException {
         for(DefaultOverdueState<SubscriptionBundle> state: bundleOverdueStates) {
             if(state.getName().equals(stateName) ) { return state; }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java
index baf45f1..20bad8d 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java
@@ -19,10 +19,11 @@ package com.ning.billing.entitlement.api.user;
 import java.util.List;
 import java.util.UUID;
 
-import com.ning.billing.catalog.api.Catalog;
 import org.joda.time.DateTime;
+
 import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
+import com.ning.billing.catalog.api.Catalog;
 import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.catalog.api.Plan;
@@ -30,6 +31,7 @@ import com.ning.billing.catalog.api.PlanPhase;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.catalog.api.PriceListSet;
 import com.ning.billing.catalog.api.Product;
+import com.ning.billing.catalog.api.overdue.OverdueState;
 import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 import com.ning.billing.entitlement.api.user.SubscriptionFactory.SubscriptionBuilder;
 import com.ning.billing.entitlement.engine.addon.AddonUtils;
@@ -88,9 +90,15 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
 
     @Override
     public SubscriptionBundle createBundleForAccount(UUID accountId, String bundleName)
-    throws EntitlementUserApiException {
-        SubscriptionBundleData bundle = new SubscriptionBundleData(bundleName, accountId);
-        return dao.createSubscriptionBundle(bundle);
+            throws EntitlementUserApiException {
+        OverdueState<SubscriptionBundle> clearState;
+        try {
+            clearState = catalogService.getCurrentCatalog().currentBundleOverdueStateSet().findClearState();
+            SubscriptionBundleData bundle = new SubscriptionBundleData(bundleName, accountId);
+            return dao.createSubscriptionBundle(bundle);
+        } catch (CatalogApiException e) {
+            throw new EntitlementUserApiException(e);
+        }
     }
 
     @Override
@@ -153,11 +161,11 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
             }
 
             SubscriptionData subscription = apiService.createPlan(new SubscriptionBuilder()
-                .setId(UUID.randomUUID())
-                .setBundleId(bundleId)
-                .setCategory(plan.getProduct().getCategory())
-                .setBundleStartDate(bundleStartDate)
-                .setStartDate(effectiveDate),
+            .setId(UUID.randomUUID())
+            .setBundleId(bundleId)
+            .setCategory(plan.getProduct().getCategory())
+            .setBundleStartDate(bundleStartDate)
+            .setStartDate(effectiveDate),
             plan, spec.getPhaseType(), realPriceList, requestedDate, effectiveDate, now);
 
             return subscription;
@@ -168,7 +176,7 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
 
 
     private void checkAddonCreationRights(SubscriptionData baseSubscription, Plan targetAddOnPlan)
-        throws EntitlementUserApiException, CatalogApiException {
+            throws EntitlementUserApiException, CatalogApiException {
 
         if (baseSubscription.getState() != SubscriptionState.ACTIVE) {
             throw new EntitlementUserApiException(ErrorCode.ENT_CREATE_AO_BP_NON_ACTIVE, targetAddOnPlan.getName());
@@ -186,20 +194,20 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
         }
     }
 
-	@Override
-	public DateTime getNextBillingDate(UUID accountId) {
-		List<SubscriptionBundle> bundles = getBundlesForAccount(accountId);
-		DateTime result = null;
-		for(SubscriptionBundle bundle : bundles) {
-			List<Subscription> subscriptions = getSubscriptionsForBundle(bundle.getId());
-			for(Subscription subscription : subscriptions) {
-				DateTime chargedThruDate = subscription.getChargedThroughDate();
-				if(result == null ||
-						(chargedThruDate != null && chargedThruDate.isBefore(result))) {
-					result = subscription.getChargedThroughDate();
-				}
-			}
-		}
-		return result;
-	}
+    @Override
+    public DateTime getNextBillingDate(UUID accountId) {
+        List<SubscriptionBundle> bundles = getBundlesForAccount(accountId);
+        DateTime result = null;
+        for(SubscriptionBundle bundle : bundles) {
+            List<Subscription> subscriptions = getSubscriptionsForBundle(bundle.getId());
+            for(Subscription subscription : subscriptions) {
+                DateTime chargedThruDate = subscription.getChargedThroughDate();
+                if(result == null ||
+                        (chargedThruDate != null && chargedThruDate.isBefore(result))) {
+                    result = subscription.getChargedThroughDate();
+                }
+            }
+        }
+        return result;
+    }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundleData.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundleData.java
index 8cc2573..38a6ff5 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundleData.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundleData.java
@@ -16,9 +16,11 @@
 
 package com.ning.billing.entitlement.api.user;
 
+import java.util.UUID;
+
 import org.joda.time.DateTime;
 
-import java.util.UUID;
+import com.ning.billing.catalog.api.overdue.OverdueState;
 
 public class SubscriptionBundleData implements SubscriptionBundle {
 
@@ -26,17 +28,19 @@ public class SubscriptionBundleData implements SubscriptionBundle {
     private final String key;
     private final UUID accountId;
     private final DateTime startDate;
+    private final OverdueState<SubscriptionBundle> overdueState;
 
     public SubscriptionBundleData(String name, UUID accountId) {
-        this(UUID.randomUUID(), name, accountId, null);
+        this(UUID.randomUUID(), name, accountId, null, null);
     }
 
-    public SubscriptionBundleData(UUID id, String key, UUID accountId, DateTime startDate) {
+    public SubscriptionBundleData(UUID id, String key, UUID accountId, DateTime startDate, OverdueState<SubscriptionBundle> overdueState) {
         super();
         this.id = id;
         this.key = key;
         this.accountId = accountId;
         this.startDate = startDate;
+        this.overdueState = overdueState;
     }
 
     @Override
@@ -60,4 +64,9 @@ public class SubscriptionBundleData implements SubscriptionBundle {
     public DateTime getStartDate() {
         return startDate;
     }
+
+    @Override
+    public OverdueState<SubscriptionBundle> getOverdueState() {
+        return overdueState;
+    }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/BundleSqlDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/BundleSqlDao.java
index 88123ca..e6b6d2a 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/BundleSqlDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/BundleSqlDao.java
@@ -16,10 +16,11 @@
 
 package com.ning.billing.entitlement.engine.dao;
 
-import com.ning.billing.entitlement.api.user.SubscriptionBundle;
-import com.ning.billing.entitlement.api.user.SubscriptionBundleData;
-import com.ning.billing.util.entity.BinderBase;
-import com.ning.billing.util.entity.MapperBase;
+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,10 +35,12 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.List;
-import java.util.UUID;
+import com.google.inject.Inject;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.ning.billing.entitlement.api.user.SubscriptionBundleData;
+import com.ning.billing.util.entity.BinderBase;
+import com.ning.billing.util.entity.MapperBase;
+import com.ning.billing.util.overdue.OverdueAccessApi;
 
 @ExternalizedSqlViaStringTemplate3()
 public interface BundleSqlDao extends Transactional<BundleSqlDao>, CloseMe, Transmogrifier {
@@ -71,6 +74,7 @@ public interface BundleSqlDao extends Transactional<BundleSqlDao>, CloseMe, Tran
     }
 
     public static class ISubscriptionBundleSqlMapper extends MapperBase implements ResultSetMapper<SubscriptionBundle> {
+        
         @Override
         public SubscriptionBundle map(int arg, ResultSet r,
                 StatementContext ctx) throws SQLException {
@@ -79,7 +83,7 @@ public interface BundleSqlDao extends Transactional<BundleSqlDao>, CloseMe, Tran
             String name = r.getString("name");
             UUID accountId = UUID.fromString(r.getString("account_id"));
             DateTime startDate = getDate(r, "start_dt");
-            SubscriptionBundleData bundle = new SubscriptionBundleData(id, name, accountId, startDate);
+            SubscriptionBundleData bundle = new SubscriptionBundleData(id, name, accountId, startDate, null);
             return bundle;
         }
 
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java
index cd688d3..413cd3e 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java
@@ -24,8 +24,6 @@ import java.util.Date;
 import java.util.List;
 import java.util.UUID;
 
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.customfield.dao.CustomFieldDao;
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.IDBI;
 import org.skife.jdbi.v2.Transaction;
@@ -38,8 +36,11 @@ import com.google.common.base.Predicate;
 import com.google.common.collect.Collections2;
 import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
+import com.ning.billing.catalog.api.CatalogApiException;
+import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.ProductCategory;
+import com.ning.billing.catalog.api.overdue.OverdueState;
 import com.ning.billing.entitlement.api.migration.AccountMigrationData;
 import com.ning.billing.entitlement.api.migration.AccountMigrationData.BundleMigrationData;
 import com.ning.billing.entitlement.api.migration.AccountMigrationData.SubscriptionMigrationData;
@@ -59,13 +60,16 @@ import com.ning.billing.entitlement.events.user.ApiEventCancel;
 import com.ning.billing.entitlement.events.user.ApiEventChange;
 import com.ning.billing.entitlement.events.user.ApiEventType;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
+import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.customfield.CustomField;
+import com.ning.billing.util.customfield.dao.CustomFieldDao;
 import com.ning.billing.util.customfield.dao.CustomFieldSqlDao;
 import com.ning.billing.util.notificationq.NotificationKey;
 import com.ning.billing.util.notificationq.NotificationQueue;
 import com.ning.billing.util.notificationq.NotificationQueueService;
 import com.ning.billing.util.notificationq.NotificationQueueService.NoSuchNotificationQueue;
+import com.ning.billing.util.overdue.OverdueAccessApi;
 
 
 public class EntitlementSqlDao implements EntitlementDao {
@@ -80,11 +84,15 @@ public class EntitlementSqlDao implements EntitlementDao {
     private final NotificationQueueService notificationQueueService;
     private final AddonUtils addonUtils;
     private final CustomFieldDao customFieldDao;
+    private final OverdueAccessApi overdueApi;
+    private final CatalogService catalogService;
 
     @Inject
     public EntitlementSqlDao(final IDBI dbi, final Clock clock, final SubscriptionFactory factory,
                              final AddonUtils addonUtils, final NotificationQueueService notificationQueueService,
-                             final CustomFieldDao customFieldDao) {
+                             final CustomFieldDao customFieldDao,
+                             final OverdueAccessApi overdueApi,
+                             final CatalogService catalogService) {
         this.clock = clock;
         this.factory = factory;
         this.subscriptionsDao = dbi.onDemand(SubscriptionSqlDao.class);
@@ -93,6 +101,8 @@ public class EntitlementSqlDao implements EntitlementDao {
         this.notificationQueueService = notificationQueueService;
         this.addonUtils = addonUtils;
         this.customFieldDao = customFieldDao;
+        this.overdueApi = overdueApi;
+        this.catalogService = catalogService;
     }
 
     @Override
@@ -103,12 +113,12 @@ public class EntitlementSqlDao implements EntitlementDao {
     @Override
     public List<SubscriptionBundle> getSubscriptionBundleForAccount(
             final UUID accountId) {
-        return bundlesDao.getBundleFromAccount(accountId.toString());
+        return applyOverdueState(bundlesDao.getBundleFromAccount(accountId.toString()));
     }
 
     @Override
     public SubscriptionBundle getSubscriptionBundleFromId(final UUID bundleId) {
-        return bundlesDao.getBundleFromId(bundleId.toString());
+        return applyOverdueState(bundlesDao.getBundleFromId(bundleId.toString()));
     }
 
     @Override
@@ -615,4 +625,23 @@ public class EntitlementSqlDao implements EntitlementDao {
             subscription.setFields(fields);
         }
     }
+ 
+    private List<SubscriptionBundle> applyOverdueState(final List<SubscriptionBundle> bundles)  { 
+        List<SubscriptionBundle> result = new ArrayList<SubscriptionBundle>();
+        for(SubscriptionBundle bundle : bundles) {
+            result.add(applyOverdueState(bundle));
+        }
+        return result;
+    }
+
+    private SubscriptionBundle applyOverdueState(final SubscriptionBundle bundle)  {
+        try {
+            String name = overdueApi.getOverdueStateNameFor(bundle);
+            OverdueState<SubscriptionBundle> state = catalogService.getCurrentCatalog().currentBundleOverdueStateSet().findState(name);
+            return new SubscriptionBundleData(bundle.getId(),bundle.getKey(),bundle.getAccountId(), bundle.getStartDate(), state);
+        } catch (CatalogApiException e) {
+           throw new EntitlementError(e);
+        }
+    }
+    
 }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java
index f89db88..c754b2c 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java
@@ -98,7 +98,7 @@ public class TestDefaultEntitlementBillingApi {
 	@BeforeMethod(alwaysRun=true)
 	public void setupEveryTime() {
 		bundles = new ArrayList<SubscriptionBundle>();
-		final SubscriptionBundle bundle = new SubscriptionBundleData( zeroId,"TestKey", oneId,  clock.getUTCNow().minusDays(4));
+		final SubscriptionBundle bundle = new SubscriptionBundleData( zeroId,"TestKey", oneId,  clock.getUTCNow().minusDays(4), null);
 		bundles.add(bundle);
 
 
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoSql.java
index 65d8495..323dd72 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoSql.java
@@ -26,10 +26,12 @@ import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
 import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 
 import com.google.inject.Inject;
+import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.entitlement.api.user.SubscriptionFactory;
 import com.ning.billing.entitlement.engine.addon.AddonUtils;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.notificationq.NotificationQueueService;
+import com.ning.billing.util.overdue.OverdueAccessApi;
 
 public class MockEntitlementDaoSql extends EntitlementSqlDao implements MockEntitlementDao {
 
@@ -37,8 +39,9 @@ public class MockEntitlementDaoSql extends EntitlementSqlDao implements MockEnti
 
     @Inject
     public MockEntitlementDaoSql(IDBI dbi, Clock clock, SubscriptionFactory factory, AddonUtils addonUtils, NotificationQueueService notificationQueueService,
-                                 CustomFieldDao customFieldDao) {
-        super(dbi, clock, factory, addonUtils, notificationQueueService, customFieldDao);
+                                 CustomFieldDao customFieldDao, final OverdueAccessApi overdueApi,
+                                 final CatalogService catalogService) {
+        super(dbi, clock, factory, addonUtils, notificationQueueService, customFieldDao, overdueApi, catalogService);
         this.resetDao = dbi.onDemand(ResetSqlDao.class);
     }
 
diff --git a/overdue/src/main/java/com/ning/billing/ovedue/notification/DefaultOverdueCheckPoster.java b/overdue/src/main/java/com/ning/billing/ovedue/notification/DefaultOverdueCheckPoster.java
index e699414..e6be7b1 100644
--- a/overdue/src/main/java/com/ning/billing/ovedue/notification/DefaultOverdueCheckPoster.java
+++ b/overdue/src/main/java/com/ning/billing/ovedue/notification/DefaultOverdueCheckPoster.java
@@ -65,7 +65,7 @@ public class DefaultOverdueCheckPoster implements OverdueCheckPoster {
         try {
             checkOverdueQueue = notificationQueueService.getNotificationQueue(DefaultOverdueService.OVERDUE_SERVICE_NAME,
                 DefaultOverdueCheckNotifier.OVERDUE_CHECK_NOTIFIER_QUEUE);
-            checkOverdueQueue.clearNotificationsFor(overdueable.getId());
+            checkOverdueQueue.removeNotificationsByKey(overdueable.getId());
         } catch (NoSuchNotificationQueue e) {
             log.error("Attempting to clear items from a non-existent queue (DefaultOverdueCheck).", e);
         }
diff --git a/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java b/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java
index fd72cee..1cd8e60 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java
@@ -29,24 +29,40 @@ import com.ning.billing.catalog.api.overdue.OverdueState;
 import com.ning.billing.catalog.api.overdue.OverdueStateSet;
 import com.ning.billing.catalog.api.overdue.Overdueable;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
-import com.ning.billing.overdue.OverdueService;
 import com.ning.billing.overdue.OverdueUserApi;
 import com.ning.billing.overdue.wrapper.OverdueWrapper;
 import com.ning.billing.overdue.wrapper.OverdueWrapperFactory;
-import com.ning.billing.util.overdue.dao.OverdueAccessDao;
+import com.ning.billing.util.overdue.OverdueAccessApi;
 
 public class DefaultOverdueUserApi implements OverdueUserApi{
 
     
     private final OverdueWrapperFactory factory;
+    private final OverdueAccessApi accessApi;
+    private final CatalogService catalogService;
    
     @Inject
-    public DefaultOverdueUserApi(OverdueWrapperFactory factory) {
+    public DefaultOverdueUserApi(OverdueWrapperFactory factory, OverdueAccessApi accessApi,  CatalogService catalogService) {
         this.factory = factory;
+        this.accessApi = accessApi;
+        this.catalogService = catalogService;
     }
     
+    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Overdueable> OverdueState<T> refreshOverdueStateFor(T overdueable) throws OverdueError {
+    public <T extends Overdueable> OverdueState<T> getOverdueStateFor(T overdueable) throws OverdueError {
+        try {
+            String stateName = accessApi.getOverdueStateNameFor(overdueable);
+            StaticCatalog catalog = catalogService.getCurrentCatalog();
+            OverdueStateSet<SubscriptionBundle> states = catalog.currentBundleOverdueStateSet();
+            return (OverdueState<T>) states.findState(stateName);
+        } catch (CatalogApiException e) {
+            throw new OverdueError(e, ErrorCode.OVERDUE_CAT_ERROR_ENCOUNTERED,overdueable.getId(), overdueable.getClass().getSimpleName());
+        }
+    }
+    
+    @Override
+    public <T extends Overdueable> OverdueState<T> refreshOverdueStateFor(T overdueable) throws OverdueError, CatalogApiException {
         OverdueWrapper<T> wrapper = factory.createOverdueWrapperFor(overdueable);
         return wrapper.refresh();
     } 
diff --git a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
index cc943c8..f110d75 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
@@ -16,6 +16,7 @@
 
 package com.ning.billing.overdue.wrapper;
 
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.overdue.BillingState;
 import com.ning.billing.catalog.api.overdue.OverdueError;
 import com.ning.billing.catalog.api.overdue.OverdueState;
@@ -47,13 +48,15 @@ public class OverdueWrapper<T extends Overdueable> {
         this.overdueStateApplicator = overdueStateApplicator;
     }
 
-    public OverdueState<T> refresh() throws OverdueError {
+    public OverdueState<T> refresh() throws OverdueError, CatalogApiException {
+        OverdueState<T> nextOverdueState;
         BillingState<T> billingState = billingStateCalcuator.calculateBillingState(overdueable);
         String previousOverdueStateName = api.getOverdueStateNameFor(overdueable);
-        OverdueState<T> nextOverdueState = overdueStateSet.calculateOverdueState(billingState, clock.getUTCNow());
+        nextOverdueState = overdueStateSet.calculateOverdueState(billingState, clock.getUTCNow());
         if(!previousOverdueStateName.equals(nextOverdueState.getName())) {
             overdueStateApplicator.apply(overdueable, nextOverdueState, nextOverdueState, overdueStateSet.dateOfNextCheck(billingState, clock.getUTCNow())); 
         }
+
         return nextOverdueState;
     }
 }
\ No newline at end of file
diff --git a/util/src/main/java/com/ning/billing/util/overdue/DefaultOverdueAcessApi.java b/util/src/main/java/com/ning/billing/util/overdue/DefaultOverdueAcessApi.java
index eb1860e..67d6948 100644
--- a/util/src/main/java/com/ning/billing/util/overdue/DefaultOverdueAcessApi.java
+++ b/util/src/main/java/com/ning/billing/util/overdue/DefaultOverdueAcessApi.java
@@ -40,16 +40,4 @@ public class DefaultOverdueAcessApi implements OverdueAccessApi {
         return dao.getOverdueStateNameFor(overdueable);
     }
 
-    @SuppressWarnings("unchecked")
-    @Override
-    public <T extends Overdueable> OverdueState<T> getOverdueStateFor(T overdueable, StaticCatalog catalog) throws OverdueError {
-        try {
-            String stateName = getOverdueStateNameFor(overdueable);
-            OverdueStateSet<SubscriptionBundle> states = catalog.currentBundleOverdueStateSet();
-            return (OverdueState<T>) states.findState(stateName);
-        } catch (CatalogApiException e) {
-            throw new OverdueError(e, ErrorCode.OVERDUE_CAT_ERROR_ENCOUNTERED,overdueable.getId(), overdueable.getClass().getSimpleName());
-        }
-    }
-
 }
diff --git a/util/src/main/java/com/ning/billing/util/overdue/OverdueAccessApi.java b/util/src/main/java/com/ning/billing/util/overdue/OverdueAccessApi.java
index 496a059..5fd9c0d 100644
--- a/util/src/main/java/com/ning/billing/util/overdue/OverdueAccessApi.java
+++ b/util/src/main/java/com/ning/billing/util/overdue/OverdueAccessApi.java
@@ -26,8 +26,5 @@ public interface OverdueAccessApi {
 
     public String getOverdueStateNameFor(Overdueable overdueable);
 
-    public <T extends Overdueable> OverdueState<T> getOverdueStateFor(T overdueable, StaticCatalog catalog)
-            throws OverdueError;
-
 
 }
diff --git a/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java b/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java
index 6c60a8c..bdd7689 100644
--- a/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java
+++ b/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java
@@ -431,7 +431,7 @@ public class TestNotificationQueue {
                 new NotificationQueueHandler() {
             @Override
             public void handleReadyNotification(String key, DateTime eventDateTime) {
-                    if(key.equals(notificationKey) || key.equals(notificationKey2)) { //ignore stray events from other tests
+                    if(key.equals(notificationKey) || key.equals(notificationKey2)) { //ig nore stray events from other tests
                         log.info("Received notification with key: " + notificationKey);
                         eventsReceived++;
                     }