killbill-aplcache

Merge pull request #676 from sruthipendyala/work-for-release-0.19.x Adding

12/21/2016 9:02:03 PM

Changes

Details

diff --git a/catalog/src/main/java/org/killbill/billing/catalog/caching/EhCacheOverriddenPlanCache.java b/catalog/src/main/java/org/killbill/billing/catalog/caching/EhCacheOverriddenPlanCache.java
index cfe56a9..6350016 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/caching/EhCacheOverriddenPlanCache.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/caching/EhCacheOverriddenPlanCache.java
@@ -211,7 +211,7 @@ public class EhCacheOverriddenPlanCache implements OverriddenPlanCache {
             }).orNull();
 
             if(overriddenTierBlock != null) {
-                blockPriceOverrides.add(new DefaultTieredBlockPriceOverride(overriddenTierBlock.getParentUnitName(), overriddenTierBlock.getSize(), overriddenTierBlock.getPrice(), overriddenTierBlock.getMax()));
+                blockPriceOverrides.add(new DefaultTieredBlockPriceOverride(overriddenTierBlock.getParentUnitName(), overriddenTierBlock.getSize(), overriddenTierBlock.getPrice(), Currency.valueOf(overriddenTierBlock.getCurrency()), overriddenTierBlock.getMax()));
             }
         }
         return blockPriceOverrides;
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseUsageModelDao.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseUsageModelDao.java
index b4e8f7f..5cf6d95 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseUsageModelDao.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseUsageModelDao.java
@@ -21,8 +21,8 @@ import org.joda.time.DateTime;
 
 public class CatalogOverridePhaseUsageModelDao {
 
-    private Short usageNumber;
     private Long recordId;
+    private Short usageNumber;
     private Long usageDefRecordId;
     private Long targetPhaseDefRecordId;
     private DateTime createdDate;
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideTierBlockModelDao.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideTierBlockModelDao.java
index 8235a08..5bcfdc6 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideTierBlockModelDao.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideTierBlockModelDao.java
@@ -23,7 +23,7 @@ public class CatalogOverrideTierBlockModelDao {
     private Short blockNumber;
     private Long recordId;
     private Long blockDefRecordId;
-    private Long targetTierRecordId;
+    private Long targetTierDefRecordId;
     private DateTime createdDate;
     private String createdBy;
     private Long tenantRecordId;
@@ -31,10 +31,10 @@ public class CatalogOverrideTierBlockModelDao {
     public CatalogOverrideTierBlockModelDao() {
     }
 
-    public CatalogOverrideTierBlockModelDao(Short blockNumber, Long blockDefRecordId, Long targetTierRecordId) {
+    public CatalogOverrideTierBlockModelDao(Short blockNumber, Long blockDefRecordId, Long targetTierDefRecordId) {
         this.blockNumber = blockNumber;
         this.blockDefRecordId = blockDefRecordId;
-        this.targetTierRecordId = targetTierRecordId;
+        this.targetTierDefRecordId = targetTierDefRecordId;
     }
 
     public Short getBlockNumber() {
@@ -49,8 +49,8 @@ public class CatalogOverrideTierBlockModelDao {
         return blockDefRecordId;
     }
 
-    public Long getTargetTierRecordId() {
-        return targetTierRecordId;
+    public Long getTargetTierDefRecordId() {
+        return targetTierDefRecordId;
     }
 
     public String getCreatedBy() {
@@ -77,8 +77,8 @@ public class CatalogOverrideTierBlockModelDao {
         this.blockDefRecordId = blockDefRecordId;
     }
 
-    public void setTargetTierRecordId(Long targetTierRecordId) {
-        this.targetTierRecordId = targetTierRecordId;
+    public void setTargetTierDefRecordId(Long targetTierDefRecordId) {
+        this.targetTierDefRecordId = targetTierDefRecordId;
     }
 
     public void setCreatedDate(DateTime createdDate) {
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideUsageDefinitionModelDao.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideUsageDefinitionModelDao.java
index df9c010..62eafbe 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideUsageDefinitionModelDao.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideUsageDefinitionModelDao.java
@@ -17,15 +17,15 @@
 
 package org.killbill.billing.catalog.dao;
 
-import org.joda.time.DateTime;
-
 import java.math.BigDecimal;
 
+import org.joda.time.DateTime;
+
 public class CatalogOverrideUsageDefinitionModelDao {
 
     private Long recordId;
     private String parentUsageName;
-    private String parentUsageType;
+    private String type;
     private String currency;
     private BigDecimal fixedPrice;
     private BigDecimal recurringPrice;
@@ -37,10 +37,10 @@ public class CatalogOverrideUsageDefinitionModelDao {
     public CatalogOverrideUsageDefinitionModelDao() {
     }
 
-    public CatalogOverrideUsageDefinitionModelDao(String parentUsageName, String parentUsageType, String currency, BigDecimal fixedPrice, BigDecimal recurringPrice, DateTime effectiveDate) {
+    public CatalogOverrideUsageDefinitionModelDao(String parentUsageName, String type, String currency, BigDecimal fixedPrice, BigDecimal recurringPrice, DateTime effectiveDate) {
 
         this.parentUsageName = parentUsageName;
-        this.parentUsageType = parentUsageType;
+        this.type = type;
         this.currency = currency;
         this.fixedPrice = fixedPrice;
         this.recurringPrice = recurringPrice;
@@ -59,8 +59,8 @@ public class CatalogOverrideUsageDefinitionModelDao {
         this.parentUsageName = parentUsageName;
     }
 
-    public void setParentUsageType(String parentUsageType) {
-        this.parentUsageType = parentUsageType;
+    public void setType(String type) {
+        this.type = type;
     }
 
     public void setCurrency(String currency) {
@@ -95,8 +95,8 @@ public class CatalogOverrideUsageDefinitionModelDao {
         return parentUsageName;
     }
 
-    public String getParentUsageType() {
-        return parentUsageType;
+    public String getType() {
+        return type;
     }
 
     public String getCurrency() {
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideUsageDefinitionSqlDao.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideUsageDefinitionSqlDao.java
index a54e776..24ad294 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideUsageDefinitionSqlDao.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideUsageDefinitionSqlDao.java
@@ -45,7 +45,7 @@ public interface CatalogOverrideUsageDefinitionSqlDao extends Transactional<Cata
                                                                                 @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
-    public List<CatalogOverrideUsageDefinitionModelDao> getByAttributes(@Bind("parentUsageName") String parentPhaseName,
+    public List<CatalogOverrideUsageDefinitionModelDao> getByAttributes(@Bind("parentUsageName") String parentUsageName,
                                                                         @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultBlockPriceOverride.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultBlockPriceOverride.java
index e33faf2..bcb66b9 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultBlockPriceOverride.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultBlockPriceOverride.java
@@ -20,6 +20,7 @@ package org.killbill.billing.catalog;
 import java.math.BigDecimal;
 
 import org.killbill.billing.catalog.api.BlockPriceOverride;
+import org.killbill.billing.catalog.api.Currency;
 
 public class DefaultBlockPriceOverride implements BlockPriceOverride {
 
@@ -29,6 +30,8 @@ public class DefaultBlockPriceOverride implements BlockPriceOverride {
 
     private BigDecimal price;
 
+    private Currency currency;
+
     @Override
     public String getUnitName() {
         return unitName;
@@ -44,9 +47,15 @@ public class DefaultBlockPriceOverride implements BlockPriceOverride {
         return price;
     }
 
-    public DefaultBlockPriceOverride( String unitName, Double size, BigDecimal price) {
+    @Override
+    public Currency getCurrency() {
+        return currency;
+    }
+
+    public DefaultBlockPriceOverride( String unitName, Double size, BigDecimal price, Currency currency) {
         this.unitName = unitName;
         this.size = size;
         this.price = price;
+        this.currency = currency;
     }
 }
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultTieredBlockPriceOverride.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultTieredBlockPriceOverride.java
index 2f58425..9663440 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultTieredBlockPriceOverride.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultTieredBlockPriceOverride.java
@@ -19,6 +19,7 @@ package org.killbill.billing.catalog;
 
 import java.math.BigDecimal;
 
+import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.catalog.api.TieredBlockPriceOverride;
 
 public class DefaultTieredBlockPriceOverride extends DefaultBlockPriceOverride implements TieredBlockPriceOverride {
@@ -30,9 +31,8 @@ public class DefaultTieredBlockPriceOverride extends DefaultBlockPriceOverride i
         return max;
     }
 
-    public DefaultTieredBlockPriceOverride(String unitName, Double size, BigDecimal price, Double max) {
-        super(unitName, size, price);
+    public DefaultTieredBlockPriceOverride(String unitName, Double size, BigDecimal price, Currency currency, Double max) {
+        super(unitName, size, price, currency);
         this.max = max;
     }
-
 }
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/override/DefaultPriceOverride.java b/catalog/src/main/java/org/killbill/billing/catalog/override/DefaultPriceOverride.java
index 2e8b0ee..225cf7c 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/override/DefaultPriceOverride.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/override/DefaultPriceOverride.java
@@ -211,7 +211,7 @@ public class DefaultPriceOverride implements PriceOverride {
             }).orNull();
 
             if(curOverride != null) {
-                resolvedTieredBlockPriceOverrides.add(new DefaultTieredBlockPriceOverride(curTieredBlock.getUnit().getName(), curOverride.getSize(), curOverride.getPrice(), curOverride.getMax())) ;
+                resolvedTieredBlockPriceOverrides.add(new DefaultTieredBlockPriceOverride(curTieredBlock.getUnit().getName(), curOverride.getSize(), curOverride.getPrice(), curOverride.getCurrency(), curOverride.getMax())) ;
             }
             else {
                 resolvedTieredBlockPriceOverrides.add(null);
diff --git a/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideTierBlockSqlDao.sql.stg b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideTierBlockSqlDao.sql.stg
index 34e52da..6fd7732 100644
--- a/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideTierBlockSqlDao.sql.stg
+++ b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideTierBlockSqlDao.sql.stg
@@ -19,7 +19,7 @@ allTableFields(prefix) ::= <<
 tableValues() ::= <<
   :blockNumber
 , :blockDefRecordId
-, :targetTierRecordId
+, :targetTierDefRecordId
 , :createdDate
 , :createdBy
 , :tenantRecordId
diff --git a/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideUsageDefinitionSqlDao.sql.stg b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideUsageDefinitionSqlDao.sql.stg
index 9455c49..359d435 100644
--- a/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideUsageDefinitionSqlDao.sql.stg
+++ b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideUsageDefinitionSqlDao.sql.stg
@@ -22,7 +22,7 @@ allTableFields(prefix) ::= <<
 
 tableValues() ::= <<
   :parentUsageName
-, :parentUsageType
+, :type
 , :fixedPrice
 , :recurringPrice
 , :effectiveDate
diff --git a/catalog/src/main/resources/org/killbill/billing/catalog/migration/V20161220000000__unit_price_override.sql b/catalog/src/main/resources/org/killbill/billing/catalog/migration/V20161220000000__unit_price_override.sql
new file mode 100644
index 0000000..85f5589
--- /dev/null
+++ b/catalog/src/main/resources/org/killbill/billing/catalog/migration/V20161220000000__unit_price_override.sql
@@ -0,0 +1,94 @@
+DROP TABLE IF EXISTS catalog_override_usage_definition;
+create table catalog_override_usage_definition
+(
+record_id serial unique,
+parent_usage_name varchar(255) NOT NULL,
+type varchar(255) NOT NULL,
+fixed_price decimal(15,9) NULL,
+recurring_price decimal(15,9) NULL,
+currency varchar(3) NOT NULL,
+effective_date datetime NOT NULL,
+created_date datetime NOT NULL,
+created_by varchar(50) NOT NULL,
+tenant_record_id bigint /*! unsigned */ not null default 0,
+PRIMARY KEY(record_id)
+);
+CREATE INDEX catalog_override_usage_definition_idx ON catalog_override_usage_definition(tenant_record_id, parent_usage_name, currency);
+
+DROP TABLE IF EXISTS catalog_override_tier_definition;
+create table catalog_override_tier_definition
+(
+record_id serial unique,
+fixed_price decimal(15,9) NULL,
+recurring_price decimal(15,9) NULL,
+currency varchar(3) NOT NULL,
+effective_date datetime NOT NULL,
+created_date datetime NOT NULL,
+created_by varchar(50) NOT NULL,
+tenant_record_id bigint /*! unsigned */ not null default 0,
+PRIMARY KEY(record_id)
+);
+CREATE INDEX catalog_override_tier_definition_idx ON catalog_override_usage_definition(tenant_record_id, currency);
+
+DROP TABLE IF EXISTS catalog_override_block_definition;
+create table catalog_override_block_definition
+(
+record_id serial unique,
+parent_unit_name varchar(255) NOT NULL,
+size double NOT NULL,
+max double NULL,
+currency varchar(3) NOT NULL,
+price decimal(15,9) NOT NULL,
+effective_date datetime NOT NULL,
+created_date datetime NOT NULL,
+created_by varchar(50) NOT NULL,
+tenant_record_id bigint /*! unsigned */ not null default 0,
+PRIMARY KEY(record_id)
+);
+CREATE INDEX catalog_override_block_definition_idx ON catalog_override_block_definition(tenant_record_id, parent_unit_name, currency);
+
+
+DROP TABLE IF EXISTS catalog_override_phase_usage;
+create table catalog_override_phase_usage
+(
+record_id serial unique,
+usage_number smallint(5) unsigned,
+usage_def_record_id  bigint /*! unsigned */ not null,
+target_phase_def_record_id bigint /*! unsigned */ not null,
+created_date datetime NOT NULL,
+created_by varchar(50) NOT NULL,
+tenant_record_id bigint /*! unsigned */ not null default 0,
+PRIMARY KEY(record_id)
+);
+CREATE INDEX catalog_override_phase_usage_idx ON catalog_override_phase_usage(tenant_record_id, usage_number, usage_def_record_id);
+
+DROP TABLE IF EXISTS catalog_override_usage_tier;
+create table catalog_override_usage_tier
+(
+record_id serial unique,
+tier_number smallint(5) unsigned,
+tier_def_record_id bigint /*! unsigned */ not null,
+target_usage_def_record_id bigint /*! unsigned */ not null,
+created_date datetime NOT NULL,
+created_by varchar(50) NOT NULL,
+tenant_record_id bigint /*! unsigned */ not null default 0,
+PRIMARY KEY(record_id)
+);
+CREATE INDEX catalog_override_usage_tier_idx ON catalog_override_usage_tier(tenant_record_id, tier_number, tier_def_record_id);
+
+
+DROP TABLE IF EXISTS catalog_override_tier_block;
+create table catalog_override_tier_block
+(
+record_id serial unique,
+block_number smallint(5) unsigned,
+block_def_record_id bigint /*! unsigned */ not null,
+target_tier_def_record_id bigint /*! unsigned */ not null,
+created_date datetime NOT NULL,
+created_by varchar(50) NOT NULL,
+tenant_record_id bigint /*! unsigned */ NOT NULL default 0,
+PRIMARY KEY(record_id)
+);
+CREATE INDEX catalog_override_tier_block_idx ON catalog_override_tier_block(tenant_record_id, block_number, block_def_record_id);
+
+
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverrideBlockDefinitionSqlDao.java b/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverrideBlockDefinitionSqlDao.java
index 591a6ef..f4f6fc0 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverrideBlockDefinitionSqlDao.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverrideBlockDefinitionSqlDao.java
@@ -29,7 +29,6 @@ import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNull;
 
 public class TestCatalogOverrideBlockDefinitionSqlDao extends CatalogTestSuiteWithEmbeddedDB {
 
@@ -42,8 +41,7 @@ public class TestCatalogOverrideBlockDefinitionSqlDao extends CatalogTestSuiteWi
     @Test(groups = "slow")
     public void testBasic() throws Exception {
 
-        final CatalogOverrideBlockDefinitionModelDao obj1 = new CatalogOverrideBlockDefinitionModelDao("p1","USD" ,BigDecimal.ONE ,1 ,1 , clock.getUTCNow());
-
+        final CatalogOverrideBlockDefinitionModelDao obj1 = new CatalogOverrideBlockDefinitionModelDao("p1", "USD", BigDecimal.ONE, 1 , 1, clock.getUTCNow());
         performTestInTransaction(new WithCatalogOverrideBlockDefinitionSqlDaoTransaction<Void>() {
             @Override
             public Void doTransaction(final CatalogOverrideBlockDefinitionSqlDao sqlDao) {
@@ -52,7 +50,7 @@ public class TestCatalogOverrideBlockDefinitionSqlDao extends CatalogTestSuiteWi
 
                 final CatalogOverrideBlockDefinitionModelDao rehydrated = sqlDao.getByRecordId(lastInserted, internalCallContext);
                 assertEquals(rehydrated.getParentUnitName(), obj1.getParentUnitName());
-                assertEquals(rehydrated.getCurrency().compareTo(obj1.getCurrency()), 0);
+                assertEquals(rehydrated.getCurrency(), obj1.getCurrency());
                 assertEquals(rehydrated.getPrice().compareTo(obj1.getPrice()), 0);
                 assertEquals(rehydrated.getSize(), obj1.getSize());
                 assertEquals(rehydrated.getMax(), obj1.getMax());
@@ -64,36 +62,33 @@ public class TestCatalogOverrideBlockDefinitionSqlDao extends CatalogTestSuiteWi
     @Test(groups = "slow")
     public void testGetByAttributes() throws Exception {
 
-        final CatalogOverrideBlockDefinitionModelDao objWithNoNullPrice = new CatalogOverrideBlockDefinitionModelDao("p2", "USD", BigDecimal.ONE, 1, 5, clock.getUTCNow());
+        final CatalogOverrideBlockDefinitionModelDao objWithNoNullPrice = new CatalogOverrideBlockDefinitionModelDao("p2", "USD", BigDecimal.ONE, new Double("1"), new Double("5"), clock.getUTCNow());
 
         performTestInTransaction(new WithCatalogOverrideBlockDefinitionSqlDaoTransaction<Void>() {
             @Override
             public Void doTransaction(final CatalogOverrideBlockDefinitionSqlDao sqlDao) {
                 sqlDao.create(objWithNoNullPrice, internalCallContext);
-                final Long lastInserted = sqlDao.getLastInsertId();
                 checkRehydrated(objWithNoNullPrice, sqlDao);
 
                 return null;
             }
 
             private void checkRehydrated(final CatalogOverrideBlockDefinitionModelDao obj, final CatalogOverrideBlockDefinitionSqlDao sqlDao) {
-                final CatalogOverrideBlockDefinitionModelDao rehydrated = sqlDao.getByAttributes(obj.getParentUnitName(), obj.getCurrency(), obj.getPrice(), obj.getSize(),obj.getMax(), internalCallContext);
-               /* assertEquals(rehydrated.getParentUnitName(), obj.getParentUnitName());
+                final CatalogOverrideBlockDefinitionModelDao rehydrated = sqlDao.getByAttributes(obj.getParentUnitName(), obj.getCurrency(), obj.getPrice(),obj.getMax(),obj.getSize(), internalCallContext);
+                assertEquals(rehydrated.getParentUnitName(), obj.getParentUnitName());
                 assertEquals(rehydrated.getCurrency(), obj.getCurrency());
-                assertEquals(rehydrated.getPrice(), obj.getPrice());
+                assertEquals(rehydrated.getPrice().compareTo(obj.getPrice()), 0);
                 assertEquals(rehydrated.getSize(), obj.getSize());
-                assertEquals(rehydrated.getMax(), obj.getMax()); */
+                assertEquals(rehydrated.getMax(), obj.getMax());
             }
         });
     }
 
-  private interface WithCatalogOverrideBlockDefinitionSqlDaoTransaction<T> {
+    private interface WithCatalogOverrideBlockDefinitionSqlDaoTransaction<T> {
 
         public <T> T doTransaction(final CatalogOverrideBlockDefinitionSqlDao sqlDao);
     }
 
-
-
     private <T> T performTestInTransaction(final WithCatalogOverrideBlockDefinitionSqlDaoTransaction<T> callback) {
         return dbi.inTransaction(new TransactionCallback<T>() {
             @Override
@@ -103,5 +98,4 @@ public class TestCatalogOverrideBlockDefinitionSqlDao extends CatalogTestSuiteWi
             }
         });
     }
-
 }
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverrideDao.java b/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverrideDao.java
index 39d6c3f..47c58c1 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverrideDao.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverrideDao.java
@@ -18,16 +18,25 @@
 package org.killbill.billing.catalog.dao;
 
 import java.math.BigDecimal;
+import java.util.ArrayList;
 import java.util.List;
 
 import org.joda.time.DateTime;
 import org.killbill.billing.catalog.CatalogTestSuiteWithEmbeddedDB;
 import org.killbill.billing.catalog.DefaultPlanPhasePriceOverride;
+import org.killbill.billing.catalog.DefaultTierPriceOverride;
+import org.killbill.billing.catalog.DefaultTieredBlockPriceOverride;
+import org.killbill.billing.catalog.DefaultUsagePriceOverride;
 import org.killbill.billing.catalog.StandaloneCatalog;
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.catalog.api.Plan;
 import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
+import org.killbill.billing.catalog.api.TierPriceOverride;
+import org.killbill.billing.catalog.api.TieredBlockPriceOverride;
+import org.killbill.billing.catalog.api.UsagePriceOverride;
+import org.killbill.billing.catalog.api.UsageType;
 import org.killbill.xmlloader.XMLLoader;
+import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.google.common.io.Resources;
@@ -94,5 +103,113 @@ public class TestCatalogOverrideDao extends CatalogTestSuiteWithEmbeddedDB {
         }
     }
 
+    @Test(groups = "slow")
+    public void testGetOverriddenPlanPhasesWithUsageOverrides() throws Exception {
+
+        final StandaloneCatalog catalog = XMLLoader.getObjectFromString(Resources.getResource("SpyCarAdvanced.xml").toExternalForm(), StandaloneCatalog.class);
+        final Plan plan = catalog.findCurrentPlan("gas-monthly");
+
+        final PlanPhasePriceOverride[] resolvedOverrides = new PlanPhasePriceOverride[plan.getAllPhases().length];
+
+        List<TieredBlockPriceOverride> tieredBlockPriceOverrides = new ArrayList<TieredBlockPriceOverride>();
+        DefaultTieredBlockPriceOverride tieredBlockPriceOverride = new DefaultTieredBlockPriceOverride("gallons", new Double("1"), new BigDecimal(4), Currency.USD, new Double("100"));
+        tieredBlockPriceOverrides.add(tieredBlockPriceOverride);
+
+        List<TierPriceOverride> tierPriceOverrides = new ArrayList<TierPriceOverride>();
+        DefaultTierPriceOverride tierPriceOverride = new DefaultTierPriceOverride(tieredBlockPriceOverrides);
+        tierPriceOverrides.add(tierPriceOverride);
+
+        List<UsagePriceOverride> usagePriceOverrides = new ArrayList<UsagePriceOverride>();
+        DefaultUsagePriceOverride usagePriceOverride = new DefaultUsagePriceOverride("gas-monthly-in-arrear", UsageType.CONSUMABLE, tierPriceOverrides);
+        usagePriceOverrides.add(usagePriceOverride);
+
+       //Override the gallons price from $3.95 to $4 and also the recurring price from  $0 to $348.64
+        resolvedOverrides[0]  = new DefaultPlanPhasePriceOverride(plan.getFinalPhase().getName(), Currency.USD, BigDecimal.ZERO, new BigDecimal("348.64"), usagePriceOverrides);
+
+        final CatalogOverridePlanDefinitionModelDao newPlan = catalogOverrideDao.getOrCreateOverridePlanDefinition(plan, new DateTime(catalog.getEffectiveDate()), resolvedOverrides, internalCallContext);
+
+        final List<CatalogOverridePhaseDefinitionModelDao> phases = catalogOverrideDao.getOverriddenPlanPhases(newPlan.getRecordId(), internalCallContext);
+        assertEquals(phases.size(), 1);
+        final CatalogOverridePhaseDefinitionModelDao curPhase = phases.get(0);
+
+        assertEquals(curPhase.getCurrency(), resolvedOverrides[0].getCurrency().name());
+        assertEquals(curPhase.getFixedPrice().compareTo(resolvedOverrides[0].getFixedPrice()), 0);
+        assertEquals(curPhase.getRecurringPrice().compareTo(resolvedOverrides[0].getRecurringPrice()), 0);
+        assertEquals(curPhase.getParentPhaseName(), resolvedOverrides[0].getPhaseName());
+
+        final List<CatalogOverrideUsageDefinitionModelDao> usages = catalogOverrideDao.getOverriddenPhaseUsages(curPhase.getRecordId(), internalCallContext);
+        assertEquals(usages.size(), 1);
+        final CatalogOverrideUsageDefinitionModelDao curUsage = usages.get(0);
+        assertEquals(curUsage.getParentUsageName(), usagePriceOverride.getName());
+        assertEquals(curUsage.getType(), usagePriceOverride.getUsageType().toString());
+
+        final List<CatalogOverrideTierDefinitionModelDao> tiers = catalogOverrideDao.getOverriddenUsageTiers(curUsage.getRecordId(), internalCallContext);
+        assertEquals(tiers.size(), 1);
+        final CatalogOverrideTierDefinitionModelDao curTier = tiers.get(0);
+
+        final List<CatalogOverrideBlockDefinitionModelDao> tierBlocks =  catalogOverrideDao.getOverriddenTierBlocks(curTier.getRecordId(), internalCallContext);
+        assertEquals(tierBlocks.size(), 1);
+        final CatalogOverrideBlockDefinitionModelDao curTieredBlock =  tierBlocks.get(0);
+        assertEquals(curTieredBlock.getParentUnitName(),tieredBlockPriceOverride.getUnitName());
+        assertEquals(curTieredBlock.getPrice().compareTo(tieredBlockPriceOverride.getPrice()), 0);
+        assertEquals(curTieredBlock.getSize(),tieredBlockPriceOverride.getSize());
+        assertEquals(curTieredBlock.getMax(),tieredBlockPriceOverride.getMax());
+    }
+
+    @Test(groups = "slow")
+    public void testGetOverrideOneOutOfTwoTieredBlocks() throws Exception {
+
+        final StandaloneCatalog catalog = XMLLoader.getObjectFromString(Resources.getResource("UsageExperimental.xml").toExternalForm(), StandaloneCatalog.class);
+        final Plan plan = catalog.findCurrentPlan("chocolate-monthly");
+
+        final PlanPhasePriceOverride[] resolvedOverrides = new PlanPhasePriceOverride[plan.getAllPhases().length];
+
+        List<TieredBlockPriceOverride> tieredBlockPriceOverrides = new ArrayList<TieredBlockPriceOverride>();
+        DefaultTieredBlockPriceOverride tieredBlockPriceOverride = new DefaultTieredBlockPriceOverride("chocolate-videos", new Double("1"), new BigDecimal(0.75), Currency.USD, new Double("10000"));
+        tieredBlockPriceOverrides.add(tieredBlockPriceOverride);
+
+        List<TierPriceOverride> tierPriceOverrides = new ArrayList<TierPriceOverride>();
+        DefaultTierPriceOverride tierPriceOverride = new DefaultTierPriceOverride(tieredBlockPriceOverrides);
+
+        tierPriceOverrides.add(null);
+        tierPriceOverrides.add(tierPriceOverride);
+
+        List<UsagePriceOverride> usagePriceOverrides = new ArrayList<UsagePriceOverride>();
+        DefaultUsagePriceOverride usagePriceOverride = new DefaultUsagePriceOverride("chocolate-monthly-videos", UsageType.CONSUMABLE, tierPriceOverrides);
+        usagePriceOverrides.add(usagePriceOverride);
+
+        //Override chocolate-videos unit price with size = 1 and max value = 10000 from $1 to $0.75
+        resolvedOverrides[0]  = new DefaultPlanPhasePriceOverride(plan.getFinalPhase().getName(), Currency.USD, null, null, usagePriceOverrides);
+
+        final CatalogOverridePlanDefinitionModelDao newPlan = catalogOverrideDao.getOrCreateOverridePlanDefinition(plan, new DateTime(catalog.getEffectiveDate()), resolvedOverrides, internalCallContext);
+
+        final List<CatalogOverridePhaseDefinitionModelDao> phases = catalogOverrideDao.getOverriddenPlanPhases(newPlan.getRecordId(), internalCallContext);
+        assertEquals(phases.size(), 1);
+        final CatalogOverridePhaseDefinitionModelDao curPhase = phases.get(0);
+
+        assertEquals(curPhase.getCurrency(), resolvedOverrides[0].getCurrency().name());
+        Assert.assertNull(curPhase.getFixedPrice());
+        Assert.assertNull(curPhase.getRecurringPrice());
+        assertEquals(curPhase.getParentPhaseName(), resolvedOverrides[0].getPhaseName());
+
+        final List<CatalogOverrideUsageDefinitionModelDao> usages = catalogOverrideDao.getOverriddenPhaseUsages(curPhase.getRecordId(), internalCallContext);
+        assertEquals(usages.size(), 1);
+        final CatalogOverrideUsageDefinitionModelDao curUsage = usages.get(0);
+        assertEquals(curUsage.getParentUsageName(), usagePriceOverride.getName());
+        assertEquals(curUsage.getType(), usagePriceOverride.getUsageType().toString());
+
+        final List<CatalogOverrideTierDefinitionModelDao> tiers = catalogOverrideDao.getOverriddenUsageTiers(curUsage.getRecordId(), internalCallContext);
+        assertEquals(tiers.size(), 1);
+        final CatalogOverrideTierDefinitionModelDao curTier = tiers.get(0);
+
+        final List<CatalogOverrideBlockDefinitionModelDao> tierBlocks =  catalogOverrideDao.getOverriddenTierBlocks(curTier.getRecordId(), internalCallContext);
+        assertEquals(tierBlocks.size(), 1);
+        final CatalogOverrideBlockDefinitionModelDao curTieredBlock =  tierBlocks.get(0);
+        assertEquals(curTieredBlock.getParentUnitName(),tieredBlockPriceOverride.getUnitName());
+        assertEquals(curTieredBlock.getPrice().compareTo(tieredBlockPriceOverride.getPrice()), 0);
+        assertEquals(curTieredBlock.getSize(),tieredBlockPriceOverride.getSize());
+        assertEquals(curTieredBlock.getMax(),tieredBlockPriceOverride.getMax());
+    }
+
 }
 
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverridePhaseUsageSqlDao.java b/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverridePhaseUsageSqlDao.java
new file mode 100644
index 0000000..f32c850
--- /dev/null
+++ b/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverridePhaseUsageSqlDao.java
@@ -0,0 +1,128 @@
+package org.killbill.billing.catalog.dao;
+/*
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 The Billing Project, LLC
+ *
+ * The Billing Project 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.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.killbill.billing.catalog.CatalogTestSuiteWithEmbeddedDB;
+import org.killbill.commons.jdbi.mapper.LowerToCamelBeanMapperFactory;
+import org.skife.jdbi.v2.DBI;
+import org.skife.jdbi.v2.Handle;
+import org.skife.jdbi.v2.TransactionCallback;
+import org.skife.jdbi.v2.TransactionStatus;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+public class TestCatalogOverridePhaseUsageSqlDao extends CatalogTestSuiteWithEmbeddedDB {
+
+
+    @BeforeClass(groups = "slow")
+    public void beforeClass() throws Exception {
+        super.beforeClass();
+        ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(CatalogOverridePhaseUsageModelDao.class));
+    }
+
+    @Test(groups = "slow")
+    public void testBasic() throws Exception {
+
+        final CatalogOverridePhaseUsageModelDao obj1 = new CatalogOverridePhaseUsageModelDao((short) 1, 2L, 3L);
+
+        performTestInTransaction(new WithCatalogOverridePhaseUsageSqlDaoTransaction<Void>() {
+            @Override
+            public Void doTransaction(final CatalogOverridePhaseUsageSqlDao sqlDao) {
+                sqlDao.create(obj1, internalCallContext);
+                final Long lastInserted = sqlDao.getLastInsertId();
+
+                final CatalogOverridePhaseUsageModelDao rehydrated = sqlDao.getByRecordId(lastInserted, internalCallContext);
+                assertEquals(rehydrated.getUsageNumber(), obj1.getUsageNumber());
+                assertEquals(rehydrated.getUsageDefRecordId(), obj1.getUsageDefRecordId());
+                assertEquals(rehydrated.getTargetPhaseDefRecordId(), obj1.getTargetPhaseDefRecordId());
+                return null;
+            }
+        });
+    }
+
+    @Test(groups = "slow")
+    public void testGetTargetPhaseDefinition() throws Exception {
+
+        final CatalogOverridePhaseUsageModelDao obj1 = new CatalogOverridePhaseUsageModelDao((short) 1, 2L, 3L);
+        final CatalogOverridePhaseUsageModelDao obj2 = new CatalogOverridePhaseUsageModelDao((short) 2, 5L, 3L);
+        final CatalogOverridePhaseUsageModelDao obj3 = new CatalogOverridePhaseUsageModelDao((short) 4, 7L, 3L);
+        final CatalogOverridePhaseUsageModelDao nobj1 = new CatalogOverridePhaseUsageModelDao((short) 4, 7L, 4L);
+
+        performTestInTransaction(new WithCatalogOverridePhaseUsageSqlDaoTransaction<Void>() {
+            @Override
+            public Void doTransaction(final CatalogOverridePhaseUsageSqlDao sqlDao) {
+                sqlDao.create(obj1, internalCallContext);
+                sqlDao.create(obj2, internalCallContext);
+                sqlDao.create(obj3, internalCallContext);
+                sqlDao.create(nobj1, internalCallContext);
+
+                final List<String> keys = new ArrayList<String>();
+                keys.add("1,2");
+                keys.add("2,5");
+                keys.add("4,7");
+                final List<Long> targetPhases = sqlDao.getTargetPhaseDefinition(keys, keys.size(), internalCallContext);
+                assertEquals(targetPhases.size(), 1);
+                assertEquals(targetPhases.get(0), new Long(3));
+                return null;
+            }
+        });
+    }
+
+    @Test(groups = "slow")
+    public void testGetTargetPhaseDefWithSameUsageOverrideAndDifferentRecurringPriceOverride() throws Exception {
+
+        final CatalogOverridePhaseUsageModelDao obj1 = new CatalogOverridePhaseUsageModelDao((short) 1, 2L, 3L);
+        final CatalogOverridePhaseUsageModelDao obj2 = new CatalogOverridePhaseUsageModelDao((short) 1, 2L, 4L);
+
+        performTestInTransaction(new WithCatalogOverridePhaseUsageSqlDaoTransaction<Void>() {
+            @Override
+            public Void doTransaction(final CatalogOverridePhaseUsageSqlDao sqlDao) {
+                sqlDao.create(obj1, internalCallContext);
+                sqlDao.create(obj2, internalCallContext);
+
+                final List<String> keys = new ArrayList<String>();
+                keys.add("1,2");
+                final List<Long> targetPhases = sqlDao.getTargetPhaseDefinition(keys, keys.size(), internalCallContext);
+                assertEquals(targetPhases.size(), 2);
+                assertEquals(targetPhases.get(0), new Long(3));
+                assertEquals(targetPhases.get(1), new Long(4));
+                return null;
+            }
+        });
+    }
+
+    private interface WithCatalogOverridePhaseUsageSqlDaoTransaction<T> {
+
+        public <T> T doTransaction(final CatalogOverridePhaseUsageSqlDao sqlDao);
+    }
+
+    private <T> T performTestInTransaction(final WithCatalogOverridePhaseUsageSqlDaoTransaction<T> callback) {
+        return dbi.inTransaction(new TransactionCallback<T>() {
+            @Override
+            public T inTransaction(final Handle handle, final TransactionStatus status) throws Exception {
+                final CatalogOverridePhaseUsageSqlDao sqlDao = handle.attach(CatalogOverridePhaseUsageSqlDao.class);
+                return callback.doTransaction(sqlDao);
+            }
+        });
+    }
+
+}
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverridePlanPhaseSqlDao.java b/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverridePlanPhaseSqlDao.java
index 2aed21b..996b186 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverridePlanPhaseSqlDao.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverridePlanPhaseSqlDao.java
@@ -17,7 +17,6 @@
 
 package org.killbill.billing.catalog.dao;
 
-import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -61,7 +60,6 @@ public class TestCatalogOverridePlanPhaseSqlDao extends CatalogTestSuiteWithEmbe
         });
     }
 
-
     @Test(groups = "slow")
     public void testGetTargetPlanDefinition() throws Exception {
 
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverrideTierBlockSqlDao.java b/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverrideTierBlockSqlDao.java
new file mode 100644
index 0000000..1f05919
--- /dev/null
+++ b/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverrideTierBlockSqlDao.java
@@ -0,0 +1,104 @@
+package org.killbill.billing.catalog.dao;
+/*
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 The Billing Project, LLC
+ *
+ * The Billing Project 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.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.killbill.billing.catalog.CatalogTestSuiteWithEmbeddedDB;
+import org.killbill.commons.jdbi.mapper.LowerToCamelBeanMapperFactory;
+import org.skife.jdbi.v2.DBI;
+import org.skife.jdbi.v2.Handle;
+import org.skife.jdbi.v2.TransactionCallback;
+import org.skife.jdbi.v2.TransactionStatus;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+public class TestCatalogOverrideTierBlockSqlDao extends CatalogTestSuiteWithEmbeddedDB {
+
+
+    @BeforeClass(groups = "slow")
+    public void beforeClass() throws Exception {
+        super.beforeClass();
+        ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(CatalogOverrideTierBlockModelDao.class));
+    }
+
+    @Test(groups = "slow")
+    public void testBasic() throws Exception {
+
+        final CatalogOverrideTierBlockModelDao obj1 = new CatalogOverrideTierBlockModelDao((short) 1, 2L, 3L);
+
+        performTestInTransaction(new WithCatalogOverrideTierBlockSqlDaoTransaction<Void>() {
+            @Override
+            public Void doTransaction(final CatalogOverrideTierBlockSqlDao sqlDao) {
+                sqlDao.create(obj1, internalCallContext);
+                final Long lastInserted = sqlDao.getLastInsertId();
+
+                final CatalogOverrideTierBlockModelDao rehydrated = sqlDao.getByRecordId(lastInserted, internalCallContext);
+                assertEquals(rehydrated.getBlockNumber(), obj1.getBlockNumber());
+                assertEquals(rehydrated.getBlockDefRecordId(), obj1.getBlockDefRecordId());
+                assertEquals(rehydrated.getTargetTierDefRecordId(), obj1.getTargetTierDefRecordId());
+                return null;
+            }
+        });
+    }
+
+    @Test(groups = "slow")
+    public void testGetTargetTierDefinition() throws Exception {
+
+        final CatalogOverrideTierBlockModelDao obj1 = new CatalogOverrideTierBlockModelDao((short) 1, 2L, 3L);
+        final CatalogOverrideTierBlockModelDao obj2 = new CatalogOverrideTierBlockModelDao((short) 2, 5L, 3L);
+        final CatalogOverrideTierBlockModelDao obj3 = new CatalogOverrideTierBlockModelDao((short) 4, 7L, 3L);
+        final CatalogOverrideTierBlockModelDao nobj1 = new CatalogOverrideTierBlockModelDao((short) 4, 7L, 4L);
+
+        performTestInTransaction(new WithCatalogOverrideTierBlockSqlDaoTransaction<Void>() {
+            @Override
+            public Void doTransaction(final CatalogOverrideTierBlockSqlDao sqlDao) {
+                sqlDao.create(obj1, internalCallContext);
+                sqlDao.create(obj2, internalCallContext);
+                sqlDao.create(obj3, internalCallContext);
+                sqlDao.create(nobj1, internalCallContext);
+
+                final List<String> keys = new ArrayList<String>();
+                keys.add("1,2");
+                keys.add("2,5");
+                keys.add("4,7");
+                final Long targetTier = sqlDao.getTargetTierDefinition(keys, keys.size(), internalCallContext);
+                assertEquals(targetTier, new Long(3));
+                return null;
+            }
+        });
+    }
+
+    private interface WithCatalogOverrideTierBlockSqlDaoTransaction<T> {
+
+        public <T> T doTransaction(final CatalogOverrideTierBlockSqlDao sqlDao);
+    }
+
+    private <T> T performTestInTransaction(final WithCatalogOverrideTierBlockSqlDaoTransaction<T> callback) {
+        return dbi.inTransaction(new TransactionCallback<T>() {
+            @Override
+            public T inTransaction(final Handle handle, final TransactionStatus status) throws Exception {
+                final CatalogOverrideTierBlockSqlDao sqlDao = handle.attach(CatalogOverrideTierBlockSqlDao.class);
+                return callback.doTransaction(sqlDao);
+            }
+        });
+    }
+
+}
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverrideTierDefinitionSqlDao.java b/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverrideTierDefinitionSqlDao.java
new file mode 100644
index 0000000..997d547
--- /dev/null
+++ b/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverrideTierDefinitionSqlDao.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 The Billing Project, LLC
+ *
+ * The Billing Project 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 org.killbill.billing.catalog.dao;
+
+import java.math.BigDecimal;
+
+import org.killbill.billing.catalog.CatalogTestSuiteWithEmbeddedDB;
+import org.killbill.commons.jdbi.mapper.LowerToCamelBeanMapperFactory;
+import org.skife.jdbi.v2.DBI;
+import org.skife.jdbi.v2.Handle;
+import org.skife.jdbi.v2.TransactionCallback;
+import org.skife.jdbi.v2.TransactionStatus;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+public class TestCatalogOverrideTierDefinitionSqlDao extends CatalogTestSuiteWithEmbeddedDB {
+    @BeforeClass(groups = "slow")
+    public void beforeClass() throws Exception {
+        super.beforeClass();
+        ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(CatalogOverrideTierDefinitionModelDao.class));
+    }
+
+    @Test(groups = "slow")
+    public void testBasic() throws Exception {
+
+        final CatalogOverrideTierDefinitionModelDao obj1 = new CatalogOverrideTierDefinitionModelDao("USD", BigDecimal.ONE,null, clock.getUTCNow());
+        performTestInTransaction(new WithCatalogOverrideTierDefinitionSqlDaoTransaction<Void>() {
+            @Override
+            public Void doTransaction(final CatalogOverrideTierDefinitionSqlDao sqlDao) {
+                sqlDao.create(obj1, internalCallContext);
+                final Long lastInserted = sqlDao.getLastInsertId();
+
+                final CatalogOverrideTierDefinitionModelDao rehydrated = sqlDao.getByRecordId(lastInserted, internalCallContext);
+                assertEquals(rehydrated.getFixedPrice().compareTo(obj1.getFixedPrice()), 0);
+                assertEquals(rehydrated.getCurrency(), obj1.getCurrency());
+                return null;
+            }
+        });
+    }
+
+    private interface WithCatalogOverrideTierDefinitionSqlDaoTransaction<T> {
+
+        public <T> T doTransaction(final CatalogOverrideTierDefinitionSqlDao sqlDao);
+    }
+
+    private <T> T performTestInTransaction(final WithCatalogOverrideTierDefinitionSqlDaoTransaction<T> callback) {
+        return dbi.inTransaction(new TransactionCallback<T>() {
+            @Override
+            public T inTransaction(final Handle handle, final TransactionStatus status) throws Exception {
+                final CatalogOverrideTierDefinitionSqlDao sqlDao = handle.attach(CatalogOverrideTierDefinitionSqlDao.class);
+                return callback.doTransaction(sqlDao);
+            }
+        });
+    }
+}
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverrideUsageDefinitionSqlDao.java b/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverrideUsageDefinitionSqlDao.java
new file mode 100644
index 0000000..222c929
--- /dev/null
+++ b/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverrideUsageDefinitionSqlDao.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 The Billing Project, LLC
+ *
+ * The Billing Project 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 org.killbill.billing.catalog.dao;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.killbill.billing.catalog.CatalogTestSuiteWithEmbeddedDB;
+import org.killbill.commons.jdbi.mapper.LowerToCamelBeanMapperFactory;
+import org.skife.jdbi.v2.DBI;
+import org.skife.jdbi.v2.Handle;
+import org.skife.jdbi.v2.TransactionCallback;
+import org.skife.jdbi.v2.TransactionStatus;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+public class TestCatalogOverrideUsageDefinitionSqlDao extends CatalogTestSuiteWithEmbeddedDB {
+
+    @BeforeClass(groups = "slow")
+    public void beforeClass() throws Exception {
+        super.beforeClass();
+        ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(CatalogOverrideUsageDefinitionModelDao.class));
+    }
+
+    @Test(groups = "slow")
+    public void testBasic() throws Exception {
+
+        final CatalogOverrideUsageDefinitionModelDao obj1 = new CatalogOverrideUsageDefinitionModelDao("u1", "CONSUMABLE", "USD",BigDecimal.ONE,null, clock.getUTCNow());
+        performTestInTransaction(new WithCatalogOverrideUsageDefinitionSqlDaoTransaction<Void>() {
+            @Override
+            public Void doTransaction(final CatalogOverrideUsageDefinitionSqlDao sqlDao) {
+                sqlDao.create(obj1, internalCallContext);
+                final Long lastInserted = sqlDao.getLastInsertId();
+
+                final CatalogOverrideUsageDefinitionModelDao rehydrated = sqlDao.getByRecordId(lastInserted, internalCallContext);
+                assertEquals(rehydrated.getParentUsageName(), obj1.getParentUsageName());
+                assertEquals(rehydrated.getType(), obj1.getType());
+                assertEquals(rehydrated.getCurrency(), obj1.getCurrency());
+                assertEquals(rehydrated.getFixedPrice().compareTo(obj1.getFixedPrice()), 0);
+                return null;
+            }
+        });
+    }
+
+    @Test(groups = "slow")
+    public void testGetByAttributes() throws Exception {
+
+        final CatalogOverrideUsageDefinitionModelDao sameUsageWithDiffBlockPrice1 = new CatalogOverrideUsageDefinitionModelDao("u1", "CONSUMABLE", "USD", null, null, clock.getUTCNow());
+        final CatalogOverrideUsageDefinitionModelDao sameUsageWithDiffBlockPrice2 = new CatalogOverrideUsageDefinitionModelDao("u1", "CONSUMABLE", "USD", null, null, clock.getUTCNow());
+        final CatalogOverrideUsageDefinitionModelDao sameUsageWithDiffBlockPrice3 = new CatalogOverrideUsageDefinitionModelDao("u2", "CONSUMABLE", "USD", null, null, clock.getUTCNow());
+        performTestInTransaction(new WithCatalogOverrideUsageDefinitionSqlDaoTransaction<Void>() {
+            @Override
+            public Void doTransaction(final CatalogOverrideUsageDefinitionSqlDao sqlDao) {
+                sqlDao.create(sameUsageWithDiffBlockPrice1, internalCallContext);
+                sqlDao.create(sameUsageWithDiffBlockPrice2, internalCallContext);
+                sqlDao.create(sameUsageWithDiffBlockPrice3, internalCallContext);
+                List<CatalogOverrideUsageDefinitionModelDao> objList = new ArrayList<CatalogOverrideUsageDefinitionModelDao>();
+                objList.add(sameUsageWithDiffBlockPrice1);
+                objList.add(sameUsageWithDiffBlockPrice2);
+                checkRehydrated(objList, sqlDao);
+
+                return null;
+            }
+
+            private void checkRehydrated(final List<CatalogOverrideUsageDefinitionModelDao> objList, final CatalogOverrideUsageDefinitionSqlDao sqlDao) {
+                final List<CatalogOverrideUsageDefinitionModelDao> rehydrated = sqlDao.getByAttributes("u1", internalCallContext);
+                assertEquals(rehydrated.size(), 2);
+                assertEquals(rehydrated.get(0).getParentUsageName(), objList.get(0).getParentUsageName());
+                assertEquals(rehydrated.get(0).getType(), objList.get(0).getType());
+                assertEquals(rehydrated.get(0).getCurrency(), objList.get(0).getCurrency());
+                assertEquals(rehydrated.get(1).getParentUsageName(), objList.get(1).getParentUsageName());
+                assertEquals(rehydrated.get(1).getType(), objList.get(1).getType());
+                assertEquals(rehydrated.get(1).getCurrency(), objList.get(1).getCurrency());
+
+            }
+        });
+    }
+
+    private interface WithCatalogOverrideUsageDefinitionSqlDaoTransaction<T> {
+
+        public <T> T doTransaction(final CatalogOverrideUsageDefinitionSqlDao sqlDao);
+    }
+
+    private <T> T performTestInTransaction(final WithCatalogOverrideUsageDefinitionSqlDaoTransaction<T> callback) {
+        return dbi.inTransaction(new TransactionCallback<T>() {
+            @Override
+            public T inTransaction(final Handle handle, final TransactionStatus status) throws Exception {
+                final CatalogOverrideUsageDefinitionSqlDao sqlDao = handle.attach(CatalogOverrideUsageDefinitionSqlDao.class);
+                return callback.doTransaction(sqlDao);
+            }
+        });
+    }
+}
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverrideUsageTierSqlDao.java b/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverrideUsageTierSqlDao.java
new file mode 100644
index 0000000..a97e0a8
--- /dev/null
+++ b/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverrideUsageTierSqlDao.java
@@ -0,0 +1,128 @@
+package org.killbill.billing.catalog.dao;
+/*
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 The Billing Project, LLC
+ *
+ * The Billing Project 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.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.killbill.billing.catalog.CatalogTestSuiteWithEmbeddedDB;
+import org.killbill.commons.jdbi.mapper.LowerToCamelBeanMapperFactory;
+import org.skife.jdbi.v2.DBI;
+import org.skife.jdbi.v2.Handle;
+import org.skife.jdbi.v2.TransactionCallback;
+import org.skife.jdbi.v2.TransactionStatus;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+public class TestCatalogOverrideUsageTierSqlDao extends CatalogTestSuiteWithEmbeddedDB {
+
+
+    @BeforeClass(groups = "slow")
+    public void beforeClass() throws Exception {
+        super.beforeClass();
+        ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(CatalogOverrideUsageTierModelDao.class));
+    }
+
+    @Test(groups = "slow")
+    public void testBasic() throws Exception {
+
+        final CatalogOverrideUsageTierModelDao obj1 = new CatalogOverrideUsageTierModelDao((short) 1, 2L, 3L);
+
+        performTestInTransaction(new WithCatalogOverrideUsageTierSqlDaoTransaction<Void>() {
+            @Override
+            public Void doTransaction(final CatalogOverrideUsageTierSqlDao sqlDao) {
+                sqlDao.create(obj1, internalCallContext);
+                final Long lastInserted = sqlDao.getLastInsertId();
+
+                final CatalogOverrideUsageTierModelDao rehydrated = sqlDao.getByRecordId(lastInserted, internalCallContext);
+                assertEquals(rehydrated.getTierNumber(), obj1.getTierNumber());
+                assertEquals(rehydrated.getTierDefRecordId(), obj1.getTierDefRecordId());
+                assertEquals(rehydrated.getTargetUsageDefRecordId(), obj1.getTargetUsageDefRecordId());
+                return null;
+            }
+        });
+    }
+
+    @Test(groups = "slow")
+    public void testGetTargetUsageDefinition() throws Exception {
+
+        final CatalogOverrideUsageTierModelDao obj1 = new CatalogOverrideUsageTierModelDao((short) 1, 2L, 3L);
+        final CatalogOverrideUsageTierModelDao obj2 = new CatalogOverrideUsageTierModelDao((short) 2, 5L, 3L);
+        final CatalogOverrideUsageTierModelDao obj3 = new CatalogOverrideUsageTierModelDao((short) 4, 7L, 3L);
+        final CatalogOverrideUsageTierModelDao nobj1 = new CatalogOverrideUsageTierModelDao((short) 4, 7L, 4L);
+
+        performTestInTransaction(new WithCatalogOverrideUsageTierSqlDaoTransaction<Void>() {
+            @Override
+            public Void doTransaction(final CatalogOverrideUsageTierSqlDao sqlDao) {
+                sqlDao.create(obj1, internalCallContext);
+                sqlDao.create(obj2, internalCallContext);
+                sqlDao.create(obj3, internalCallContext);
+                sqlDao.create(nobj1, internalCallContext);
+
+                final List<String> keys = new ArrayList<String>();
+                keys.add("1,2");
+                keys.add("2,5");
+                keys.add("4,7");
+                final List<Long> targetUsages = sqlDao.getTargetUsageDefinition(keys, keys.size(), internalCallContext);
+                assertEquals(targetUsages.size(), 1);
+                assertEquals(targetUsages.get(0), new Long(3));
+                return null;
+            }
+        });
+    }
+
+    @Test(groups = "slow")
+    public void testGetTargetUsageDefWithSameTierOverrideAndDifferentUsagePriceOverride() throws Exception {
+
+        final CatalogOverrideUsageTierModelDao obj1 = new CatalogOverrideUsageTierModelDao((short) 1, 2L, 3L);
+        final CatalogOverrideUsageTierModelDao obj2 = new CatalogOverrideUsageTierModelDao((short) 1, 2L, 4L);
+
+        performTestInTransaction(new WithCatalogOverrideUsageTierSqlDaoTransaction<Void>() {
+            @Override
+            public Void doTransaction(final CatalogOverrideUsageTierSqlDao sqlDao) {
+                sqlDao.create(obj1, internalCallContext);
+                sqlDao.create(obj2, internalCallContext);
+
+                final List<String> keys = new ArrayList<String>();
+                keys.add("1,2");
+                final List<Long> targetUsages = sqlDao.getTargetUsageDefinition(keys, keys.size(), internalCallContext);
+                assertEquals(targetUsages.size(), 2);
+                assertEquals(targetUsages.get(0), new Long(3));
+                assertEquals(targetUsages.get(1), new Long(4));
+                return null;
+            }
+        });
+    }
+
+    private interface WithCatalogOverrideUsageTierSqlDaoTransaction<T> {
+
+        public <T> T doTransaction(final CatalogOverrideUsageTierSqlDao sqlDao);
+    }
+
+    private <T> T performTestInTransaction(final WithCatalogOverrideUsageTierSqlDaoTransaction<T> callback) {
+        return dbi.inTransaction(new TransactionCallback<T>() {
+            @Override
+            public T inTransaction(final Handle handle, final TransactionStatus status) throws Exception {
+                final CatalogOverrideUsageTierSqlDao sqlDao = handle.attach(CatalogOverrideUsageTierSqlDao.class);
+                return callback.doTransaction(sqlDao);
+            }
+        });
+    }
+
+}
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/TestDefaultPriceOverride.java b/catalog/src/test/java/org/killbill/billing/catalog/TestDefaultPriceOverride.java
index 325b7a2..3f62d98 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/TestDefaultPriceOverride.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/TestDefaultPriceOverride.java
@@ -30,6 +30,10 @@ import org.killbill.billing.catalog.api.InternationalPrice;
 import org.killbill.billing.catalog.api.Plan;
 import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
 import org.killbill.billing.catalog.api.Price;
+import org.killbill.billing.catalog.api.TierPriceOverride;
+import org.killbill.billing.catalog.api.TieredBlockPriceOverride;
+import org.killbill.billing.catalog.api.UsagePriceOverride;
+import org.killbill.billing.catalog.api.UsageType;
 import org.killbill.billing.catalog.override.DefaultPriceOverride;
 import org.killbill.xmlloader.XMLLoader;
 import org.testng.annotations.Test;
@@ -180,4 +184,192 @@ public class TestDefaultPriceOverride extends CatalogTestSuiteWithEmbeddedDB {
             }
         }
     }
+
+    @Test(groups = "slow")
+    public void testOverrideOneOutOfTwoTieredBlockPrices() throws Exception {
+
+        final StandaloneCatalog catalog = XMLLoader.getObjectFromString(Resources.getResource("UsageExperimental.xml").toExternalForm(), StandaloneCatalog.class);
+        final Plan plan = catalog.findCurrentPlan("chocolate-monthly");
+
+        final List<PlanPhasePriceOverride> overrides = new ArrayList<PlanPhasePriceOverride>();
+
+        final List<TieredBlockPriceOverride> tieredBlockPriceOverrides = new ArrayList<TieredBlockPriceOverride>();
+        tieredBlockPriceOverrides.add(new DefaultTieredBlockPriceOverride("chocolate-videos", new Double("1"), new BigDecimal("0.75"), Currency.USD, new Double("10000")));
+
+        final List<TierPriceOverride> tierPriceOverrides = new ArrayList<TierPriceOverride>();
+        tierPriceOverrides.add(new DefaultTierPriceOverride(tieredBlockPriceOverrides));
+
+        final List<UsagePriceOverride> usagePriceOverrides = new ArrayList<UsagePriceOverride>();
+        usagePriceOverrides.add(new DefaultUsagePriceOverride("chocolate-monthly-videos", UsageType.CONSUMABLE, tierPriceOverrides));
+
+        final PlanPhasePriceOverride phase = new DefaultPlanPhasePriceOverride(plan.getFinalPhase().getName(),Currency.USD, null, null, usagePriceOverrides);
+        overrides.add(phase);
+
+        //Overriding only the tieredblockprice for unit - 'chocolate-videos' with size = 1 and max = 10000 from $1 to $0.75
+        final DefaultPlan overriddenPlan = priceOverride.getOrCreateOverriddenPlan(plan, new DateTime(catalog.getEffectiveDate()), overrides, internalCallContext);
+
+        final Matcher m = DefaultPriceOverride.CUSTOM_PLAN_NAME_PATTERN.matcher(overriddenPlan.getName());
+
+        assertTrue(m.matches());
+        assertEquals(m.group(1), plan.getName());
+        assertEquals(overriddenPlan.getProduct().getName(), plan.getProduct().getName());
+        assertEquals(overriddenPlan.getRecurringBillingPeriod(), plan.getRecurringBillingPeriod());
+        if (plan.getEffectiveDateForExistingSubscriptions() != null) {
+            assertEquals(overriddenPlan.getEffectiveDateForExistingSubscriptions().compareTo(plan.getEffectiveDateForExistingSubscriptions()), 0);
+        }
+        assertNotEquals(overriddenPlan.getFinalPhase().getName(), plan.getFinalPhase().getName());
+
+        for(int i = 0 ; i < overriddenPlan.getFinalPhase().getUsages().length; i++) {
+            final DefaultUsage initialUsage = (DefaultUsage) plan.getFinalPhase().getUsages()[i];
+            final DefaultUsage newUsage = (DefaultUsage) overriddenPlan.getFinalPhase().getUsages()[i];
+
+            assertEquals(newUsage.getName(), initialUsage.getName());
+            assertEquals(newUsage.getUsageType(), initialUsage.getUsageType());
+            assertEquals(newUsage.getBillingPeriod(), initialUsage.getBillingPeriod());
+            assertEquals(newUsage.getBillingPeriod(), initialUsage.getBillingPeriod());
+            assertEquals(newUsage.getTiers().length, initialUsage.getTiers().length);
+
+            for(int j = 0 ; j < newUsage.getTiers().length; j++){
+                final DefaultTier initialTier = (DefaultTier) initialUsage.getTiers()[j];
+                final DefaultTier newTier = (DefaultTier) newUsage.getTiers()[j];
+                assertEquals(newTier.getTieredBlocks().length, initialTier.getTieredBlocks().length);
+
+                for(int k = 0; k < newTier.getTieredBlocks().length; k++){
+                    final DefaultTieredBlock initialTieredBlock = (DefaultTieredBlock) initialTier.getTieredBlocks()[k];
+                    final DefaultTieredBlock newTieredBlock = (DefaultTieredBlock) newTier.getTieredBlocks()[k];
+                    final TieredBlockPriceOverride override = Iterables.tryFind(tieredBlockPriceOverrides, new Predicate<TieredBlockPriceOverride>() {
+                        @Override
+                        public boolean apply(final TieredBlockPriceOverride input) {
+
+                            return input.getUnitName().equals(initialTieredBlock.getUnit().getName()) &&
+                                    Double.compare(input.getSize(), initialTieredBlock.getSize()) == 0 &&
+                                    Double.compare(input.getMax(), initialTieredBlock.getMax()) == 0;
+                        }
+                    }).orNull();
+
+                    assertEquals(newTieredBlock.getUnit().getName(), initialTieredBlock.getUnit().getName());
+                    assertEquals(newTieredBlock.getMax(),initialTieredBlock.getMax());
+                    assertEquals(newTieredBlock.getSize(), initialTieredBlock.getSize());
+                    assertTieredBlockInternationalPrice(newTieredBlock.getPrice(), initialTieredBlock.getPrice(), override);
+                }
+            }
+        }
+    }
+
+    @Test(groups = "slow")
+    public void testOverrideTwoOutOfTwoTieredBlockPrices() throws Exception {
+
+        final StandaloneCatalog catalog = XMLLoader.getObjectFromString(Resources.getResource("UsageExperimental.xml").toExternalForm(), StandaloneCatalog.class);
+        final Plan plan = catalog.findCurrentPlan("chocolate-monthly");
+
+        final List<PlanPhasePriceOverride> overrides = new ArrayList<PlanPhasePriceOverride>();
+
+        final List<TieredBlockPriceOverride> tieredBlockPriceOverrides1 = new ArrayList<TieredBlockPriceOverride>();
+        tieredBlockPriceOverrides1.add(new DefaultTieredBlockPriceOverride("chocolate-videos", new Double("1"), new BigDecimal("1.5"), Currency.USD, new Double("5")));
+
+        final List<TieredBlockPriceOverride> tieredBlockPriceOverrides2 = new ArrayList<TieredBlockPriceOverride>();
+        tieredBlockPriceOverrides2.add(new DefaultTieredBlockPriceOverride("chocolate-videos", new Double("1"), new BigDecimal("0.75"), Currency.USD, new Double("10000")));
+
+        final List<TierPriceOverride> tierPriceOverrides = new ArrayList<TierPriceOverride>();
+        tierPriceOverrides.add(new DefaultTierPriceOverride(tieredBlockPriceOverrides1));
+        tierPriceOverrides.add(new DefaultTierPriceOverride(tieredBlockPriceOverrides2));
+
+        final List<UsagePriceOverride> usagePriceOverrides = new ArrayList<UsagePriceOverride>();
+        usagePriceOverrides.add(new DefaultUsagePriceOverride("chocolate-monthly-videos", UsageType.CONSUMABLE, tierPriceOverrides));
+
+        final PlanPhasePriceOverride phase = new DefaultPlanPhasePriceOverride(plan.getFinalPhase().getName(),Currency.USD, null, new BigDecimal("35"), usagePriceOverrides);
+        overrides.add(phase);
+
+        /* Overriding phase recurring price from $30 to $35, tieredblockprice from $2 to $1.5 for unit- 'chocolate-videos' with size = 1 and max = 5 and
+         also overriding tieredblockprice from $1 to $0.75 for unit - 'chocolate-videos' with size = 1 and max = 10000 */
+        final DefaultPlan overriddenPlan = priceOverride.getOrCreateOverriddenPlan(plan, new DateTime(catalog.getEffectiveDate()), overrides, internalCallContext);
+
+        final Matcher m = DefaultPriceOverride.CUSTOM_PLAN_NAME_PATTERN.matcher(overriddenPlan.getName());
+
+        assertTrue(m.matches());
+        assertEquals(m.group(1), plan.getName());
+        assertEquals(overriddenPlan.getProduct().getName(), plan.getProduct().getName());
+        assertEquals(overriddenPlan.getRecurringBillingPeriod(), plan.getRecurringBillingPeriod());
+        if (plan.getEffectiveDateForExistingSubscriptions() != null) {
+            assertEquals(overriddenPlan.getEffectiveDateForExistingSubscriptions().compareTo(plan.getEffectiveDateForExistingSubscriptions()), 0);
+        }
+        assertNotEquals(overriddenPlan.getFinalPhase().getName(), plan.getFinalPhase().getName());
+
+        final DefaultPlanPhase initialPhase = (DefaultPlanPhase) plan.getFinalPhase();
+        final DefaultPlanPhase newPhase = (DefaultPlanPhase) overriddenPlan.getFinalPhase();
+
+        final PlanPhasePriceOverride override = Iterables.tryFind(overrides, new Predicate<PlanPhasePriceOverride>() {
+            @Override
+            public boolean apply(final PlanPhasePriceOverride input) {
+                return input.getPhaseName().equals(initialPhase.getName());
+            }
+        }).orNull();
+
+        assertNotEquals(newPhase.getName(), initialPhase.getName());
+        assertEquals(newPhase.getName(), overriddenPlan.getName() + "-" +  initialPhase.getName().split("-")[initialPhase.getName().split("-").length -1]);
+        assertEquals(newPhase.getDuration(), initialPhase.getDuration());
+        assertEquals(newPhase.getPhaseType(), initialPhase.getPhaseType());
+        assertEquals(newPhase.getUsages().length, initialPhase.getUsages().length);
+        if (initialPhase.getFixed() != null) {
+            assertEquals(newPhase.getFixed().getType(), initialPhase.getFixed().getType());
+            assertInternationalPrice(newPhase.getFixed().getPrice(), initialPhase.getFixed().getPrice(), override, true);
+        }
+        if (initialPhase.getRecurring() != null) {
+            assertInternationalPrice(newPhase.getRecurring().getRecurringPrice(), initialPhase.getRecurring().getRecurringPrice(), override, false);
+        }
+
+        for(int i = 0 ; i < overriddenPlan.getFinalPhase().getUsages().length; i++) {
+            final DefaultUsage initialUsage = (DefaultUsage) plan.getFinalPhase().getUsages()[i];
+            final DefaultUsage newUsage = (DefaultUsage) overriddenPlan.getFinalPhase().getUsages()[i];
+
+            assertEquals(newUsage.getName(), initialUsage.getName());
+            assertEquals(newUsage.getUsageType(), initialUsage.getUsageType());
+            assertEquals(newUsage.getBillingPeriod(), initialUsage.getBillingPeriod());
+            assertEquals(newUsage.getBillingPeriod(), initialUsage.getBillingPeriod());
+            assertEquals(newUsage.getTiers().length, initialUsage.getTiers().length);
+
+            for(int j = 0 ; j < newUsage.getTiers().length; j++){
+                final DefaultTier initialTier = (DefaultTier) initialUsage.getTiers()[j];
+                final DefaultTier newTier = (DefaultTier) newUsage.getTiers()[j];
+                assertEquals(newTier.getTieredBlocks().length, initialTier.getTieredBlocks().length);
+
+                for(int k = 0; k < newTier.getTieredBlocks().length; k++){
+                    final DefaultTieredBlock initialTieredBlock = (DefaultTieredBlock) initialTier.getTieredBlocks()[k];
+                    final DefaultTieredBlock newTieredBlock = (DefaultTieredBlock) newTier.getTieredBlocks()[k];
+                    List<TieredBlockPriceOverride> tieredBlockPriceOverrides = new ArrayList<TieredBlockPriceOverride>();
+                    tieredBlockPriceOverrides.addAll(tieredBlockPriceOverrides1);
+                    tieredBlockPriceOverrides.addAll(tieredBlockPriceOverrides2);
+                    final TieredBlockPriceOverride tieredBlockPriceOverride = Iterables.tryFind(tieredBlockPriceOverrides, new Predicate<TieredBlockPriceOverride>() {
+                        @Override
+                        public boolean apply(final TieredBlockPriceOverride input) {
+
+                            return input.getUnitName().equals(initialTieredBlock.getUnit().getName()) &&
+                                    Double.compare(input.getSize(), initialTieredBlock.getSize()) == 0 &&
+                                    Double.compare(input.getMax(), initialTieredBlock.getMax()) == 0;
+                        }
+                    }).orNull();
+
+                    assertEquals(newTieredBlock.getUnit().getName(), initialTieredBlock.getUnit().getName());
+                    assertEquals(newTieredBlock.getMax(),initialTieredBlock.getMax());
+                    assertEquals(newTieredBlock.getSize(), initialTieredBlock.getSize());
+                    assertTieredBlockInternationalPrice(newTieredBlock.getPrice(), initialTieredBlock.getPrice(), tieredBlockPriceOverride);
+                }
+            }
+        }
+    }
+
+    private void assertTieredBlockInternationalPrice(final InternationalPrice newInternationalPrice, final InternationalPrice initInternationalPrice, final TieredBlockPriceOverride override) throws CurrencyValueNull {
+        assertEquals(newInternationalPrice.getPrices().length, initInternationalPrice.getPrices().length);
+        for (int i = 0; i < newInternationalPrice.getPrices().length; i++) {
+            final Price initPrice = initInternationalPrice.getPrices()[i];
+            final Price newPrice = newInternationalPrice.getPrices()[i];
+            if (override != null && override.getCurrency() == initPrice.getCurrency() && override.getPrice() != null) {
+                assertEquals(newPrice.getValue().compareTo(override.getPrice()), 0);
+            } else {
+                if (initPrice != null && initPrice.getValue() != null) {
+                    assertEquals(newPrice.getValue().compareTo(initPrice.getValue()), 0);
+                }
+            }
+        }
+    }
 }
diff --git a/catalog/src/test/resources/UsageExperimental.xml b/catalog/src/test/resources/UsageExperimental.xml
index 11f3d17..9fd614f 100644
--- a/catalog/src/test/resources/UsageExperimental.xml
+++ b/catalog/src/test/resources/UsageExperimental.xml
@@ -38,6 +38,7 @@
         <unit name="fastrack-tokens"/>
         <unit name="bandwith-meg-sec"/>
         <unit name="Mbytes"/>
+        <unit name="chocolate-videos" />
     </units>
 
     <products>
@@ -59,6 +60,9 @@
         <product name="ConsumableInArrear">
             <category>BASE</category>
         </product>
+        <product name="Chocolate">
+            <category>BASE</category>
+        </product>
     </products>
 
     <rules>
@@ -264,6 +268,60 @@
             </finalPhase>
         </plan>
 
+        <plan name="chocolate-monthly">
+            <product>Chocolate</product>
+            <finalPhase type="EVERGREEN">
+                <duration>
+                    <unit>UNLIMITED</unit>
+                </duration>
+                <recurring>
+                    <billingPeriod>MONTHLY</billingPeriod>
+                    <recurringPrice>
+                        <price>
+                            <currency>USD</currency>
+                            <value>30.00</value>
+                        </price>
+                    </recurringPrice>
+                </recurring>
+                <usages>
+                    <usage name="chocolate-monthly-videos" billingMode="IN_ARREAR" usageType="CONSUMABLE">
+                        <billingPeriod>MONTHLY</billingPeriod>
+                        <tiers>
+                            <tier>
+                                <blocks>
+                                    <tieredBlock>
+                                        <unit>chocolate-videos</unit>
+                                        <size>1</size>
+                                        <prices>
+                                            <price>
+                                                <currency>USD</currency>
+                                                <value>2</value>
+                                            </price>
+                                        </prices>
+                                        <max>5</max>
+                                    </tieredBlock>
+                                </blocks>
+                            </tier>
+                            <tier>
+                                <blocks>
+                                    <tieredBlock>
+                                        <unit>chocolate-videos</unit>
+                                        <size>1</size>
+                                        <prices>
+                                            <price>
+                                                <currency>USD</currency>
+                                                <value>1</value>
+                                            </price>
+                                        </prices>
+                                        <max>10000</max>
+                                    </tieredBlock>
+                                </blocks>
+                            </tier>
+                        </tiers>
+                    </usage>
+                </usages>
+            </finalPhase>
+        </plan>
 
     </plans>
     <priceLists>
@@ -274,6 +332,7 @@
                 <plan>consumable-in-advance-topup</plan>
                 <plan>capacity-in-arrear</plan>
                 <plan>consumable-in-arrear</plan>
+                <plan>chocolate-monthly</plan>
             </plans>
         </defaultPriceList>
     </priceLists>
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PhasePriceOverrideJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PhasePriceOverrideJson.java
index 379536e..037ab58 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PhasePriceOverrideJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PhasePriceOverrideJson.java
@@ -189,7 +189,7 @@ public class PhasePriceOverrideJson {
                         for (final TierPriceOverrideJson tierPriceOverrideJson : usageOverrideJson.getTierPriceOverrides()) {
                             List<TieredBlockPriceOverride> blockPriceOverrides = new LinkedList<TieredBlockPriceOverride>();
                             for (final BlockPriceOverrideJson block : tierPriceOverrideJson.getBlockPriceOverrides()) {
-                                DefaultTieredBlockPriceOverride tieredBlockPriceOverride = new DefaultTieredBlockPriceOverride( block.getUnitName(), block.getSize(), block.getPrice(), block.getMax());
+                                DefaultTieredBlockPriceOverride tieredBlockPriceOverride = new DefaultTieredBlockPriceOverride( block.getUnitName(), block.getSize(), block.getPrice(),currency, block.getMax());
                                 blockPriceOverrides.add(tieredBlockPriceOverride);
                             }
                             DefaultTierPriceOverride tierPriceOverride = new DefaultTierPriceOverride(blockPriceOverrides);