killbill-aplcache
Changes
beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithCatalogUpdate.java 2(+1 -1)
beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithEntilementPlugin.java 2(+1 -1)
catalog/src/main/java/org/killbill/billing/catalog/caching/EhCacheOverriddenPlanCache.java 115(+108 -7)
catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideBlockDefinitionModelDao.java 137(+137 -0)
catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideBlockDefinitionSqlDao.java 58(+58 -0)
catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.java 2(+1 -1)
catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseUsageModelDao.java 96(+96 -0)
catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseUsageSqlDao.java 51(+51 -0)
catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideTierBlockModelDao.java 95(+95 -0)
catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideTierBlockSqlDao.java 50(+50 -0)
catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideTierDefinitionModelDao.java 108(+108 -0)
catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideTierDefinitionSqlDao.java 49(+49 -0)
catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideUsageDefinitionModelDao.java 130(+130 -0)
catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideUsageDefinitionSqlDao.java 53(+53 -0)
catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideUsageTierModelDao.java 94(+94 -0)
catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideUsageTierSqlDao.java 51(+51 -0)
catalog/src/main/java/org/killbill/billing/catalog/dao/PhaseUsageKeysCollectionBinder.java 56(+56 -0)
catalog/src/main/java/org/killbill/billing/catalog/dao/TierBlockKeysCollectionBinder.java 56(+56 -0)
catalog/src/main/java/org/killbill/billing/catalog/dao/UsageTierKeysCollectionBinder.java 57(+57 -0)
catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideBlockDefinitionSqlDao.sql.stg 81(+81 -0)
catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePhaseUsageSqlDao.sql.stg 73(+73 -0)
catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideTierBlockSqlDao.sql.stg 73(+73 -0)
catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideTierDefinitionSqlDao.sql.stg 67(+67 -0)
catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideUsageDefinitionSqlDao.sql.stg 83(+83 -0)
catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideUsageTierSqlDao.sql.stg 73(+73 -0)
catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverrideBlockDefinitionSqlDao.java 107(+107 -0)
Details
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithCatalogUpdate.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithCatalogUpdate.java
index c314ac2..3f81642 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithCatalogUpdate.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithCatalogUpdate.java
@@ -201,7 +201,7 @@ public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("bar-monthly", null);
final List<PlanPhasePriceOverride> overrides = new ArrayList<PlanPhasePriceOverride>();
- overrides.add(new DefaultPlanPhasePriceOverride(plan.getFinalPhase().getName(), account.getCurrency(), null, BigDecimal.ONE));
+ overrides.add(new DefaultPlanPhasePriceOverride(plan.getFinalPhase().getName(), account.getCurrency(), null, BigDecimal.ONE, null));
final Entitlement baseEntitlement = createEntitlement(spec, overrides, true);
List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, testCallContext);
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithEntilementPlugin.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithEntilementPlugin.java
index b19e101..38ed77c 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithEntilementPlugin.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithEntilementPlugin.java
@@ -103,7 +103,7 @@ public class TestWithEntilementPlugin extends TestIntegrationBase {
accountChecker.checkAccount(account.getId(), accountData, callContext);
final List<PlanPhasePriceOverride> overrides = new ArrayList<PlanPhasePriceOverride>();
- overrides.add(new DefaultPlanPhasePriceOverride("shotgun-monthly-evergreen", account.getCurrency(), null, BigDecimal.TEN));
+ overrides.add(new DefaultPlanPhasePriceOverride("shotgun-monthly-evergreen", account.getCurrency(), null, BigDecimal.TEN, null));
testEntitlementPluginApi.setPlanPhasePriceOverride(overrides);
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithPriceOverride.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithPriceOverride.java
index 0869e63..54de017 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithPriceOverride.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithPriceOverride.java
@@ -57,7 +57,7 @@ public class TestWithPriceOverride extends TestIntegrationBase {
accountChecker.checkAccount(account.getId(), accountData, callContext);
final List<PlanPhasePriceOverride> overrides = new ArrayList<PlanPhasePriceOverride>();
- overrides.add(new DefaultPlanPhasePriceOverride("shotgun-monthly-trial", account.getCurrency(), BigDecimal.ONE, null));
+ overrides.add(new DefaultPlanPhasePriceOverride("shotgun-monthly-trial", account.getCurrency(), BigDecimal.ONE, null, null));
final DefaultEntitlement bpSubscription = createBaseEntitlementWithPriceOverrideAndCheckForCompletion(account.getId(), "bundleKey", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, overrides, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
// Check bundle after BP got created otherwise we get an error from auditApi.
@@ -76,7 +76,7 @@ public class TestWithPriceOverride extends TestIntegrationBase {
accountChecker.checkAccount(account.getId(), accountData, callContext);
final List<PlanPhasePriceOverride> overrides = new ArrayList<PlanPhasePriceOverride>();
- overrides.add(new DefaultPlanPhasePriceOverride("shotgun-monthly-evergreen", account.getCurrency(), null, BigDecimal.TEN));
+ overrides.add(new DefaultPlanPhasePriceOverride("shotgun-monthly-evergreen", account.getCurrency(), null, BigDecimal.TEN, null));
final DefaultEntitlement bpSubscription = createBaseEntitlementWithPriceOverrideAndCheckForCompletion(account.getId(), "bundleKey", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, overrides, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
// Check bundle after BP got created otherwise we get an error from auditApi.
@@ -118,7 +118,7 @@ public class TestWithPriceOverride extends TestIntegrationBase {
invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), new LocalDate(2012, 6, 1), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
final List<PlanPhasePriceOverride> overrides = new ArrayList<PlanPhasePriceOverride>();
- overrides.add(new DefaultPlanPhasePriceOverride("shotgun-monthly-evergreen", account.getCurrency(), null, new BigDecimal("279.95")));
+ overrides.add(new DefaultPlanPhasePriceOverride("shotgun-monthly-evergreen", account.getCurrency(), null, new BigDecimal("279.95"), null));
busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
bpSubscription.changePlanOverrideBillingPolicy(new PlanSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), overrides, new LocalDate(2012, 5, 1), BillingActionPolicy.IMMEDIATE, ImmutableList.<PluginProperty>of(), callContext);
@@ -165,7 +165,7 @@ public class TestWithPriceOverride extends TestIntegrationBase {
assertListenerStatus();
final List<PlanPhasePriceOverride> overrides = new ArrayList<PlanPhasePriceOverride>();
- overrides.add(new DefaultPlanPhasePriceOverride("telescopic-scope-monthly-evergreen", account.getCurrency(), null, new BigDecimal("1200.00")));
+ overrides.add(new DefaultPlanPhasePriceOverride("telescopic-scope-monthly-evergreen", account.getCurrency(), null, new BigDecimal("1200.00"), null));
busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
aoEntitlement.changePlanOverrideBillingPolicy(new PlanSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), overrides, new LocalDate(2012, 5, 5), BillingActionPolicy.IMMEDIATE, ImmutableList.<PluginProperty>of(), callContext);
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 3b54252..cfe56a9 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
@@ -17,6 +17,7 @@
package org.killbill.billing.catalog.caching;
+import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
@@ -27,14 +28,26 @@ import org.killbill.billing.ObjectType;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.DefaultPlan;
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.api.CatalogApiException;
import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.catalog.api.Plan;
import org.killbill.billing.catalog.api.PlanPhase;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.StaticCatalog;
+import org.killbill.billing.catalog.api.Tier;
+import org.killbill.billing.catalog.api.TierPriceOverride;
+import org.killbill.billing.catalog.api.TieredBlock;
+import org.killbill.billing.catalog.api.TieredBlockPriceOverride;
+import org.killbill.billing.catalog.api.Usage;
+import org.killbill.billing.catalog.api.UsagePriceOverride;
+import org.killbill.billing.catalog.dao.CatalogOverrideBlockDefinitionModelDao;
import org.killbill.billing.catalog.dao.CatalogOverrideDao;
import org.killbill.billing.catalog.dao.CatalogOverridePhaseDefinitionModelDao;
+import org.killbill.billing.catalog.dao.CatalogOverrideTierDefinitionModelDao;
+import org.killbill.billing.catalog.dao.CatalogOverrideUsageDefinitionModelDao;
import org.killbill.billing.catalog.override.DefaultPriceOverride;
import org.killbill.billing.util.cache.Cachable.CacheType;
import org.killbill.billing.util.cache.CacheController;
@@ -91,17 +104,15 @@ public class EhCacheOverriddenPlanCache implements OverriddenPlanCache {
final List<CatalogOverridePhaseDefinitionModelDao> phaseDefs = overrideDao.getOverriddenPlanPhases(planDefRecordId, context);
final DefaultPlan defaultPlan = (DefaultPlan) catalog.findCurrentPlan(parentPlanName);
-
- final PlanPhasePriceOverride[] overrides = createOverrides(defaultPlan, phaseDefs);
+ final PlanPhasePriceOverride[] overrides = createOverrides(defaultPlan, phaseDefs, context);
return new DefaultPlan(planName, defaultPlan, overrides);
}
- private PlanPhasePriceOverride[] createOverrides(final Plan defaultPlan, final List<CatalogOverridePhaseDefinitionModelDao> phaseDefs) {
+ private PlanPhasePriceOverride[] createOverrides(final Plan defaultPlan, final List<CatalogOverridePhaseDefinitionModelDao> phaseDefs, final InternalTenantContext context) {
final PlanPhasePriceOverride[] result = new PlanPhasePriceOverride[defaultPlan.getAllPhases().length];
for (int i = 0; i < defaultPlan.getAllPhases().length; i++) {
-
final PlanPhase curPhase = defaultPlan.getAllPhases()[i];
final CatalogOverridePhaseDefinitionModelDao overriddenPhase = Iterables.tryFind(phaseDefs, new Predicate<CatalogOverridePhaseDefinitionModelDao>() {
@Override
@@ -109,10 +120,100 @@ public class EhCacheOverriddenPlanCache implements OverriddenPlanCache {
return input.getParentPhaseName().equals(curPhase.getName());
}
}).orNull();
- result[i] = (overriddenPhase != null) ?
- new DefaultPlanPhasePriceOverride(curPhase.getName(), Currency.valueOf(overriddenPhase.getCurrency()), overriddenPhase.getFixedPrice(), overriddenPhase.getRecurringPrice()) :
- null;
+
+ if(overriddenPhase != null) {
+ List<UsagePriceOverride> usagePriceOverrides = getUsagePriceOverrides(curPhase, overriddenPhase, context);
+ result[i] = new DefaultPlanPhasePriceOverride(curPhase.getName(), Currency.valueOf(overriddenPhase.getCurrency()), overriddenPhase.getFixedPrice(), overriddenPhase.getRecurringPrice(), usagePriceOverrides);
+ }
+ else {
+ result[i] = null;
+ }
}
return result;
}
+
+ List<UsagePriceOverride> getUsagePriceOverrides(PlanPhase curPhase, CatalogOverridePhaseDefinitionModelDao overriddenPhase, final InternalTenantContext context) {
+
+ final List<UsagePriceOverride> usagePriceOverrides = new ArrayList<UsagePriceOverride>();
+ final List<CatalogOverrideUsageDefinitionModelDao> usageDefs = overrideDao.getOverriddenPhaseUsages(overriddenPhase.getRecordId(), context);
+
+ for(int i = 0; i < curPhase.getUsages().length; i++){
+ final Usage curUsage = curPhase.getUsages()[i];
+ final CatalogOverrideUsageDefinitionModelDao overriddenUsage = Iterables.tryFind(usageDefs, new Predicate<CatalogOverrideUsageDefinitionModelDao>() {
+ @Override
+ public boolean apply(final CatalogOverrideUsageDefinitionModelDao input) {
+ return input.getParentUsageName().equals(curUsage.getName());
+ }
+ }).orNull();
+
+ if(overriddenUsage != null) {
+ List<TierPriceOverride> tierPriceOverrides = getTierPriceOverrides(curUsage, overriddenUsage, context);
+ usagePriceOverrides.add(new DefaultUsagePriceOverride(overriddenUsage.getParentUsageName(), curUsage.getUsageType(),tierPriceOverrides));
+ }
+ }
+ return usagePriceOverrides;
+ }
+
+ List<TierPriceOverride> getTierPriceOverrides(Usage curUsage, CatalogOverrideUsageDefinitionModelDao overriddenUsage, final InternalTenantContext context) {
+
+ final List<TierPriceOverride> tierPriceOverrides = new ArrayList<TierPriceOverride>();
+
+ final List<CatalogOverrideTierDefinitionModelDao> tierDefs = overrideDao.getOverriddenUsageTiers(overriddenUsage.getRecordId(), context);
+ for(int i = 0; i < curUsage.getTiers().length; i++){
+ final Tier curTier = curUsage.getTiers()[i];
+ final TieredBlock[] curTieredBlocks = curTier.getTieredBlocks();
+
+ final CatalogOverrideTierDefinitionModelDao overriddenTier = Iterables.tryFind(tierDefs, new Predicate<CatalogOverrideTierDefinitionModelDao>() {
+ @Override
+ public boolean apply(final CatalogOverrideTierDefinitionModelDao input) {
+ final List<CatalogOverrideBlockDefinitionModelDao> blockDefs = overrideDao.getOverriddenTierBlocks(input.getRecordId(), context);
+ for(CatalogOverrideBlockDefinitionModelDao blockDef : blockDefs) {
+ String unitName = blockDef.getParentUnitName();
+ Double max = blockDef.getMax();
+ Double size = blockDef.getSize();
+
+ for(TieredBlock curTieredBlock : curTieredBlocks) {
+ if (unitName.equals(curTieredBlock.getUnit().getName()) &&
+ Double.compare(size, curTieredBlock.getSize()) == 0 &&
+ Double.compare(max, curTieredBlock.getMax()) == 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ }).orNull();
+
+ if(overriddenTier != null) {
+ List<TieredBlockPriceOverride> tieredBlockPriceOverrides = getTieredBlockPriceOverrides(curTier, overriddenTier, context);
+ tierPriceOverrides.add(new DefaultTierPriceOverride(tieredBlockPriceOverrides));
+ }
+ }
+ return tierPriceOverrides;
+ }
+
+ List<TieredBlockPriceOverride> getTieredBlockPriceOverrides(Tier curTier, CatalogOverrideTierDefinitionModelDao overriddenTier, final InternalTenantContext context) {
+
+ final List<TieredBlockPriceOverride> blockPriceOverrides = new ArrayList<TieredBlockPriceOverride>();
+ final List<CatalogOverrideBlockDefinitionModelDao> blockDefs = overrideDao.getOverriddenTierBlocks(overriddenTier.getRecordId(), context);
+
+ for(int i = 0; i < curTier.getTieredBlocks().length; i++){
+ final TieredBlock curTieredBlock = curTier.getTieredBlocks()[i];
+ final CatalogOverrideBlockDefinitionModelDao overriddenTierBlock = Iterables.tryFind(blockDefs, new Predicate<CatalogOverrideBlockDefinitionModelDao>() {
+ @Override
+ public boolean apply(final CatalogOverrideBlockDefinitionModelDao input) {
+ return (input.getParentUnitName().equals(curTieredBlock.getUnit().getName()) &&
+ Double.compare(input.getSize(), curTieredBlock.getSize()) == 0 &&
+ Double.compare(input.getMax(), curTieredBlock.getMax()) == 0);
+
+ }
+ }).orNull();
+
+ if(overriddenTierBlock != null) {
+ blockPriceOverrides.add(new DefaultTieredBlockPriceOverride(overriddenTierBlock.getParentUnitName(), overriddenTierBlock.getSize(), overriddenTierBlock.getPrice(), overriddenTierBlock.getMax()));
+ }
+ }
+ return blockPriceOverrides;
+ }
}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideBlockDefinitionModelDao.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideBlockDefinitionModelDao.java
new file mode 100644
index 0000000..543b0e0
--- /dev/null
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideBlockDefinitionModelDao.java
@@ -0,0 +1,137 @@
+/*
+ * 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.joda.time.DateTime;
+
+public class CatalogOverrideBlockDefinitionModelDao {
+
+ private Long recordId;
+ private String parentUnitName;
+ private String currency;
+ private BigDecimal price;
+ private String blockType;
+ private double size;
+ private double max;
+ private DateTime effectiveDate;
+ private DateTime createdDate;
+ private String createdBy;
+ private Long tenantRecordId;
+
+ public Long getRecordId() {
+ return recordId;
+ }
+
+ public void setRecordId(Long recordId) {
+ this.recordId = recordId;
+ }
+
+ public String getParentUnitName() {
+ return parentUnitName;
+ }
+
+ public void setParentUnitName(String parentUnitName) {
+ this.parentUnitName = parentUnitName;
+ }
+
+ public String getCurrency() {
+ return currency;
+ }
+
+ public void setCurrency(String currency) {
+ this.currency = currency;
+ }
+
+ public BigDecimal getPrice() {
+ return price;
+ }
+
+ public void setPrice(BigDecimal price) {
+ this.price = price;
+ }
+
+ public String getBlockType() {
+ return blockType;
+ }
+
+ public void setBlockType(String blockType) {
+ this.blockType = blockType;
+ }
+
+ public double getSize() {
+ return size;
+ }
+
+ public void setSize(double size) {
+ this.size = size;
+ }
+
+ public double getMax() {
+ return max;
+ }
+
+ public void setMax(double max) {
+ this.max = max;
+ }
+
+ public DateTime getEffectiveDate() {
+ return effectiveDate;
+ }
+
+ public void setEffectiveDate(DateTime effectiveDate) {
+ this.effectiveDate = effectiveDate;
+ }
+
+ public DateTime getCreatedDate() {
+ return createdDate;
+ }
+
+ public void setCreatedDate(DateTime createdDate) {
+ this.createdDate = createdDate;
+ }
+
+ public String getCreatedBy() {
+ return createdBy;
+ }
+
+ public void setCreatedBy(String createdBy) {
+ this.createdBy = createdBy;
+ }
+
+ public Long getTenantRecordId() {
+ return tenantRecordId;
+ }
+
+ public void setTenantRecordId(Long tenantRecordId) {
+ this.tenantRecordId = tenantRecordId;
+ }
+
+ public CatalogOverrideBlockDefinitionModelDao() {
+ }
+
+ public CatalogOverrideBlockDefinitionModelDao(String parentUnitName, String currency, BigDecimal price, double size, double max, DateTime effectiveDate) {
+ this.parentUnitName = parentUnitName;
+ this.currency = currency;
+ this.price = price;
+ this.size = size;
+ this.max = max;
+ this.effectiveDate = effectiveDate;
+ }
+}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideBlockDefinitionSqlDao.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideBlockDefinitionSqlDao.java
new file mode 100644
index 0000000..a09b696
--- /dev/null
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideBlockDefinitionSqlDao.java
@@ -0,0 +1,58 @@
+/*
+ * 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.List;
+
+import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
+import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
+
+@EntitySqlDaoStringTemplate
+public interface CatalogOverrideBlockDefinitionSqlDao extends Transactional<CatalogOverrideBlockDefinitionSqlDao>, CloseMe {
+
+ @SqlUpdate
+ public void create(@SmartBindBean final CatalogOverrideBlockDefinitionModelDao entity,
+ @SmartBindBean final InternalCallContext context);
+
+ @SqlQuery
+ public CatalogOverrideBlockDefinitionModelDao getByRecordId(@Bind("recordId") final Long recordId,
+ @SmartBindBean final InternalTenantContext context);
+
+ @SqlQuery
+ public CatalogOverrideBlockDefinitionModelDao getByAttributes(@Bind("parentUnitName") final String parentUnitName,
+ @Bind("currency") final String currency,
+ @Bind("price") final BigDecimal price,
+ @Bind("max") final double max,
+ @Bind("size") final double size,
+ @SmartBindBean final InternalTenantContext context);
+
+ @SqlQuery
+ public List<CatalogOverrideBlockDefinitionModelDao> getOverriddenTierBlocks(@Bind("targetTierDefRecordId") Long targetTierDefRecordId,
+ @SmartBindBean final InternalTenantContext context);
+
+ @SqlQuery
+ public Long getLastInsertId();
+}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideDao.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideDao.java
index eaef9b1..64ca132 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideDao.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideDao.java
@@ -22,12 +22,19 @@ import java.util.List;
import org.joda.time.DateTime;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.catalog.api.Plan;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
public interface CatalogOverrideDao {
- public CatalogOverridePlanDefinitionModelDao getOrCreateOverridePlanDefinition(String parentPlanName, DateTime catalogEffectiveDate, PlanPhasePriceOverride[] resolvedOverride, InternalCallContext context);
+ public CatalogOverridePlanDefinitionModelDao getOrCreateOverridePlanDefinition(Plan parentPlan, DateTime catalogEffectiveDate, PlanPhasePriceOverride[] resolvedOverride, InternalCallContext context);
public List<CatalogOverridePhaseDefinitionModelDao> getOverriddenPlanPhases(final Long planDefRecordId, final InternalTenantContext context);
+ public List<CatalogOverrideUsageDefinitionModelDao> getOverriddenPhaseUsages(final Long phaseDefRecordId, final InternalTenantContext context);
+
+ public List<CatalogOverrideTierDefinitionModelDao> getOverriddenUsageTiers(final Long usageDefRecordId, final InternalTenantContext context);
+
+ public List<CatalogOverrideBlockDefinitionModelDao> getOverriddenTierBlocks(final Long tierDefRecordId, final InternalTenantContext context);
+
}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.java
index 87061c9..19164aa 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.java
@@ -42,7 +42,7 @@ public interface CatalogOverridePhaseDefinitionSqlDao extends Transactional<Cata
@SmartBindBean final InternalTenantContext context);
@SqlQuery
- public CatalogOverridePhaseDefinitionModelDao getByAttributes(@Bind("parentPhaseName") String parentPhaseName,
+ public List<CatalogOverridePhaseDefinitionModelDao> getByAttributes(@Bind("parentPhaseName") String parentPhaseName,
@Bind("currency") String currency,
@Bind("fixedPrice") BigDecimal fixedPrice,
@Bind("recurringPrice") BigDecimal recurringPrice,
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
new file mode 100644
index 0000000..b4e8f7f
--- /dev/null
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseUsageModelDao.java
@@ -0,0 +1,96 @@
+/*
+ * 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 org.joda.time.DateTime;
+
+public class CatalogOverridePhaseUsageModelDao {
+
+ private Short usageNumber;
+ private Long recordId;
+ private Long usageDefRecordId;
+ private Long targetPhaseDefRecordId;
+ private DateTime createdDate;
+ private String createdBy;
+ private Long tenantRecordId;
+
+ public CatalogOverridePhaseUsageModelDao() {
+ }
+
+ public CatalogOverridePhaseUsageModelDao(Short usageNumber, Long usageDefRecordId, Long targetPhaseDefRecordId) {
+ this.usageNumber = usageNumber;
+ this.usageDefRecordId = usageDefRecordId;
+ this.targetPhaseDefRecordId = targetPhaseDefRecordId;
+ }
+
+ public Long getRecordId() {
+ return recordId;
+ }
+
+ public Short getUsageNumber() {
+ return usageNumber;
+ }
+
+ public Long getUsageDefRecordId() {
+ return usageDefRecordId;
+ }
+
+ public Long getTargetPhaseDefRecordId() {
+ return targetPhaseDefRecordId;
+ }
+
+ public DateTime getCreatedDate() {
+ return createdDate;
+ }
+
+ public String getCreatedBy() {
+ return createdBy;
+ }
+
+ public Long getTenantRecordId() {
+ return tenantRecordId;
+ }
+
+ public void setRecordId(Long recordId) {
+ this.recordId = recordId;
+ }
+
+ public void setUsageNumber(Short usageNumber) {
+ this.usageNumber = usageNumber;
+ }
+
+ public void setUsageDefRecordId(Long usageDefRecordId) {
+ this.usageDefRecordId = usageDefRecordId;
+ }
+
+ public void setTargetPhaseDefRecordId(Long targetPhaseDefRecordId) {
+ this.targetPhaseDefRecordId = targetPhaseDefRecordId;
+ }
+
+ public void setCreatedDate(DateTime createdDate) {
+ this.createdDate = createdDate;
+ }
+
+ public void setCreatedBy(String createdBy) {
+ this.createdBy = createdBy;
+ }
+
+ public void setTenantRecordId(Long tenantRecordId) {
+ this.tenantRecordId = tenantRecordId;
+ }
+}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseUsageSqlDao.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseUsageSqlDao.java
new file mode 100644
index 0000000..5c63d82
--- /dev/null
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseUsageSqlDao.java
@@ -0,0 +1,51 @@
+/*
+ * 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.util.Collection;
+import java.util.List;
+
+import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
+import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
+
+@EntitySqlDaoStringTemplate
+public interface CatalogOverridePhaseUsageSqlDao extends Transactional<CatalogOverridePhaseUsageSqlDao>, CloseMe {
+
+ @SqlUpdate
+ public void create(@SmartBindBean final CatalogOverridePhaseUsageModelDao entity,
+ @SmartBindBean final InternalCallContext context);
+
+ @SqlQuery
+ public CatalogOverridePhaseUsageModelDao getByRecordId(@Bind("recordId") final Long recordId,
+ @SmartBindBean final InternalTenantContext context);
+
+ @SqlQuery
+ public List<Long> getTargetPhaseDefinition(@PhaseUsageKeysCollectionBinder final Collection<String> concatUsageNumAndUsageDefRecordId,
+ @Bind("targetCount") final Integer targetCount,
+ @SmartBindBean final InternalTenantContext context);
+
+ @SqlQuery
+ public Long getLastInsertId();
+}
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
new file mode 100644
index 0000000..8235a08
--- /dev/null
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideTierBlockModelDao.java
@@ -0,0 +1,95 @@
+/*
+ * 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 org.joda.time.DateTime;
+
+public class CatalogOverrideTierBlockModelDao {
+ private Short blockNumber;
+ private Long recordId;
+ private Long blockDefRecordId;
+ private Long targetTierRecordId;
+ private DateTime createdDate;
+ private String createdBy;
+ private Long tenantRecordId;
+
+ public CatalogOverrideTierBlockModelDao() {
+ }
+
+ public CatalogOverrideTierBlockModelDao(Short blockNumber, Long blockDefRecordId, Long targetTierRecordId) {
+ this.blockNumber = blockNumber;
+ this.blockDefRecordId = blockDefRecordId;
+ this.targetTierRecordId = targetTierRecordId;
+ }
+
+ public Short getBlockNumber() {
+ return blockNumber;
+ }
+
+ public Long getRecordId() {
+ return recordId;
+ }
+
+ public Long getBlockDefRecordId() {
+ return blockDefRecordId;
+ }
+
+ public Long getTargetTierRecordId() {
+ return targetTierRecordId;
+ }
+
+ public String getCreatedBy() {
+ return createdBy;
+ }
+
+ public DateTime getCreatedDate() {
+ return createdDate;
+ }
+
+ public Long getTenantRecordId() {
+ return tenantRecordId;
+ }
+
+ public void setBlockNumber(Short blockNumber) {
+ this.blockNumber = blockNumber;
+ }
+
+ public void setRecordId(Long recordId) {
+ this.recordId = recordId;
+ }
+
+ public void setBlockDefRecordId(Long blockDefRecordId) {
+ this.blockDefRecordId = blockDefRecordId;
+ }
+
+ public void setTargetTierRecordId(Long targetTierRecordId) {
+ this.targetTierRecordId = targetTierRecordId;
+ }
+
+ public void setCreatedDate(DateTime createdDate) {
+ this.createdDate = createdDate;
+ }
+
+ public void setCreatedBy(String createdBy) {
+ this.createdBy = createdBy;
+ }
+
+ public void setTenantRecordId(Long tenantRecordId) {
+ this.tenantRecordId = tenantRecordId;
+ }
+}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideTierBlockSqlDao.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideTierBlockSqlDao.java
new file mode 100644
index 0000000..998cb87
--- /dev/null
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideTierBlockSqlDao.java
@@ -0,0 +1,50 @@
+/*
+ * 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.util.Collection;
+
+import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
+import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
+
+@EntitySqlDaoStringTemplate
+public interface CatalogOverrideTierBlockSqlDao extends Transactional<CatalogOverrideTierBlockSqlDao>, CloseMe {
+
+ @SqlUpdate
+ public void create(@SmartBindBean final CatalogOverrideTierBlockModelDao entity,
+ @SmartBindBean final InternalCallContext context);
+
+ @SqlQuery
+ public CatalogOverrideTierBlockModelDao getByRecordId(@Bind("recordId") final Long recordId,
+ @SmartBindBean final InternalTenantContext context);
+
+ @SqlQuery
+ public Long getTargetTierDefinition(@TierBlockKeysCollectionBinder final Collection<String> concatBlockNumAndBlockDefRecordId,
+ @Bind("targetCount") final Integer targetCount,
+ @SmartBindBean final InternalTenantContext context);
+
+ @SqlQuery
+ public Long getLastInsertId();
+}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideTierDefinitionModelDao.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideTierDefinitionModelDao.java
new file mode 100644
index 0000000..27c758e
--- /dev/null
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideTierDefinitionModelDao.java
@@ -0,0 +1,108 @@
+/*
+ * 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 org.joda.time.DateTime;
+
+import java.math.BigDecimal;
+
+public class CatalogOverrideTierDefinitionModelDao {
+
+ private Long recordId;
+ private String currency;
+ private BigDecimal fixedPrice;
+ private BigDecimal recurringPrice;
+ private DateTime effectiveDate;
+ private DateTime createdDate;
+ private String createdBy;
+ private Long tenantRecordId;
+
+ public CatalogOverrideTierDefinitionModelDao() {
+ }
+
+ public CatalogOverrideTierDefinitionModelDao( String currency, BigDecimal fixedPrice, BigDecimal recurringPrice, DateTime effectiveDate) {
+ this.currency = currency;
+ this.fixedPrice = fixedPrice;
+ this.recurringPrice = recurringPrice;
+ this.effectiveDate = effectiveDate;
+ }
+
+ public Long getRecordId() {
+ return recordId;
+ }
+
+ public void setRecordId(Long recordId) {
+ this.recordId = recordId;
+ }
+
+ public String getCurrency() {
+ return currency;
+ }
+
+ public void setCurrency(String currency) {
+ this.currency = currency;
+ }
+
+ public BigDecimal getFixedPrice() {
+ return fixedPrice;
+ }
+
+ public void setFixedPrice(BigDecimal fixedPrice) {
+ this.fixedPrice = fixedPrice;
+ }
+
+ public BigDecimal getRecurringPrice() {
+ return recurringPrice;
+ }
+
+ public void setRecurringPrice(BigDecimal recurringPrice) {
+ this.recurringPrice = recurringPrice;
+ }
+
+ public DateTime getEffectiveDate() {
+ return effectiveDate;
+ }
+
+ public void setEffectiveDate(DateTime effectiveDate) {
+ this.effectiveDate = effectiveDate;
+ }
+
+ public DateTime getCreatedDate() {
+ return createdDate;
+ }
+
+ public void setCreatedDate(DateTime createdDate) {
+ this.createdDate = createdDate;
+ }
+
+ public String getCreatedBy() {
+ return createdBy;
+ }
+
+ public void setCreatedBy(String createdBy) {
+ this.createdBy = createdBy;
+ }
+
+ public Long getTenantRecordId() {
+ return tenantRecordId;
+ }
+
+ public void setTenantRecordId(Long tenantRecordId) {
+ this.tenantRecordId = tenantRecordId;
+ }
+}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideTierDefinitionSqlDao.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideTierDefinitionSqlDao.java
new file mode 100644
index 0000000..eecf646
--- /dev/null
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideTierDefinitionSqlDao.java
@@ -0,0 +1,49 @@
+/*
+ * 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.util.List;
+
+import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
+import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
+
+@EntitySqlDaoStringTemplate
+public interface CatalogOverrideTierDefinitionSqlDao extends Transactional<CatalogOverrideTierDefinitionSqlDao>, CloseMe {
+
+ @SqlUpdate
+ public void create(@SmartBindBean final CatalogOverrideTierDefinitionModelDao entity,
+ @SmartBindBean final InternalCallContext context);
+
+ @SqlQuery
+ public CatalogOverrideTierDefinitionModelDao getByRecordId(@Bind("recordId") final Long recordId,
+ @SmartBindBean final InternalTenantContext context);
+
+ @SqlQuery
+ public List<CatalogOverrideTierDefinitionModelDao> getOverriddenUsageTiers(@Bind("targetUsageDefRecordId") Long targetUsageDefRecordId,
+ @SmartBindBean final InternalTenantContext context);
+
+ @SqlQuery
+ public Long getLastInsertId();
+}
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
new file mode 100644
index 0000000..df9c010
--- /dev/null
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideUsageDefinitionModelDao.java
@@ -0,0 +1,130 @@
+/*
+ * 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 org.joda.time.DateTime;
+
+import java.math.BigDecimal;
+
+public class CatalogOverrideUsageDefinitionModelDao {
+
+ private Long recordId;
+ private String parentUsageName;
+ private String parentUsageType;
+ private String currency;
+ private BigDecimal fixedPrice;
+ private BigDecimal recurringPrice;
+ private DateTime effectiveDate;
+ private DateTime createdDate;
+ private String createdBy;
+ private Long tenantRecordId;
+
+ public CatalogOverrideUsageDefinitionModelDao() {
+ }
+
+ public CatalogOverrideUsageDefinitionModelDao(String parentUsageName, String parentUsageType, String currency, BigDecimal fixedPrice, BigDecimal recurringPrice, DateTime effectiveDate) {
+
+ this.parentUsageName = parentUsageName;
+ this.parentUsageType = parentUsageType;
+ this.currency = currency;
+ this.fixedPrice = fixedPrice;
+ this.recurringPrice = recurringPrice;
+ this.effectiveDate = effectiveDate;
+ }
+
+ public Long getRecordId() {
+ return recordId;
+ }
+
+ public void setRecordId(Long recordId) {
+ this.recordId = recordId;
+ }
+
+ public void setParentUsageName(String parentUsageName) {
+ this.parentUsageName = parentUsageName;
+ }
+
+ public void setParentUsageType(String parentUsageType) {
+ this.parentUsageType = parentUsageType;
+ }
+
+ public void setCurrency(String currency) {
+ this.currency = currency;
+ }
+
+ public void setFixedPrice(BigDecimal fixedPrice) {
+ this.fixedPrice = fixedPrice;
+ }
+
+ public void setRecurringPrice(BigDecimal recurringPrice) {
+ this.recurringPrice = recurringPrice;
+ }
+
+ public void setEffectiveDate(DateTime effectiveDate) {
+ this.effectiveDate = effectiveDate;
+ }
+
+ public void setCreatedDate(DateTime createdDate) {
+ this.createdDate = createdDate;
+ }
+
+ public void setCreatedBy(String createdBy) {
+ this.createdBy = createdBy;
+ }
+
+ public void setTenantRecordId(Long tenantRecordId) {
+ this.tenantRecordId = tenantRecordId;
+ }
+
+ public String getParentUsageName() {
+ return parentUsageName;
+ }
+
+ public String getParentUsageType() {
+ return parentUsageType;
+ }
+
+ public String getCurrency() {
+ return currency;
+ }
+
+ public BigDecimal getFixedPrice() {
+ return fixedPrice;
+ }
+
+ public BigDecimal getRecurringPrice() {
+ return recurringPrice;
+ }
+
+ public DateTime getEffectiveDate() {
+ return effectiveDate;
+ }
+
+ public DateTime getCreatedDate() {
+ return createdDate;
+ }
+
+ public String getCreatedBy() {
+ return createdBy;
+ }
+
+ public Long getTenantRecordId() {
+ return tenantRecordId;
+ }
+
+}
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
new file mode 100644
index 0000000..a54e776
--- /dev/null
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideUsageDefinitionSqlDao.java
@@ -0,0 +1,53 @@
+/*
+ * 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.util.List;
+
+import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
+import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
+
+@EntitySqlDaoStringTemplate
+public interface CatalogOverrideUsageDefinitionSqlDao extends Transactional<CatalogOverrideUsageDefinitionSqlDao>, CloseMe {
+
+ @SqlUpdate
+ public void create(@SmartBindBean final CatalogOverrideUsageDefinitionModelDao entity,
+ @SmartBindBean final InternalCallContext context);
+
+ @SqlQuery
+ public CatalogOverrideUsageDefinitionModelDao getByRecordId(@Bind("recordId") final Long recordId,
+ @SmartBindBean final InternalTenantContext context);
+
+ @SqlQuery
+ public List<CatalogOverrideUsageDefinitionModelDao> getOverriddenPhaseUsages(@Bind("targetPhaseDefRecordId") Long targetPhaseDefRecordId,
+ @SmartBindBean final InternalTenantContext context);
+
+ @SqlQuery
+ public List<CatalogOverrideUsageDefinitionModelDao> getByAttributes(@Bind("parentUsageName") String parentPhaseName,
+ @SmartBindBean final InternalTenantContext context);
+
+ @SqlQuery
+ public Long getLastInsertId();
+}
\ No newline at end of file
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideUsageTierModelDao.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideUsageTierModelDao.java
new file mode 100644
index 0000000..ec05e28
--- /dev/null
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideUsageTierModelDao.java
@@ -0,0 +1,94 @@
+/*
+ * 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 org.joda.time.DateTime;
+
+public class CatalogOverrideUsageTierModelDao {
+
+ private Long recordId;
+ private Short tierNumber;
+ private Long tierDefRecordId;
+ private Long targetUsageDefRecordId;
+ private DateTime createdDate;
+ private String createdBy;
+ private Long tenantRecordId;
+
+ public CatalogOverrideUsageTierModelDao() {
+ }
+
+ public CatalogOverrideUsageTierModelDao(Short tierNumber, Long tierDefRecordId, Long targetUsageDefRecordId) {
+ this.tierNumber = tierNumber;
+ this.tierDefRecordId = tierDefRecordId;
+ this.targetUsageDefRecordId = targetUsageDefRecordId;
+ }
+
+ public Long getRecordId() { return recordId; }
+
+ public Short getTierNumber() {
+ return tierNumber;
+ }
+
+ public void setTierNumber(Short tierNumber) {
+ this.tierNumber = tierNumber;
+ }
+
+ public Long getTierDefRecordId() {
+ return tierDefRecordId;
+ }
+
+ public Long getTargetUsageDefRecordId() {
+ return targetUsageDefRecordId;
+ }
+
+ public DateTime getCreatedDate() {
+ return createdDate;
+ }
+
+ public void setRecordId(Long recordId) {
+ this.recordId = recordId;
+ }
+
+ public void setTierDefRecordId(Long tierDefRecordId) {
+ this.tierDefRecordId = tierDefRecordId;
+ }
+
+ public void setTargetUsageDefRecordId(Long targetUsageDefRecordId) {
+ this.targetUsageDefRecordId = targetUsageDefRecordId;
+ }
+
+ public void setCreatedDate(DateTime createdDate) {
+ this.createdDate = createdDate;
+ }
+
+ public void setCreatedBy(String createdBy) {
+ this.createdBy = createdBy;
+ }
+
+ public void setTenantRecordId(Long tenantRecordId) {
+ this.tenantRecordId = tenantRecordId;
+ }
+
+ public String getCreatedBy() {
+ return createdBy;
+ }
+
+ public Long getTenantRecordId() {
+ return tenantRecordId;
+ }
+}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideUsageTierSqlDao.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideUsageTierSqlDao.java
new file mode 100644
index 0000000..7665047
--- /dev/null
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverrideUsageTierSqlDao.java
@@ -0,0 +1,51 @@
+/*
+ * 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.util.Collection;
+import java.util.List;
+
+import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
+import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
+
+@EntitySqlDaoStringTemplate
+public interface CatalogOverrideUsageTierSqlDao extends Transactional<CatalogOverrideUsageTierSqlDao>, CloseMe {
+
+ @SqlUpdate
+ public void create(@SmartBindBean final CatalogOverrideUsageTierModelDao entity,
+ @SmartBindBean final InternalCallContext context);
+
+ @SqlQuery
+ public CatalogOverrideUsageTierModelDao getByRecordId(@Bind("recordId") final Long recordId,
+ @SmartBindBean final InternalTenantContext context);
+
+ @SqlQuery
+ public List<Long> getTargetUsageDefinition(@UsageTierKeysCollectionBinder final Collection<String> concatTierNumAndTierDefRecordId,
+ @Bind("targetCount") final Integer targetCount,
+ @SmartBindBean final InternalTenantContext context);
+
+ @SqlQuery
+ public Long getLastInsertId();
+}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/DefaultCatalogOverrideDao.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/DefaultCatalogOverrideDao.java
index 8b9f31c..1173418 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/dao/DefaultCatalogOverrideDao.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/DefaultCatalogOverrideDao.java
@@ -23,7 +23,15 @@ import java.util.List;
import org.joda.time.DateTime;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.catalog.api.Currency;
+import org.killbill.billing.catalog.api.Plan;
+import org.killbill.billing.catalog.api.PlanPhase;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
+import org.killbill.billing.catalog.api.Tier;
+import org.killbill.billing.catalog.api.TierPriceOverride;
+import org.killbill.billing.catalog.api.TieredBlockPriceOverride;
+import org.killbill.billing.catalog.api.Usage;
+import org.killbill.billing.catalog.api.UsagePriceOverride;
import org.killbill.clock.Clock;
import org.killbill.commons.jdbi.mapper.LowerToCamelBeanMapperFactory;
import org.skife.jdbi.v2.DBI;
@@ -47,10 +55,16 @@ public class DefaultCatalogOverrideDao implements CatalogOverrideDao {
((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(CatalogOverridePlanDefinitionModelDao.class));
((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(CatalogOverridePhaseDefinitionModelDao.class));
((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(CatalogOverridePlanPhaseModelDao.class));
+ ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(CatalogOverrideBlockDefinitionModelDao.class));
+ ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(CatalogOverrideTierBlockModelDao.class));
+ ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(CatalogOverrideTierDefinitionModelDao.class));
+ ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(CatalogOverrideUsageDefinitionModelDao.class));
+ ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(CatalogOverrideUsageTierModelDao.class));
+ ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(CatalogOverridePhaseUsageModelDao.class));
}
@Override
- public CatalogOverridePlanDefinitionModelDao getOrCreateOverridePlanDefinition(final String parentPlanName, final DateTime catalogEffectiveDate, final PlanPhasePriceOverride[] resolvedOverride, final InternalCallContext context) {
+ public CatalogOverridePlanDefinitionModelDao getOrCreateOverridePlanDefinition(final Plan parentPlan, final DateTime catalogEffectiveDate, final PlanPhasePriceOverride[] resolvedOverride, final InternalCallContext context) {
return dbi.inTransaction(new TransactionCallback<CatalogOverridePlanDefinitionModelDao>() {
@Override
@@ -60,7 +74,8 @@ public class DefaultCatalogOverrideDao implements CatalogOverrideDao {
for (int i = 0; i < resolvedOverride.length; i++) {
final PlanPhasePriceOverride curOverride = resolvedOverride[i];
if (curOverride != null) {
- final CatalogOverridePhaseDefinitionModelDao createdOverridePhaseDefinitionModelDao = getOrCreateOverridePhaseDefinitionFromTransaction(curOverride.getPhaseName(), catalogEffectiveDate, curOverride, handle, context);
+ PlanPhase parentPlanPhase = parentPlan.getAllPhases()[i];
+ final CatalogOverridePhaseDefinitionModelDao createdOverridePhaseDefinitionModelDao = getOrCreateOverridePhaseDefinitionFromTransaction(parentPlanPhase, curOverride.getPhaseName(),curOverride.getCurrency(), catalogEffectiveDate, curOverride, handle, context);
overridePhaseDefinitionModelDaos[i] = createdOverridePhaseDefinitionModelDao;
}
}
@@ -71,7 +86,7 @@ public class DefaultCatalogOverrideDao implements CatalogOverrideDao {
return sqlDao.getByRecordId(targetPlanDefinitionRecordId, context);
}
- final CatalogOverridePlanDefinitionModelDao inputPlanDef = new CatalogOverridePlanDefinitionModelDao(parentPlanName, true, catalogEffectiveDate);
+ final CatalogOverridePlanDefinitionModelDao inputPlanDef = new CatalogOverridePlanDefinitionModelDao(parentPlan.getName(), true, catalogEffectiveDate);
sqlDao.create(inputPlanDef, context);
final Long recordId = sqlDao.getLastInsertId();
final CatalogOverridePlanDefinitionModelDao resultPlanDef = sqlDao.getByRecordId(recordId, context);
@@ -86,17 +101,6 @@ public class DefaultCatalogOverrideDao implements CatalogOverrideDao {
});
}
- @Override
- public List<CatalogOverridePhaseDefinitionModelDao> getOverriddenPlanPhases(final Long planDefRecordId, final InternalTenantContext context) {
- return dbi.inTransaction(new TransactionCallback<List<CatalogOverridePhaseDefinitionModelDao>>() {
- @Override
- public List<CatalogOverridePhaseDefinitionModelDao> inTransaction(final Handle handle, final TransactionStatus status) throws Exception {
- final CatalogOverridePhaseDefinitionSqlDao sqlDao = handle.attach(CatalogOverridePhaseDefinitionSqlDao.class);
- return sqlDao.getOverriddenPlanPhases(planDefRecordId, context);
- }
- });
- }
-
private Long getOverridePlanDefinitionFromTransaction(final CatalogOverridePhaseDefinitionModelDao[] overridePhaseDefinitionModelDaos, final Handle inTransactionHandle, final InternalCallContext context) {
final CatalogOverridePlanPhaseSqlDao sqlDao = inTransactionHandle.attach(CatalogOverridePlanPhaseSqlDao.class);
@@ -105,11 +109,7 @@ public class DefaultCatalogOverrideDao implements CatalogOverrideDao {
final CatalogOverridePhaseDefinitionModelDao cur = overridePhaseDefinitionModelDaos[i];
if (cur != null) {
// Each key is the concatenation of the phase_number, phase_definition_record_id
- final StringBuffer key = new StringBuffer();
- key.append(i);
- key.append(",");
- key.append(cur.getRecordId());
- keys.add(key.toString());
+ keys.add(getConcatenatedKey(i, cur.getRecordId()).toString());
}
}
return keys.size() > 0 ? sqlDao.getTargetPlanDefinition(keys, keys.size(), context) : null;
@@ -121,16 +121,270 @@ public class DefaultCatalogOverrideDao implements CatalogOverrideDao {
sqlDao.create(modelDao, context);
}
- private CatalogOverridePhaseDefinitionModelDao getOrCreateOverridePhaseDefinitionFromTransaction(final String parentPhaseName, final DateTime catalogEffectiveDate, final PlanPhasePriceOverride override, final Handle inTransactionHandle, final InternalCallContext context) {
+ private CatalogOverridePhaseDefinitionModelDao getOrCreateOverridePhaseDefinitionFromTransaction(final PlanPhase parentPlanPhase, final String parentPhaseName, final Currency currency, final DateTime catalogEffectiveDate, final PlanPhasePriceOverride override, final Handle inTransactionHandle, final InternalCallContext context) {
+ final CatalogOverridePhaseDefinitionSqlDao sqlDao = inTransactionHandle.attach(CatalogOverridePhaseDefinitionSqlDao.class);
+
+ if(override.getUsagePriceOverrides() == null || (override.getUsagePriceOverrides() != null && isUsageOverrideListHasOnlyNull(override.getUsagePriceOverrides()))) {
+ return getOrCreatePhaseDefinitionFromTransactionWithoutUsageOverrides(parentPhaseName, catalogEffectiveDate, override, inTransactionHandle, context);
+ }
+
+ final CatalogOverrideUsageDefinitionModelDao[] overrideUsageDefinitionModelDaos = new CatalogOverrideUsageDefinitionModelDao[override.getUsagePriceOverrides().size()];
+ List<UsagePriceOverride> resolvedUsageOverrides = override.getUsagePriceOverrides();
+ for (int i = 0; i < resolvedUsageOverrides.size(); i++) {
+ final UsagePriceOverride curOverride = resolvedUsageOverrides.get(i);
+ if (curOverride != null) {
+ Usage parentUsage = parentPlanPhase.getUsages()[i];
+ final CatalogOverrideUsageDefinitionModelDao createdOverrideUsageDefinitionModelDao = getOrCreateOverrideUsageDefinitionFromTransaction(parentUsage, currency, catalogEffectiveDate, curOverride, inTransactionHandle, context);
+ overrideUsageDefinitionModelDaos[i] = createdOverrideUsageDefinitionModelDao;
+ }
+ }
+
+ final List<Long> targetPhaseDefinitionRecordIds = getOverridePhaseDefinitionFromTransaction(overrideUsageDefinitionModelDaos, inTransactionHandle, context);
+ List<CatalogOverridePhaseDefinitionModelDao> results = sqlDao.getByAttributes(parentPhaseName, override.getCurrency().name(), override.getFixedPrice(), override.getRecurringPrice(), context);
+
+ for(CatalogOverridePhaseDefinitionModelDao phase : results) {
+ if (targetPhaseDefinitionRecordIds != null && targetPhaseDefinitionRecordIds.contains(phase.getRecordId())) {
+ return phase;
+ }
+ }
+
+ final CatalogOverridePhaseDefinitionModelDao inputPhaseDef = new CatalogOverridePhaseDefinitionModelDao(parentPhaseName, override.getCurrency().name(), override.getFixedPrice(), override.getRecurringPrice(),
+ catalogEffectiveDate);
+ sqlDao.create(inputPhaseDef, context);
+ final Long recordId = sqlDao.getLastInsertId();
+ final CatalogOverridePhaseDefinitionModelDao resultPhaseDef = sqlDao.getByRecordId(recordId, context);
+
+ for (short i = 0; i < overrideUsageDefinitionModelDaos.length; i++) {
+ if (overrideUsageDefinitionModelDaos[i] != null) {
+ createCatalogOverridePhaseUsageFromTransaction(i, overrideUsageDefinitionModelDaos[i], resultPhaseDef, inTransactionHandle, context);
+ }
+ }
+ return resultPhaseDef;
+ }
+
+ private CatalogOverridePhaseDefinitionModelDao getOrCreatePhaseDefinitionFromTransactionWithoutUsageOverrides(String parentPhaseName,final DateTime catalogEffectiveDate, final PlanPhasePriceOverride override, final Handle inTransactionHandle, final InternalCallContext context) {
+
final CatalogOverridePhaseDefinitionSqlDao sqlDao = inTransactionHandle.attach(CatalogOverridePhaseDefinitionSqlDao.class);
- CatalogOverridePhaseDefinitionModelDao result = sqlDao.getByAttributes(parentPhaseName, override.getCurrency().name(), override.getFixedPrice(), override.getRecurringPrice(), context);
+ List<CatalogOverridePhaseDefinitionModelDao> resultPhases = sqlDao.getByAttributes(parentPhaseName, override.getCurrency().name(), override.getFixedPrice(), override.getRecurringPrice(), context);
+ for(CatalogOverridePhaseDefinitionModelDao resultPhase : resultPhases) {
+ if (resultPhase != null && getOverriddenPhaseUsages(resultPhase.getRecordId(), context).size() == 0) {
+ return resultPhase;
+ }
+ }
+
+ final CatalogOverridePhaseDefinitionModelDao phaseDef = new CatalogOverridePhaseDefinitionModelDao(parentPhaseName, override.getCurrency().name(), override.getFixedPrice(), override.getRecurringPrice(),
+ catalogEffectiveDate);
+ sqlDao.create(phaseDef, context);
+ final Long recordId = sqlDao.getLastInsertId();
+ return sqlDao.getByRecordId(recordId, context);
+ }
+
+ private List<Long> getOverridePhaseDefinitionFromTransaction(final CatalogOverrideUsageDefinitionModelDao[] overrideUsageDefinitionModelDaos, final Handle inTransactionHandle, final InternalCallContext context) {
+ final CatalogOverridePhaseUsageSqlDao sqlDao = inTransactionHandle.attach(CatalogOverridePhaseUsageSqlDao.class);
+
+ final List<String> keys = new ArrayList<String>();
+ for (int i = 0; i < overrideUsageDefinitionModelDaos.length; i++) {
+ final CatalogOverrideUsageDefinitionModelDao cur = overrideUsageDefinitionModelDaos[i];
+ // Each key is the concatenation of the usage_number, usage_definition_record_id
+ if (cur != null) {
+ keys.add(getConcatenatedKey(i, cur.getRecordId()).toString());
+ }
+ }
+ return keys.size() > 0 ? sqlDao.getTargetPhaseDefinition(keys, keys.size(), context) : null;
+ }
+
+ private void createCatalogOverridePhaseUsageFromTransaction(final short usageNum, final CatalogOverrideUsageDefinitionModelDao usageDef, final CatalogOverridePhaseDefinitionModelDao phaseDef, final Handle inTransactionHandle, final InternalCallContext context) {
+ final CatalogOverridePhaseUsageSqlDao sqlDao = inTransactionHandle.attach(CatalogOverridePhaseUsageSqlDao.class);
+ final CatalogOverridePhaseUsageModelDao modelDao = new CatalogOverridePhaseUsageModelDao(usageNum, usageDef.getRecordId(), phaseDef.getRecordId());
+ sqlDao.create(modelDao, context);
+ }
+
+ private CatalogOverrideUsageDefinitionModelDao getOrCreateOverrideUsageDefinitionFromTransaction(final Usage parentUsage, Currency currency, final DateTime catalogEffectiveDate, final UsagePriceOverride override, final Handle inTransactionHandle, final InternalCallContext context){
+
+ final List<TierPriceOverride> resolvedTierOverrides = override.getTierPriceOverrides();
+
+ final CatalogOverrideTierDefinitionModelDao[] overrideTierDefinitionModelDaos = new CatalogOverrideTierDefinitionModelDao[resolvedTierOverrides.size()];
+ for (int i = 0; i < resolvedTierOverrides.size(); i++) {
+ final TierPriceOverride curOverride = resolvedTierOverrides.get(i);
+ if (curOverride != null) {
+ Tier parentTier = parentUsage.getTiers()[i];
+ final CatalogOverrideTierDefinitionModelDao createdOverrideTierDefinitionModelDao = getOrCreateOverrideTierDefinitionFromTransaction(parentTier, curOverride, currency, catalogEffectiveDate, inTransactionHandle, context);
+ overrideTierDefinitionModelDaos[i] = createdOverrideTierDefinitionModelDao;
+ }
+ }
+
+ final CatalogOverrideUsageDefinitionSqlDao sqlDao = inTransactionHandle.attach(CatalogOverrideUsageDefinitionSqlDao.class);
+ final List<Long> targetUsageDefinitionRecordIds = getOverrideUsageDefinitionFromTransaction(overrideTierDefinitionModelDaos, inTransactionHandle, context);
+
+ List<CatalogOverrideUsageDefinitionModelDao> results = sqlDao.getByAttributes(parentUsage.getName(), context);
+
+ for(CatalogOverrideUsageDefinitionModelDao usage : results) {
+ if (targetUsageDefinitionRecordIds != null && targetUsageDefinitionRecordIds.contains(usage.getRecordId())) {
+ return usage;
+ }
+ }
+
+ final CatalogOverrideUsageDefinitionModelDao inputUsageDef = new CatalogOverrideUsageDefinitionModelDao(parentUsage.getName(), parentUsage.getUsageType().name(), currency.name(), null, null, catalogEffectiveDate);
+ sqlDao.create(inputUsageDef, context);
+ final Long recordId = sqlDao.getLastInsertId();
+ final CatalogOverrideUsageDefinitionModelDao resultUsageDef = sqlDao.getByRecordId(recordId, context);
+
+ for (short i = 0; i < overrideTierDefinitionModelDaos.length; i++) {
+ if (overrideTierDefinitionModelDaos[i] != null) {
+ createCatalogOverrideUsageTierFromTransaction(i, overrideTierDefinitionModelDaos[i], resultUsageDef, inTransactionHandle, context);
+ }
+ }
+ return resultUsageDef;
+ }
+
+ private List<Long> getOverrideUsageDefinitionFromTransaction(final CatalogOverrideTierDefinitionModelDao[] overrideTierDefinitionModelDaos, final Handle inTransactionHandle, final InternalCallContext context) {
+ final CatalogOverrideUsageTierSqlDao sqlDao = inTransactionHandle.attach(CatalogOverrideUsageTierSqlDao.class);
+
+ final List<String> keys = new ArrayList<String>();
+ for (int i = 0; i < overrideTierDefinitionModelDaos.length; i++) {
+ final CatalogOverrideTierDefinitionModelDao cur = overrideTierDefinitionModelDaos[i];
+ if (cur != null) {
+ // Each key is the concatenation of the tier_number, tier_definition_record_id
+ keys.add(getConcatenatedKey(i, cur.getRecordId()).toString());
+ }
+ }
+ return keys.size() > 0 ? sqlDao.getTargetUsageDefinition(keys, keys.size(), context) : null;
+ }
+
+ private void createCatalogOverrideUsageTierFromTransaction(final short tierNum, final CatalogOverrideTierDefinitionModelDao tierDef, final CatalogOverrideUsageDefinitionModelDao usageDef, final Handle inTransactionHandle, final InternalCallContext context) {
+ final CatalogOverrideUsageTierSqlDao sqlDao = inTransactionHandle.attach(CatalogOverrideUsageTierSqlDao.class);
+ final CatalogOverrideUsageTierModelDao modelDao = new CatalogOverrideUsageTierModelDao(tierNum, tierDef.getRecordId(), usageDef.getRecordId());
+ sqlDao.create(modelDao, context);
+ }
+
+ private CatalogOverrideTierDefinitionModelDao getOrCreateOverrideTierDefinitionFromTransaction(final Tier parentTier, final TierPriceOverride tierPriceOverride,Currency currency, final DateTime catalogEffectiveDate, final Handle inTransactionHandle, final InternalCallContext context){
+
+ final List<TieredBlockPriceOverride> resolvedTierBlockOverrides = tierPriceOverride.getTieredBlockPriceOverrides();
+
+ final CatalogOverrideBlockDefinitionModelDao[] overrideBlockDefinitionModelDaos = new CatalogOverrideBlockDefinitionModelDao[resolvedTierBlockOverrides.size()];
+ for (int i = 0; i < resolvedTierBlockOverrides.size(); i++) {
+ final TieredBlockPriceOverride curOverride = resolvedTierBlockOverrides.get(i);
+ if (curOverride != null) {
+ final CatalogOverrideBlockDefinitionModelDao createdOverrideBlockDefinitionModelDao = getOrCreateOverriddenBlockDefinitionFromTransaction(curOverride,catalogEffectiveDate, currency.name(), inTransactionHandle, context);
+ overrideBlockDefinitionModelDaos[i] = createdOverrideBlockDefinitionModelDao;
+ }
+ }
+
+ final CatalogOverrideTierDefinitionSqlDao sqlDao = inTransactionHandle.attach(CatalogOverrideTierDefinitionSqlDao.class);
+ final Long targetTierDefinitionRecordId = getOverrideTierDefinitionFromTransaction(overrideBlockDefinitionModelDaos, inTransactionHandle, context);
+ if (targetTierDefinitionRecordId != null) {
+ return sqlDao.getByRecordId(targetTierDefinitionRecordId, context);
+ }
+
+ final CatalogOverrideTierDefinitionModelDao inputTierDef = new CatalogOverrideTierDefinitionModelDao(currency.name(), null, null, catalogEffectiveDate);
+ sqlDao.create(inputTierDef, context);
+ final Long recordId = sqlDao.getLastInsertId();
+ final CatalogOverrideTierDefinitionModelDao resultTierDef = sqlDao.getByRecordId(recordId, context);
+
+ for (short i = 0; i < overrideBlockDefinitionModelDaos.length; i++) {
+ if (overrideBlockDefinitionModelDaos[i] != null) {
+ createCatalogOverrideTierBlockFromTransaction(i, overrideBlockDefinitionModelDaos[i], resultTierDef, inTransactionHandle, context);
+ }
+ }
+ return resultTierDef;
+ }
+
+ private void createCatalogOverrideTierBlockFromTransaction(final short blockNum, final CatalogOverrideBlockDefinitionModelDao blockDef, final CatalogOverrideTierDefinitionModelDao tierDef, final Handle inTransactionHandle, final InternalCallContext context) {
+ final CatalogOverrideTierBlockSqlDao sqlDao = inTransactionHandle.attach(CatalogOverrideTierBlockSqlDao.class);
+ final CatalogOverrideTierBlockModelDao modelDao = new CatalogOverrideTierBlockModelDao(blockNum, blockDef.getRecordId(), tierDef.getRecordId());
+ sqlDao.create(modelDao, context);
+ }
+
+ private Long getOverrideTierDefinitionFromTransaction(final CatalogOverrideBlockDefinitionModelDao[] overrideBlockDefinitionModelDaos, final Handle inTransactionHandle, final InternalCallContext context) {
+ final CatalogOverrideTierBlockSqlDao sqlDao = inTransactionHandle.attach(CatalogOverrideTierBlockSqlDao.class);
+
+ final List<String> keys = new ArrayList<String>();
+ for (int i = 0; i < overrideBlockDefinitionModelDaos.length; i++) {
+ final CatalogOverrideBlockDefinitionModelDao cur = overrideBlockDefinitionModelDaos[i];
+ if (cur != null) {
+ // Each key is the concatenation of the block_number, block_definition_record_id
+ keys.add(getConcatenatedKey(i, cur.getRecordId()).toString());
+ }
+ }
+ return keys.size() > 0 ? sqlDao.getTargetTierDefinition(keys, keys.size(), context) : null;
+ }
+
+ private CatalogOverrideBlockDefinitionModelDao getOrCreateOverriddenBlockDefinitionFromTransaction(TieredBlockPriceOverride tieredBlockPriceOverride,final DateTime catalogEffectiveDate, String currency, final Handle inTransactionHandle, final InternalCallContext context)
+ {
+ final CatalogOverrideBlockDefinitionSqlDao sqlDao = inTransactionHandle.attach(CatalogOverrideBlockDefinitionSqlDao.class);
+
+ CatalogOverrideBlockDefinitionModelDao result = sqlDao.getByAttributes(tieredBlockPriceOverride.getUnitName(),
+ currency, tieredBlockPriceOverride.getPrice(), tieredBlockPriceOverride.getMax(),
+ tieredBlockPriceOverride.getSize(),context);
if (result == null) {
- final CatalogOverridePhaseDefinitionModelDao phaseDef = new CatalogOverridePhaseDefinitionModelDao(parentPhaseName, override.getCurrency().name(), override.getFixedPrice(), override.getRecurringPrice(),
- catalogEffectiveDate);
- sqlDao.create(phaseDef, context);
+ final CatalogOverrideBlockDefinitionModelDao blockDef = new CatalogOverrideBlockDefinitionModelDao(tieredBlockPriceOverride.getUnitName(),currency, tieredBlockPriceOverride.getPrice(),
+ tieredBlockPriceOverride.getSize(),tieredBlockPriceOverride.getMax(), catalogEffectiveDate);
+ sqlDao.create(blockDef, context);
final Long recordId = sqlDao.getLastInsertId();
result = sqlDao.getByRecordId(recordId, context);
}
return result;
}
+
+ @Override
+ public List<CatalogOverridePhaseDefinitionModelDao> getOverriddenPlanPhases(final Long planDefRecordId, final InternalTenantContext context) {
+ return dbi.inTransaction(new TransactionCallback<List<CatalogOverridePhaseDefinitionModelDao>>() {
+ @Override
+ public List<CatalogOverridePhaseDefinitionModelDao> inTransaction(final Handle handle, final TransactionStatus status) throws Exception {
+ final CatalogOverridePhaseDefinitionSqlDao sqlDao = handle.attach(CatalogOverridePhaseDefinitionSqlDao.class);
+ return sqlDao.getOverriddenPlanPhases(planDefRecordId, context);
+ }
+ });
+ }
+
+ @Override
+ public List<CatalogOverrideUsageDefinitionModelDao> getOverriddenPhaseUsages(final Long phaseDefRecordId, final InternalTenantContext context) {
+ return dbi.inTransaction(new TransactionCallback<List<CatalogOverrideUsageDefinitionModelDao>>() {
+ @Override
+ public List<CatalogOverrideUsageDefinitionModelDao> inTransaction(final Handle handle, final TransactionStatus status) throws Exception {
+ final CatalogOverrideUsageDefinitionSqlDao sqlDao = handle.attach(CatalogOverrideUsageDefinitionSqlDao.class);
+ return sqlDao.getOverriddenPhaseUsages(phaseDefRecordId, context);
+ }
+ });
+ }
+
+ @Override
+ public List<CatalogOverrideTierDefinitionModelDao> getOverriddenUsageTiers(final Long usageDefRecordId, final InternalTenantContext context) {
+ return dbi.inTransaction(new TransactionCallback<List<CatalogOverrideTierDefinitionModelDao>>() {
+ @Override
+ public List<CatalogOverrideTierDefinitionModelDao> inTransaction(final Handle handle, final TransactionStatus status) throws Exception {
+ final CatalogOverrideTierDefinitionSqlDao sqlDao = handle.attach(CatalogOverrideTierDefinitionSqlDao.class);
+ return sqlDao.getOverriddenUsageTiers(usageDefRecordId, context);
+ }
+ });
+ }
+
+ @Override
+ public List<CatalogOverrideBlockDefinitionModelDao> getOverriddenTierBlocks(final Long tierDefRecordId, final InternalTenantContext context) {
+ return dbi.inTransaction(new TransactionCallback<List<CatalogOverrideBlockDefinitionModelDao>>() {
+ @Override
+ public List<CatalogOverrideBlockDefinitionModelDao> inTransaction(final Handle handle, final TransactionStatus status) throws Exception {
+ final CatalogOverrideBlockDefinitionSqlDao sqlDao = handle.attach(CatalogOverrideBlockDefinitionSqlDao.class);
+ return sqlDao.getOverriddenTierBlocks(tierDefRecordId, context);
+ }
+ });
+ }
+
+
+ private boolean isUsageOverrideListHasOnlyNull(List<UsagePriceOverride> usagePriceOverrides) {
+ for (UsagePriceOverride override : usagePriceOverrides) {
+ if (override != null) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private StringBuffer getConcatenatedKey(int index, Long recordId) {
+ final StringBuffer key = new StringBuffer();
+ key.append(index);
+ key.append(",");
+ key.append(recordId);
+ return key;
+ }
}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/PhaseUsageKeysCollectionBinder.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/PhaseUsageKeysCollectionBinder.java
new file mode 100644
index 0000000..8460ec8
--- /dev/null
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/PhaseUsageKeysCollectionBinder.java
@@ -0,0 +1,56 @@
+/*
+ * 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.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Collection;
+
+import org.killbill.billing.catalog.dao.PhaseUsageKeysCollectionBinder.PhaseUsageKeysCollectionBinderFactory;
+import org.skife.jdbi.v2.SQLStatement;
+import org.skife.jdbi.v2.sqlobject.Binder;
+import org.skife.jdbi.v2.sqlobject.BinderFactory;
+import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
+
+@BindingAnnotation(PhaseUsageKeysCollectionBinderFactory.class)
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface PhaseUsageKeysCollectionBinder {
+
+ public static class PhaseUsageKeysCollectionBinderFactory implements BinderFactory {
+
+ @Override
+ public Binder build(Annotation annotation) {
+ return new Binder<PhaseUsageKeysCollectionBinder, Collection<String>>() {
+
+ @Override
+ public void bind(SQLStatement<?> query, PhaseUsageKeysCollectionBinder bind, Collection<String> keys) {
+ query.define("keys", keys);
+ int idx = 0;
+ for (String state : keys) {
+ query.bind("key_" + idx, state);
+ idx++;
+ }
+ }
+ };
+ }
+ }
+}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/TierBlockKeysCollectionBinder.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/TierBlockKeysCollectionBinder.java
new file mode 100644
index 0000000..e84ab84
--- /dev/null
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/TierBlockKeysCollectionBinder.java
@@ -0,0 +1,56 @@
+/*
+ * 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.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Collection;
+
+import org.killbill.billing.catalog.dao.TierBlockKeysCollectionBinder.TierBlockKeysCollectionBinderFactory;
+import org.skife.jdbi.v2.SQLStatement;
+import org.skife.jdbi.v2.sqlobject.Binder;
+import org.skife.jdbi.v2.sqlobject.BinderFactory;
+import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
+
+@BindingAnnotation(TierBlockKeysCollectionBinderFactory.class)
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface TierBlockKeysCollectionBinder {
+
+ public static class TierBlockKeysCollectionBinderFactory implements BinderFactory {
+
+ @Override
+ public Binder build(Annotation annotation) {
+ return new Binder<TierBlockKeysCollectionBinder, Collection<String>>() {
+
+ @Override
+ public void bind(SQLStatement<?> query, TierBlockKeysCollectionBinder bind, Collection<String> keys) {
+ query.define("keys", keys);
+ int idx = 0;
+ for (String state : keys) {
+ query.bind("key_" + idx, state);
+ idx++;
+ }
+ }
+ };
+ }
+ }
+}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/UsageTierKeysCollectionBinder.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/UsageTierKeysCollectionBinder.java
new file mode 100644
index 0000000..2a5edfb
--- /dev/null
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/UsageTierKeysCollectionBinder.java
@@ -0,0 +1,57 @@
+/*
+ * 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.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Collection;
+
+import org.killbill.billing.catalog.dao.UsageTierKeysCollectionBinder.UsageTierKeysCollectionBinderFactory;
+import org.skife.jdbi.v2.SQLStatement;
+import org.skife.jdbi.v2.sqlobject.Binder;
+import org.skife.jdbi.v2.sqlobject.BinderFactory;
+import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
+
+@BindingAnnotation(UsageTierKeysCollectionBinderFactory.class)
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface UsageTierKeysCollectionBinder {
+
+ public static class UsageTierKeysCollectionBinderFactory implements BinderFactory {
+
+ @Override
+ public Binder build(Annotation annotation) {
+ return new Binder<UsageTierKeysCollectionBinder, Collection<String>>() {
+
+ @Override
+ public void bind(SQLStatement<?> query, UsageTierKeysCollectionBinder bind, Collection<String> keys) {
+ query.define("keys", keys);
+
+ int idx = 0;
+ for (String state : keys) {
+ query.bind("key_" + idx, state);
+ idx++;
+ }
+ }
+ };
+ }
+ }
+}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultBlock.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultBlock.java
index 784e577..46bee2d 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultBlock.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultBlock.java
@@ -17,6 +17,8 @@
package org.killbill.billing.catalog;
+import java.math.BigDecimal;
+
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
@@ -27,6 +29,7 @@ import org.killbill.billing.ErrorCode;
import org.killbill.billing.catalog.api.Block;
import org.killbill.billing.catalog.api.BlockType;
import org.killbill.billing.catalog.api.CatalogApiException;
+import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.catalog.api.InternationalPrice;
import org.killbill.billing.catalog.api.PlanPhase;
import org.killbill.billing.catalog.api.Unit;
@@ -93,6 +96,15 @@ public class DefaultBlock extends ValidatingConfig<StandaloneCatalog> implements
return errors;
}
+ public DefaultBlock() {
+ }
+
+ public DefaultBlock(final DefaultUnit unit, final Double size, final DefaultInternationalPrice prices, final BigDecimal overriddenPrice, Currency currency) {
+ this.unit = unit;
+ this.size = size;
+ this.prices = prices != null ? new DefaultInternationalPrice(prices, overriddenPrice, currency) : null;
+ }
+
public DefaultBlock setType(final BlockType type) {
this.type = type;
return this;
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultBlockPriceOverride.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultBlockPriceOverride.java
new file mode 100644
index 0000000..e33faf2
--- /dev/null
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultBlockPriceOverride.java
@@ -0,0 +1,52 @@
+/*
+ * 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;
+
+import java.math.BigDecimal;
+
+import org.killbill.billing.catalog.api.BlockPriceOverride;
+
+public class DefaultBlockPriceOverride implements BlockPriceOverride {
+
+ private String unitName;
+
+ private Double size;
+
+ private BigDecimal price;
+
+ @Override
+ public String getUnitName() {
+ return unitName;
+ }
+
+ @Override
+ public Double getSize() {
+ return size;
+ }
+
+ @Override
+ public BigDecimal getPrice() {
+ return price;
+ }
+
+ public DefaultBlockPriceOverride( String unitName, Double size, BigDecimal price) {
+ this.unitName = unitName;
+ this.size = size;
+ this.price = price;
+ }
+}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultInternationalPrice.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultInternationalPrice.java
index 10040ba..1514278 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultInternationalPrice.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultInternationalPrice.java
@@ -16,13 +16,14 @@
package org.killbill.billing.catalog;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
import java.math.BigDecimal;
import java.net.URI;
import java.util.Arrays;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+
import org.killbill.billing.ErrorCode;
import org.killbill.billing.catalog.api.CatalogApiException;
import org.killbill.billing.catalog.api.Currency;
@@ -65,6 +66,18 @@ public class DefaultInternationalPrice extends ValidatingConfig<StandaloneCatalo
}
}
+ public DefaultInternationalPrice(final DefaultInternationalPrice in, final BigDecimal overriddenPrice, final Currency currency) {
+ this.prices = in.getPrices() != null ? new DefaultPrice[in.getPrices().length] : null;
+ for (int i = 0; i < in.getPrices().length; i++) {
+ final DefaultPrice curPrice = (DefaultPrice) in.getPrices()[i];
+ if (curPrice.getCurrency().equals(currency)){
+ prices[i] = new DefaultPrice(overriddenPrice, currency);
+ } else {
+ prices[i] = curPrice;
+ }
+ }
+ }
+
/* (non-Javadoc)
* @see org.killbill.billing.catalog.IInternationalPrice#getPrice(org.killbill.billing.catalog.api.Currency)
*/
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlanPhase.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlanPhase.java
index bf451af..6c6c47f 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlanPhase.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlanPhase.java
@@ -38,10 +38,14 @@ import org.killbill.billing.catalog.api.PlanPhase;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.Recurring;
import org.killbill.billing.catalog.api.Usage;
+import org.killbill.billing.catalog.api.UsagePriceOverride;
import org.killbill.xmlloader.ValidatingConfig;
import org.killbill.xmlloader.ValidationError;
import org.killbill.xmlloader.ValidationErrors;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+
@XmlAccessorType(XmlAccessType.NONE)
public class DefaultPlanPhase extends ValidatingConfig<StandaloneCatalog> implements PlanPhase {
@@ -75,7 +79,19 @@ public class DefaultPlanPhase extends ValidatingConfig<StandaloneCatalog> implem
this.recurring = override != null && override.getRecurringPrice() != null ? new DefaultRecurring((DefaultRecurring) in.getRecurring(), override) : (DefaultRecurring) in.getRecurring();
this.usages = new DefaultUsage[in.getUsages().length];
for (int i = 0; i < in.getUsages().length; i++) {
- usages[i] = (DefaultUsage) in.getUsages()[i];
+ final Usage curUsage = in.getUsages()[i];
+ if(override != null && override.getUsagePriceOverrides()!= null) {
+ final UsagePriceOverride usagePriceOverride = Iterables.tryFind(override.getUsagePriceOverrides(), new Predicate<UsagePriceOverride>() {
+ @Override
+ public boolean apply(final UsagePriceOverride input) {
+ return input !=null && input.getName().equals(curUsage.getName());
+ }
+ }).orNull();
+ usages[i] = (usagePriceOverride !=null) ? new DefaultUsage(in.getUsages()[i], usagePriceOverride, override.getCurrency()) : (DefaultUsage)curUsage;
+ }
+ else {
+ usages[i] = (DefaultUsage)curUsage;
+ }
}
this.plan = parentPlan;
}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlanPhasePriceOverride.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlanPhasePriceOverride.java
index 2a1ee1c..aca3021 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlanPhasePriceOverride.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlanPhasePriceOverride.java
@@ -18,10 +18,12 @@
package org.killbill.billing.catalog;
import java.math.BigDecimal;
+import java.util.List;
import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
+import org.killbill.billing.catalog.api.UsagePriceOverride;
public class DefaultPlanPhasePriceOverride implements PlanPhasePriceOverride {
@@ -30,21 +32,24 @@ public class DefaultPlanPhasePriceOverride implements PlanPhasePriceOverride {
private final Currency currency;
private final BigDecimal fixedPrice;
private final BigDecimal recurringPrice;
+ private final List<UsagePriceOverride> usagePriceOverrides;
- public DefaultPlanPhasePriceOverride(final PlanPhaseSpecifier planPhaseSpecifier, final Currency currency, final BigDecimal fixedPrice, final BigDecimal recurringPrice) {
+ public DefaultPlanPhasePriceOverride(final PlanPhaseSpecifier planPhaseSpecifier, final Currency currency, final BigDecimal fixedPrice, final BigDecimal recurringPrice, final List<UsagePriceOverride> usagePriceOverrides) {
this.phaseName = null;
this.planPhaseSpecifier = planPhaseSpecifier;
this.currency = currency;
this.fixedPrice = fixedPrice;
this.recurringPrice = recurringPrice;
+ this.usagePriceOverrides = usagePriceOverrides;
}
- public DefaultPlanPhasePriceOverride(final String phaseName, final Currency currency, final BigDecimal fixedPrice, final BigDecimal recurringPrice) {
+ public DefaultPlanPhasePriceOverride(final String phaseName, final Currency currency, final BigDecimal fixedPrice, final BigDecimal recurringPrice, List<UsagePriceOverride> usagePriceOverrides) {
this.phaseName = phaseName;
this.planPhaseSpecifier = null;
this.currency = currency;
this.fixedPrice = fixedPrice;
this.recurringPrice = recurringPrice;
+ this.usagePriceOverrides = usagePriceOverrides;
}
@Override
@@ -71,4 +76,9 @@ public class DefaultPlanPhasePriceOverride implements PlanPhasePriceOverride {
public BigDecimal getRecurringPrice() {
return recurringPrice;
}
+
+ @Override
+ public List<UsagePriceOverride> getUsagePriceOverrides() {
+ return usagePriceOverrides;
+ }
}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultTier.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultTier.java
index 1baf1a3..b5e6c49 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultTier.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultTier.java
@@ -25,14 +25,23 @@ import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import org.killbill.billing.catalog.api.BillingMode;
+import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.catalog.api.InternationalPrice;
import org.killbill.billing.catalog.api.PlanPhase;
import org.killbill.billing.catalog.api.Tier;
+import org.killbill.billing.catalog.api.TierPriceOverride;
+import org.killbill.billing.catalog.api.TieredBlock;
+import org.killbill.billing.catalog.api.TieredBlockPriceOverride;
import org.killbill.billing.catalog.api.UsageType;
import org.killbill.xmlloader.ValidatingConfig;
import org.killbill.xmlloader.ValidationError;
import org.killbill.xmlloader.ValidationErrors;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+
+
+
@XmlAccessorType(XmlAccessType.NONE)
public class DefaultTier extends ValidatingConfig<StandaloneCatalog> implements Tier {
@@ -62,6 +71,31 @@ public class DefaultTier extends ValidatingConfig<StandaloneCatalog> implements
blocks = new DefaultTieredBlock[0];
}
+ public DefaultTier(Tier in, TierPriceOverride override, Currency currency) {
+ this.limits = (DefaultLimit[])in.getLimits();
+ this.blocks = new DefaultTieredBlock[in.getTieredBlocks().length];
+
+ for (int i = 0; i < in.getTieredBlocks().length; i++) {
+ if(override != null && override.getTieredBlockPriceOverrides() != null) {
+ final TieredBlock curTieredBlock = in.getTieredBlocks()[i];
+ final TieredBlockPriceOverride overriddenTierBlock = Iterables.tryFind(override.getTieredBlockPriceOverrides(), new Predicate<TieredBlockPriceOverride>() {
+ @Override
+ public boolean apply(final TieredBlockPriceOverride input) {
+ return (input != null && input.getUnitName().equals(curTieredBlock.getUnit().getName()) &&
+ Double.compare(input.getSize(), curTieredBlock.getSize()) == 0 &&
+ Double.compare(input.getMax(), curTieredBlock.getMax()) == 0);
+ }
+
+ }).orNull();
+ blocks[i] = (overriddenTierBlock != null) ? new DefaultTieredBlock(in.getTieredBlocks()[i], overriddenTierBlock, currency) :
+ (DefaultTieredBlock) in.getTieredBlocks()[i];
+ }
+ else {
+ blocks[i] = (DefaultTieredBlock) in.getTieredBlocks()[i];
+ }
+ }
+ }
+
@Override
public DefaultLimit[] getLimits() {
return limits;
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultTieredBlock.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultTieredBlock.java
index ae39968..aa661ab 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultTieredBlock.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultTieredBlock.java
@@ -21,7 +21,9 @@ import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import org.killbill.billing.catalog.api.BlockType;
+import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.catalog.api.TieredBlock;
+import org.killbill.billing.catalog.api.TieredBlockPriceOverride;
@XmlAccessorType(XmlAccessType.NONE)
public class DefaultTieredBlock extends DefaultBlock implements TieredBlock {
@@ -39,6 +41,14 @@ public class DefaultTieredBlock extends DefaultBlock implements TieredBlock {
return this;
}
+ public DefaultTieredBlock() {
+ }
+
+ public DefaultTieredBlock(TieredBlock in, TieredBlockPriceOverride override, Currency currency) {
+ super((DefaultUnit)in.getUnit(), in.getSize(),(DefaultInternationalPrice)in.getPrice(), override.getPrice(),currency);
+ this.max = in.getMax();
+ }
+
@Override
public BlockType getType() {
return BlockType.TIERED;
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultTieredBlockPriceOverride.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultTieredBlockPriceOverride.java
new file mode 100644
index 0000000..2f58425
--- /dev/null
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultTieredBlockPriceOverride.java
@@ -0,0 +1,38 @@
+/*
+ * 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;
+
+import java.math.BigDecimal;
+
+import org.killbill.billing.catalog.api.TieredBlockPriceOverride;
+
+public class DefaultTieredBlockPriceOverride extends DefaultBlockPriceOverride implements TieredBlockPriceOverride {
+
+ private Double max;
+
+ @Override
+ public Double getMax() {
+ return max;
+ }
+
+ public DefaultTieredBlockPriceOverride(String unitName, Double size, BigDecimal price, Double max) {
+ super(unitName, size, price);
+ this.max = max;
+ }
+
+}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultTierPriceOverride.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultTierPriceOverride.java
new file mode 100644
index 0000000..6735918
--- /dev/null
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultTierPriceOverride.java
@@ -0,0 +1,37 @@
+/*
+ * 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;
+
+import org.killbill.billing.catalog.api.TierPriceOverride;
+import org.killbill.billing.catalog.api.TieredBlockPriceOverride;
+
+import java.util.List;
+
+public class DefaultTierPriceOverride implements TierPriceOverride {
+
+ List<TieredBlockPriceOverride> tieredBlockPriceOverrides;
+
+ public DefaultTierPriceOverride(List<TieredBlockPriceOverride> tieredBlockPriceOverrides) {
+ this.tieredBlockPriceOverrides = tieredBlockPriceOverrides;
+ }
+
+ public List<TieredBlockPriceOverride> getTieredBlockPriceOverrides() {
+ return tieredBlockPriceOverrides;
+ }
+
+}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultUsage.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultUsage.java
index 1c6daa8..570b18e 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultUsage.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultUsage.java
@@ -19,6 +19,7 @@ package org.killbill.billing.catalog;
import java.net.URI;
import java.util.Arrays;
+import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@@ -30,16 +31,25 @@ import javax.xml.bind.annotation.XmlID;
import org.killbill.billing.catalog.api.BillingMode;
import org.killbill.billing.catalog.api.BillingPeriod;
import org.killbill.billing.catalog.api.Block;
+import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.catalog.api.InternationalPrice;
import org.killbill.billing.catalog.api.Limit;
import org.killbill.billing.catalog.api.PlanPhase;
import org.killbill.billing.catalog.api.Tier;
+import org.killbill.billing.catalog.api.TierPriceOverride;
+import org.killbill.billing.catalog.api.TieredBlock;
+import org.killbill.billing.catalog.api.TieredBlockPriceOverride;
import org.killbill.billing.catalog.api.Usage;
+import org.killbill.billing.catalog.api.UsagePriceOverride;
import org.killbill.billing.catalog.api.UsageType;
import org.killbill.xmlloader.ValidatingConfig;
import org.killbill.xmlloader.ValidationError;
import org.killbill.xmlloader.ValidationErrors;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+
+
@XmlAccessorType(XmlAccessType.NONE)
public class DefaultUsage extends ValidatingConfig<StandaloneCatalog> implements Usage {
@@ -88,6 +98,49 @@ public class DefaultUsage extends ValidatingConfig<StandaloneCatalog> implements
tiers = new DefaultTier[0];
}
+ public DefaultUsage(final Usage in, UsagePriceOverride override, Currency currency) {
+ this.name = in.getName();
+ this.usageType = in.getUsageType();
+ this.billingPeriod = in.getBillingPeriod();
+ this.billingMode = in.getBillingMode();
+ this.limits = (DefaultLimit[]) in.getLimits();
+ this.blocks = (DefaultBlock[]) in.getBlocks();
+ this.tiers = new DefaultTier[in.getTiers().length];
+
+ for (int i = 0; i < in.getTiers().length; i++) {
+ if(override != null && override.getTierPriceOverrides()!=null) {
+ final TieredBlock[] curTieredBlocks = in.getTiers()[i].getTieredBlocks();
+
+ final TierPriceOverride overriddenTier = Iterables.tryFind(override.getTierPriceOverrides(), new Predicate<TierPriceOverride>() {
+ @Override
+ public boolean apply(final TierPriceOverride input) {
+
+ if(input !=null) {
+ final List<TieredBlockPriceOverride> blockPriceOverrides = input.getTieredBlockPriceOverrides();
+ for (TieredBlockPriceOverride blockDef : blockPriceOverrides) {
+ String unitName = blockDef.getUnitName();
+ Double max = blockDef.getMax();
+ Double size = blockDef.getSize();
+ for (TieredBlock curTieredBlock : curTieredBlocks) {
+ if (unitName.equals(curTieredBlock.getUnit().getName()) &&
+ Double.compare(size, curTieredBlock.getSize()) == 0 &&
+ Double.compare(max, curTieredBlock.getMax()) == 0) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+ }).orNull();
+ tiers[i] = (overriddenTier != null) ? new DefaultTier(in.getTiers()[i], overriddenTier, currency) : (DefaultTier)in.getTiers()[i] ;
+ }
+ else {
+ tiers[i] = (DefaultTier) in.getTiers()[i];
+ }
+ }
+ }
+
@Override
public String getName() {
return name;
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultUsagePriceOverride.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultUsagePriceOverride.java
new file mode 100644
index 0000000..d427c24
--- /dev/null
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultUsagePriceOverride.java
@@ -0,0 +1,54 @@
+/*
+ * 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;
+
+import java.util.List;
+
+import org.killbill.billing.catalog.api.TierPriceOverride;
+import org.killbill.billing.catalog.api.UsagePriceOverride;
+import org.killbill.billing.catalog.api.UsageType;
+
+public class DefaultUsagePriceOverride implements UsagePriceOverride {
+
+ String name;
+ UsageType usageType;
+ List<TierPriceOverride> tierPriceOverrides;
+
+ public DefaultUsagePriceOverride(String name, UsageType usageType, List<TierPriceOverride> tierPriceOverrides) {
+ this.name = name;
+ this.usageType = usageType;
+ this.tierPriceOverrides = tierPriceOverrides;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public UsageType getUsageType() {
+ return usageType;
+ }
+
+ @Override
+ public List<TierPriceOverride> getTierPriceOverrides() {
+ return tierPriceOverrides;
+ }
+
+
+}
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 86b8739..2e8b0ee 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
@@ -18,6 +18,7 @@
package org.killbill.billing.catalog.override;
import java.util.List;
+import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Pattern;
@@ -30,12 +31,21 @@ import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.DefaultPlan;
import org.killbill.billing.catalog.DefaultPlanPhase;
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.api.CatalogApiException;
import org.killbill.billing.catalog.api.Plan;
import org.killbill.billing.catalog.api.PlanPhase;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.StaticCatalog;
+import org.killbill.billing.catalog.api.Tier;
+import org.killbill.billing.catalog.api.TierPriceOverride;
+import org.killbill.billing.catalog.api.TieredBlock;
+import org.killbill.billing.catalog.api.TieredBlockPriceOverride;
+import org.killbill.billing.catalog.api.Usage;
+import org.killbill.billing.catalog.api.UsagePriceOverride;
import org.killbill.billing.catalog.caching.OverriddenPlanCache;
import org.killbill.billing.catalog.dao.CatalogOverrideDao;
import org.killbill.billing.catalog.dao.CatalogOverridePlanDefinitionModelDao;
@@ -80,9 +90,15 @@ public class DefaultPriceOverride implements PriceOverride {
return false;
}
}).orNull();
- resolvedOverride[index++] = curOverride != null ?
- new DefaultPlanPhasePriceOverride(curPhase.getName(), curOverride.getCurrency(), curOverride.getFixedPrice(), curOverride.getRecurringPrice()) :
- null;
+
+ if(curOverride != null) {
+ List<UsagePriceOverride> resolvedUsageOverrides = getResolvedUsageOverrides(curPhase.getUsages(), curOverride.getUsagePriceOverrides());
+ resolvedOverride[index++] = new DefaultPlanPhasePriceOverride(curPhase.getName(), curOverride.getCurrency(), curOverride.getFixedPrice(),
+ curOverride.getRecurringPrice(), resolvedUsageOverrides);
+ }
+ else {
+ resolvedOverride[index++] = null;
+ }
}
for (int i = 0; i < resolvedOverride.length; i++) {
@@ -104,11 +120,12 @@ public class DefaultPriceOverride implements PriceOverride {
final String planName;
if (context != null) {
- final CatalogOverridePlanDefinitionModelDao overriddenPlan = overrideDao.getOrCreateOverridePlanDefinition(parentPlan.getName(), catalogEffectiveDate, resolvedOverride, context);
+ final CatalogOverridePlanDefinitionModelDao overriddenPlan = overrideDao.getOrCreateOverridePlanDefinition(parentPlan, catalogEffectiveDate, resolvedOverride, context);
planName = new StringBuffer(parentPlan.getName()).append("-").append(overriddenPlan.getRecordId()).toString();
} else {
planName = new StringBuffer(parentPlan.getName()).append("-dryrun-").append(DRY_RUN_PLAN_IDX.incrementAndGet()).toString();
}
+
final DefaultPlan result = new DefaultPlan(planName, (DefaultPlan) parentPlan, resolvedOverride);
if (context == null) {
overriddenPlanCache.addDryRunPlan(planName, result);
@@ -116,6 +133,94 @@ public class DefaultPriceOverride implements PriceOverride {
return result;
}
+ public List<UsagePriceOverride> getResolvedUsageOverrides(Usage[] usages, List<UsagePriceOverride> usagePriceOverrides) throws CatalogApiException{
+ List<UsagePriceOverride> resolvedUsageOverrides = new ArrayList<UsagePriceOverride>();
+
+ for (final Usage curUsage : usages) {
+ final UsagePriceOverride curOverride = Iterables.tryFind(usagePriceOverrides, new Predicate<UsagePriceOverride>() {
+ @Override
+ public boolean apply(final UsagePriceOverride input) {
+ return input.getName() != null && input.getName().equals(curUsage.getName());
+ }
+ }).orNull();
+ if(curOverride != null) {
+ List<TierPriceOverride> tierPriceOverrides = getResolvedTierOverrides(curUsage.getTiers(), curOverride.getTierPriceOverrides());
+ resolvedUsageOverrides.add(new DefaultUsagePriceOverride(curUsage.getName(), curUsage.getUsageType(),tierPriceOverrides));
+ } else {
+ resolvedUsageOverrides.add(null);
+ }
+ }
+
+ return resolvedUsageOverrides;
+ }
+
+ public List<TierPriceOverride> getResolvedTierOverrides(Tier[] tiers, List<TierPriceOverride> tierPriceOverrides) throws CatalogApiException{
+ List<TierPriceOverride> resolvedTierOverrides = new ArrayList<TierPriceOverride>();
+
+ for (final Tier curTier : tiers) {
+ final TierPriceOverride curOverride = Iterables.tryFind(tierPriceOverrides, new Predicate<TierPriceOverride>() {
+ @Override
+ public boolean apply(final TierPriceOverride input) {
+
+ if (input.getTieredBlockPriceOverrides() != null) {
+ for (TieredBlockPriceOverride blockPriceOverride : input.getTieredBlockPriceOverrides()) {
+ String unitName = blockPriceOverride.getUnitName();
+ Double max = blockPriceOverride.getMax();
+ Double size = blockPriceOverride.getSize();
+
+ for (int i = 0; i < curTier.getTieredBlocks().length; i++) {
+ TieredBlock curTieredBlock = curTier.getTieredBlocks()[i];
+ if (unitName.equals(curTieredBlock.getUnit().getName()) &&
+ Double.compare(size, curTieredBlock.getSize()) == 0 &&
+ Double.compare(max, curTieredBlock.getMax()) == 0) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+ }).orNull();
+
+ if(curOverride != null) {
+ List<TieredBlockPriceOverride> tieredBlockPriceOverrides = getResolvedTieredBlockPriceOverrides(curTier.getTieredBlocks(),
+ curOverride.getTieredBlockPriceOverrides());
+ resolvedTierOverrides.add(new DefaultTierPriceOverride(tieredBlockPriceOverrides));
+ }
+ else {
+ resolvedTierOverrides.add(null);
+ }
+ }
+
+ return resolvedTierOverrides;
+ }
+
+ public List<TieredBlockPriceOverride> getResolvedTieredBlockPriceOverrides(TieredBlock[] tieredBlocks, List<TieredBlockPriceOverride> tieredBlockPriceOverrides) throws CatalogApiException {
+ List<TieredBlockPriceOverride> resolvedTieredBlockPriceOverrides = new ArrayList<TieredBlockPriceOverride>();
+
+ for (final TieredBlock curTieredBlock : tieredBlocks) {
+
+ final TieredBlockPriceOverride curOverride = Iterables.tryFind(tieredBlockPriceOverrides, new Predicate<TieredBlockPriceOverride>() {
+ @Override
+ public boolean apply(final TieredBlockPriceOverride input) {
+ return input.getUnitName() != null && input.getSize() != null && input.getMax() != null &&
+ (input.getUnitName().equals(curTieredBlock.getUnit().getName()) &&
+ Double.compare(input.getSize(), curTieredBlock.getSize()) == 0 &&
+ Double.compare(input.getMax(), curTieredBlock.getMax()) == 0);
+ }
+ }).orNull();
+
+ if(curOverride != null) {
+ resolvedTieredBlockPriceOverrides.add(new DefaultTieredBlockPriceOverride(curTieredBlock.getUnit().getName(), curOverride.getSize(), curOverride.getPrice(), curOverride.getMax())) ;
+ }
+ else {
+ resolvedTieredBlockPriceOverrides.add(null);
+ }
+ }
+ return resolvedTieredBlockPriceOverrides;
+ }
+
+
@Override
public DefaultPlan getOverriddenPlan(final String planName, final StaticCatalog catalog, final InternalTenantContext context) throws CatalogApiException {
return overriddenPlanCache.getOverriddenPlan(planName, catalog, context);
diff --git a/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideBlockDefinitionSqlDao.sql.stg b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideBlockDefinitionSqlDao.sql.stg
new file mode 100644
index 0000000..217209a
--- /dev/null
+++ b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideBlockDefinitionSqlDao.sql.stg
@@ -0,0 +1,81 @@
+group CatalogOverrideBlockDefinitionSqlDao;
+
+tableName() ::= "catalog_override_block_definition"
+
+tableFields(prefix) ::= <<
+ <prefix>parent_unit_name
+, <prefix>size
+, <prefix>max
+, <prefix>currency
+, <prefix>price
+, <prefix>effective_date
+, <prefix>created_date
+, <prefix>created_by
+, <prefix>tenant_record_id
+>>
+
+allTableFields(prefix) ::= <<
+ <prefix>record_id
+, <tableFields(prefix)>
+>>
+
+tableValues() ::= <<
+ :parentUnitName
+, :size
+, :max
+, :currency
+, :price
+, :effectiveDate
+, :createdDate
+, :createdBy
+, :tenantRecordId
+>>
+
+allTableValues() ::= <<
+ :recordId
+, <tableValues()>
+>>
+
+create() ::= <<
+insert into <tableName()> (
+<tableFields()>
+)
+values (
+<tableValues()>
+)
+;
+>>
+
+getByRecordId() ::= <<
+select <allTableFields()>
+from <tableName()>
+where record_id = :recordId
+and tenant_record_id = :tenantRecordId
+;
+>>
+
+getByAttributes() ::= <<
+select <allTableFields()>
+from <tableName()>
+where parent_unit_name = :parentUnitName
+and currency = :currency
+and price = :price
+and max = :max
+and size = :size;
+>>
+
+getOverriddenTierBlocks() ::= <<
+select <allTableFields("bdef.")>
+from <tableName()> bdef
+join catalog_override_tier_block tb
+on bdef.record_id = tb.block_def_record_id
+where
+tb.target_tier_def_record_id = :targetTierDefRecordId
+and tb.tenant_record_id = :tenantRecordId
+;
+>>
+
+getLastInsertId() ::= <<
+select LAST_INSERT_ID();
+>>
+
diff --git a/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePhaseUsageSqlDao.sql.stg b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePhaseUsageSqlDao.sql.stg
new file mode 100644
index 0000000..127e89b
--- /dev/null
+++ b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePhaseUsageSqlDao.sql.stg
@@ -0,0 +1,73 @@
+group CatalogOverridePhaseUsageSqlDao;
+
+tableName() ::= "catalog_override_phase_usage"
+
+tableFields(prefix) ::= <<
+ <prefix>usage_number
+, <prefix>usage_def_record_id
+, <prefix>target_phase_def_record_id
+, <prefix>created_date
+, <prefix>created_by
+, <prefix>tenant_record_id
+>>
+
+allTableFields(prefix) ::= <<
+ <prefix>record_id
+, <tableFields(prefix)>
+>>
+
+tableValues() ::= <<
+ :usageNumber
+, :usageDefRecordId
+, :targetPhaseDefRecordId
+, :createdDate
+, :createdBy
+, :tenantRecordId
+>>
+
+allTableValues() ::= <<
+ :recordId
+, <tableValues()>
+>>
+
+create() ::= <<
+insert into <tableName()> (
+<tableFields()>
+)
+values (
+<tableValues()>
+)
+;
+>>
+
+getByRecordId() ::= <<
+select <allTableFields()>
+from
+<tableName()>
+where record_id = :recordId
+and tenant_record_id = :tenantRecordId
+;
+>>
+
+getTargetPhaseDefinition(keys) ::= <<
+select
+target_phase_def_record_id
+from (select
+ target_phase_def_record_id
+ , count(*) count
+ from
+ <tableName()>
+ where
+ concat_ws(',', usage_number, usage_def_record_id) in (<keys: {key | :key_<i0>}; separator="," >)
+ and tenant_record_id = :tenantRecordId
+ group by target_phase_def_record_id) tmp
+where
+1=1
+and tmp.count = :targetCount
+;
+>>
+
+getLastInsertId() ::= <<
+select LAST_INSERT_ID();
+>>
+
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
new file mode 100644
index 0000000..34e52da
--- /dev/null
+++ b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideTierBlockSqlDao.sql.stg
@@ -0,0 +1,73 @@
+group CatalogOverrideTierBlockSqlDao;
+
+tableName() ::= "catalog_override_tier_block"
+
+tableFields(prefix) ::= <<
+ <prefix>block_number
+, <prefix>block_def_record_id
+, <prefix>target_tier_def_record_id
+, <prefix>created_date
+, <prefix>created_by
+, <prefix>tenant_record_id
+>>
+
+allTableFields(prefix) ::= <<
+ <prefix>record_id
+, <tableFields(prefix)>
+>>
+
+tableValues() ::= <<
+ :blockNumber
+, :blockDefRecordId
+, :targetTierRecordId
+, :createdDate
+, :createdBy
+, :tenantRecordId
+>>
+
+allTableValues() ::= <<
+ :recordId
+, <tableValues()>
+>>
+
+create() ::= <<
+insert into <tableName()> (
+<tableFields()>
+)
+values (
+<tableValues()>
+)
+;
+>>
+
+getByRecordId() ::= <<
+select <allTableFields()>
+from
+<tableName()>
+where record_id = :recordId
+and tenant_record_id = :tenantRecordId
+;
+>>
+
+getTargetTierDefinition(keys) ::= <<
+select
+target_tier_def_record_id
+from (select
+ target_tier_def_record_id
+ , count(*) count
+ from
+ <tableName()>
+ where
+ concat_ws(',', block_number, block_def_record_id) in (<keys: {key | :key_<i0>}; separator="," >)
+ and tenant_record_id = :tenantRecordId
+ group by target_tier_def_record_id) tmp
+where
+1=1
+and tmp.count = :targetCount
+;
+>>
+
+getLastInsertId() ::= <<
+select LAST_INSERT_ID();
+>>
+
diff --git a/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideTierDefinitionSqlDao.sql.stg b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideTierDefinitionSqlDao.sql.stg
new file mode 100644
index 0000000..dbf1b54
--- /dev/null
+++ b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideTierDefinitionSqlDao.sql.stg
@@ -0,0 +1,67 @@
+group CatalogOverrideTierDefinitionSqlDao;
+
+tableName() ::= "catalog_override_tier_definition"
+
+tableFields(prefix) ::= <<
+ <prefix>fixed_price
+, <prefix>recurring_price
+, <prefix>effective_date
+, <prefix>created_date
+, <prefix>created_by
+, <prefix>currency
+, <prefix>tenant_record_id
+>>
+
+allTableFields(prefix) ::= <<
+ <prefix>record_id
+, <tableFields(prefix)>
+>>
+
+tableValues() ::= <<
+ :fixedPrice
+, :recurringPrice
+, :effectiveDate
+, :createdDate
+, :createdBy
+, :currency
+, :tenantRecordId
+>>
+
+allTableValues() ::= <<
+ :recordId
+, <tableValues()>
+>>
+
+create() ::= <<
+insert into <tableName()> (
+<tableFields()>
+)
+values (
+<tableValues()>
+)
+;
+>>
+
+getByRecordId() ::= <<
+select <allTableFields()>
+from <tableName()>
+where record_id = :recordId
+and tenant_record_id = :tenantRecordId
+;
+>>
+
+getOverriddenUsageTiers() ::= <<
+select <allTableFields("tdef.")>
+from <tableName()> tdef
+join catalog_override_usage_tier ut
+on tdef.record_id = ut.tier_def_record_id
+where
+ut.target_usage_def_record_id = :targetUsageDefRecordId
+and ut.tenant_record_id = :tenantRecordId
+;
+>>
+
+getLastInsertId() ::= <<
+ select LAST_INSERT_ID();
+>>
+
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
new file mode 100644
index 0000000..9455c49
--- /dev/null
+++ b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideUsageDefinitionSqlDao.sql.stg
@@ -0,0 +1,83 @@
+group CatalogOverrideUsageDefinitionSqlDao;
+
+tableName() ::= "catalog_override_usage_definition"
+
+tableFields(prefix) ::= <<
+ <prefix>parent_usage_name
+, <prefix>type
+, <prefix>fixed_price
+, <prefix>recurring_price
+, <prefix>effective_date
+, <prefix>currency
+, <prefix>created_by
+, <prefix>created_date
+, <prefix>tenant_record_id
+>>
+
+allTableFields(prefix) ::= <<
+ <prefix>record_id
+, <tableFields(prefix)>
+>>
+
+
+tableValues() ::= <<
+ :parentUsageName
+, :parentUsageType
+, :fixedPrice
+, :recurringPrice
+, :effectiveDate
+, :currency
+, :createdBy
+, :createdDate
+, :tenantRecordId
+>>
+
+
+allTableValues() ::= <<
+ :recordId
+, <tableValues()>
+>>
+
+create() ::= <<
+insert into <tableName()>(
+<tableFields()>
+)
+values(
+<tableValues()>
+)
+;
+>>
+
+getByRecordId() ::= <<
+select <allTableFields()>
+from <tableName()>
+where record_id = :recordId
+and tenant_record_id = :tenantRecordId
+;
+>>
+
+getByAttributes() ::= <<
+select <allTableFields()>
+from <tableName()>
+where parent_usage_name = :parentUsageName
+and tenant_record_id = :tenantRecordId
+;
+>>
+
+getOverriddenPhaseUsages() ::= <<
+select <allTableFields("udef.")>
+from <tableName()> udef
+join catalog_override_phase_usage pu
+on udef.record_id = pu.usage_def_record_id
+where
+pu.target_phase_def_record_id = :targetPhaseDefRecordId
+and pu.tenant_record_id = :tenantRecordId
+order by pu.usage_number asc
+;
+>>
+
+
+getLastInsertId() ::= <<
+ select LAST_INSERT_ID();
+>>
+
diff --git a/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideUsageTierSqlDao.sql.stg b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideUsageTierSqlDao.sql.stg
new file mode 100644
index 0000000..18aa401
--- /dev/null
+++ b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverrideUsageTierSqlDao.sql.stg
@@ -0,0 +1,73 @@
+group CatalogOverrideUsageTierSqlDao;
+
+tableName() ::= "catalog_override_usage_tier"
+
+tableFields(prefix) ::= <<
+ <prefix>tier_number
+, <prefix>tier_def_record_id
+, <prefix>target_usage_def_record_id
+, <prefix>created_date
+, <prefix>created_by
+, <prefix>tenant_record_id
+>>
+
+allTableFields(prefix) ::= <<
+ <prefix>record_id
+, <tableFields(prefix)>
+>>
+
+tableValues() ::= <<
+ :tierNumber
+, :tierDefRecordId
+, :targetUsageDefRecordId
+, :createdDate
+, :createdBy
+, :tenantRecordId
+>>
+
+allTableValues() ::= <<
+ :recordId
+, <tableValues()>
+>>
+
+create() ::= <<
+insert into <tableName()> (
+<tableFields()>
+)
+values (
+<tableValues()>
+)
+;
+>>
+
+getByRecordId() ::= <<
+select <allTableFields()>
+from
+<tableName()>
+where record_id = :recordId
+and tenant_record_id = :tenantRecordId
+;
+>>
+
+getTargetUsageDefinition(keys) ::= <<
+select
+target_usage_def_record_id
+from (select
+ target_usage_def_record_id
+ , count(*) count
+ from
+ <tableName()>
+ where
+ concat_ws(',', tier_number, tier_def_record_id) in (<keys: {key | :key_<i0>}; separator="," >)
+ and tenant_record_id = :tenantRecordId
+ group by target_usage_def_record_id) tmp
+where
+1=1
+and tmp.count = :targetCount
+;
+>>
+
+getLastInsertId() ::= <<
+select LAST_INSERT_ID();
+>>
+
diff --git a/catalog/src/main/resources/org/killbill/billing/catalog/ddl.sql b/catalog/src/main/resources/org/killbill/billing/catalog/ddl.sql
index fce5967..0bbd08d 100644
--- a/catalog/src/main/resources/org/killbill/billing/catalog/ddl.sql
+++ b/catalog/src/main/resources/org/killbill/billing/catalog/ddl.sql
@@ -41,3 +41,99 @@ CREATE TABLE catalog_override_plan_phase (
PRIMARY KEY(record_id)
) /*! CHARACTER SET utf8 COLLATE utf8_bin */;
CREATE INDEX catalog_override_plan_phase_idx ON catalog_override_plan_phase(tenant_record_id, phase_number, phase_def_record_id);
+
+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
new file mode 100644
index 0000000..591a6ef
--- /dev/null
+++ b/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverrideBlockDefinitionSqlDao.java
@@ -0,0 +1,107 @@
+/*
+ * 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;
+import static org.testng.Assert.assertNull;
+
+public class TestCatalogOverrideBlockDefinitionSqlDao extends CatalogTestSuiteWithEmbeddedDB {
+
+ @BeforeClass(groups = "slow")
+ public void beforeClass() throws Exception {
+ super.beforeClass();
+ ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(CatalogOverrideBlockDefinitionModelDao.class));
+ }
+
+ @Test(groups = "slow")
+ public void testBasic() throws Exception {
+
+ final CatalogOverrideBlockDefinitionModelDao obj1 = new CatalogOverrideBlockDefinitionModelDao("p1","USD" ,BigDecimal.ONE ,1 ,1 , clock.getUTCNow());
+
+ performTestInTransaction(new WithCatalogOverrideBlockDefinitionSqlDaoTransaction<Void>() {
+ @Override
+ public Void doTransaction(final CatalogOverrideBlockDefinitionSqlDao sqlDao) {
+ sqlDao.create(obj1, internalCallContext);
+ final Long lastInserted = sqlDao.getLastInsertId();
+
+ final CatalogOverrideBlockDefinitionModelDao rehydrated = sqlDao.getByRecordId(lastInserted, internalCallContext);
+ assertEquals(rehydrated.getParentUnitName(), obj1.getParentUnitName());
+ assertEquals(rehydrated.getCurrency().compareTo(obj1.getCurrency()), 0);
+ assertEquals(rehydrated.getPrice().compareTo(obj1.getPrice()), 0);
+ assertEquals(rehydrated.getSize(), obj1.getSize());
+ assertEquals(rehydrated.getMax(), obj1.getMax());
+ return null;
+ }
+ });
+ }
+
+ @Test(groups = "slow")
+ public void testGetByAttributes() throws Exception {
+
+ final CatalogOverrideBlockDefinitionModelDao objWithNoNullPrice = new CatalogOverrideBlockDefinitionModelDao("p2", "USD", BigDecimal.ONE, 1, 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());
+ assertEquals(rehydrated.getCurrency(), obj.getCurrency());
+ assertEquals(rehydrated.getPrice(), obj.getPrice());
+ assertEquals(rehydrated.getSize(), obj.getSize());
+ assertEquals(rehydrated.getMax(), obj.getMax()); */
+ }
+ });
+ }
+
+ 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
+ public T inTransaction(final Handle handle, final TransactionStatus status) throws Exception {
+ final CatalogOverrideBlockDefinitionSqlDao sqlDao = handle.attach(CatalogOverrideBlockDefinitionSqlDao.class);
+ return callback.doTransaction(sqlDao);
+ }
+ });
+ }
+
+}
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 cbff820..39d6c3f 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
@@ -45,8 +45,8 @@ public class TestCatalogOverrideDao extends CatalogTestSuiteWithEmbeddedDB {
final PlanPhasePriceOverride[] resolvedOverrides = new PlanPhasePriceOverride[plan.getAllPhases().length];
resolvedOverrides[0] = null;
- resolvedOverrides[1] = new DefaultPlanPhasePriceOverride(plan.getFinalPhase().getName(), Currency.USD, null, new BigDecimal("128.76"));
- final CatalogOverridePlanDefinitionModelDao newPlan = catalogOverrideDao.getOrCreateOverridePlanDefinition(plan.getName(), new DateTime(catalog.getEffectiveDate()), resolvedOverrides, internalCallContext);
+ resolvedOverrides[1] = new DefaultPlanPhasePriceOverride(plan.getFinalPhase().getName(), Currency.USD, null, new BigDecimal("128.76"), null);
+ final CatalogOverridePlanDefinitionModelDao newPlan = catalogOverrideDao.getOrCreateOverridePlanDefinition(plan, new DateTime(catalog.getEffectiveDate()), resolvedOverrides, internalCallContext);
assertEquals(newPlan.getParentPlanName(), "standard-monthly");
assertTrue(newPlan.getIsActive());
}
@@ -58,10 +58,11 @@ public class TestCatalogOverrideDao extends CatalogTestSuiteWithEmbeddedDB {
final Plan plan = catalog.findCurrentPlan("discount-standard-monthly");
final PlanPhasePriceOverride[] resolvedOverrides = new PlanPhasePriceOverride[plan.getAllPhases().length];
- resolvedOverrides[0] = new DefaultPlanPhasePriceOverride(plan.getAllPhases()[0].getName(), Currency.USD, BigDecimal.TEN, null);
+ resolvedOverrides[0] = new DefaultPlanPhasePriceOverride(plan.getAllPhases()[0].getName(), Currency.USD, BigDecimal.TEN, null, null);
resolvedOverrides[1] = null;
- resolvedOverrides[2] = new DefaultPlanPhasePriceOverride(plan.getFinalPhase().getName(), Currency.USD, null, new BigDecimal("348.64"));
- final CatalogOverridePlanDefinitionModelDao newPlan = catalogOverrideDao.getOrCreateOverridePlanDefinition(plan.getName(), new DateTime(catalog.getEffectiveDate()), resolvedOverrides, internalCallContext);
+ resolvedOverrides[2] = new DefaultPlanPhasePriceOverride(plan.getFinalPhase().getName(), Currency.USD, null, new BigDecimal("348.64"), null);
+ final CatalogOverridePlanDefinitionModelDao newPlan = catalogOverrideDao.getOrCreateOverridePlanDefinition(plan, new DateTime(catalog.getEffectiveDate()), resolvedOverrides, internalCallContext);
+
assertEquals(newPlan.getParentPlanName(), "discount-standard-monthly");
assertTrue(newPlan.getIsActive());
@@ -76,11 +77,11 @@ public class TestCatalogOverrideDao extends CatalogTestSuiteWithEmbeddedDB {
final Plan plan = catalog.findCurrentPlan("discount-standard-monthly");
final PlanPhasePriceOverride[] resolvedOverrides = new PlanPhasePriceOverride[plan.getAllPhases().length];
- resolvedOverrides[0] = new DefaultPlanPhasePriceOverride(plan.getAllPhases()[0].getName(), Currency.USD, BigDecimal.TEN, BigDecimal.ONE);
- resolvedOverrides[1] = new DefaultPlanPhasePriceOverride(plan.getAllPhases()[1].getName(), Currency.USD, BigDecimal.ONE, BigDecimal.TEN);
- resolvedOverrides[2] = new DefaultPlanPhasePriceOverride(plan.getFinalPhase().getName(), Currency.USD, BigDecimal.ZERO, new BigDecimal("348.64"));
+ resolvedOverrides[0] = new DefaultPlanPhasePriceOverride(plan.getAllPhases()[0].getName(), Currency.USD, BigDecimal.TEN, BigDecimal.ONE, null);
+ resolvedOverrides[1] = new DefaultPlanPhasePriceOverride(plan.getAllPhases()[1].getName(), Currency.USD, BigDecimal.ONE, BigDecimal.TEN, null);
+ resolvedOverrides[2] = new DefaultPlanPhasePriceOverride(plan.getFinalPhase().getName(), Currency.USD, BigDecimal.ZERO, new BigDecimal("348.64"), null);
- final CatalogOverridePlanDefinitionModelDao newPlan = catalogOverrideDao.getOrCreateOverridePlanDefinition(plan.getName(), new DateTime(catalog.getEffectiveDate()), resolvedOverrides, internalCallContext);
+ final CatalogOverridePlanDefinitionModelDao newPlan = catalogOverrideDao.getOrCreateOverridePlanDefinition(plan, new DateTime(catalog.getEffectiveDate()), resolvedOverrides, internalCallContext);
final List<CatalogOverridePhaseDefinitionModelDao> phases = catalogOverrideDao.getOverriddenPlanPhases(newPlan.getRecordId(), internalCallContext);
assertEquals(phases.size(), 3);
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverridePhaseDefinitionSqlDao.java b/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverridePhaseDefinitionSqlDao.java
index aa2dc48..6090a65 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverridePhaseDefinitionSqlDao.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/dao/TestCatalogOverridePhaseDefinitionSqlDao.java
@@ -103,7 +103,7 @@ public class TestCatalogOverridePhaseDefinitionSqlDao extends CatalogTestSuiteWi
}
private void checkRehydrated(final CatalogOverridePhaseDefinitionModelDao obj, final CatalogOverridePhaseDefinitionSqlDao sqlDao) {
- final CatalogOverridePhaseDefinitionModelDao rehydrated = sqlDao.getByAttributes(obj.getParentPhaseName(), obj.getCurrency(), obj.getFixedPrice(), obj.getRecurringPrice(), internalCallContext);
+ final CatalogOverridePhaseDefinitionModelDao rehydrated = sqlDao.getByAttributes(obj.getParentPhaseName(), obj.getCurrency(), obj.getFixedPrice(), obj.getRecurringPrice(), internalCallContext).get(0);
assertEquals(rehydrated.getParentPhaseName(), obj.getParentPhaseName());
if (obj.getFixedPrice() != null) {
assertEquals(rehydrated.getFixedPrice().compareTo(obj.getFixedPrice()), 0);
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 858dde8..325b7a2 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/TestDefaultPriceOverride.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/TestDefaultPriceOverride.java
@@ -51,9 +51,9 @@ public class TestDefaultPriceOverride extends CatalogTestSuiteWithEmbeddedDB {
final Plan plan = catalog.findCurrentPlan("discount-standard-monthly");
final List<PlanPhasePriceOverride> overrides = new ArrayList<PlanPhasePriceOverride>();
- final PlanPhasePriceOverride phase1 = new DefaultPlanPhasePriceOverride(plan.getAllPhases()[0].getName(), Currency.USD, BigDecimal.ONE, null);
+ final PlanPhasePriceOverride phase1 = new DefaultPlanPhasePriceOverride(plan.getAllPhases()[0].getName(), Currency.USD, BigDecimal.ONE, null,null);
overrides.add(phase1);
- final PlanPhasePriceOverride phase3 = new DefaultPlanPhasePriceOverride(plan.getAllPhases()[2].getName(), Currency.USD, null, new BigDecimal("142.41"));
+ final PlanPhasePriceOverride phase3 = new DefaultPlanPhasePriceOverride(plan.getAllPhases()[2].getName(), Currency.USD, null, new BigDecimal("142.41"),null);
overrides.add(phase3);
final DefaultPlan overriddenPlan = priceOverride.getOrCreateOverriddenPlan(plan, new DateTime(catalog.getEffectiveDate()), overrides, internalCallContext);
@@ -104,7 +104,7 @@ public class TestDefaultPriceOverride extends CatalogTestSuiteWithEmbeddedDB {
final Plan plan = catalog.findCurrentPlan("discount-standard-monthly");
final List<PlanPhasePriceOverride> overrides = new ArrayList<PlanPhasePriceOverride>();
- final PlanPhasePriceOverride phase1 = new DefaultPlanPhasePriceOverride(plan.getAllPhases()[0].getName(), Currency.USD, null, BigDecimal.ONE);
+ final PlanPhasePriceOverride phase1 = new DefaultPlanPhasePriceOverride(plan.getAllPhases()[0].getName(), Currency.USD, null, BigDecimal.ONE,null);
overrides.add(phase1);
priceOverride.getOrCreateOverriddenPlan(plan, new DateTime(catalog.getEffectiveDate()), overrides, internalCallContext);
@@ -118,9 +118,9 @@ public class TestDefaultPriceOverride extends CatalogTestSuiteWithEmbeddedDB {
final Plan plan = catalog.findCurrentPlan("discount-standard-monthly");
final List<PlanPhasePriceOverride> overrides = new ArrayList<PlanPhasePriceOverride>();
- final PlanPhasePriceOverride phase1 = new DefaultPlanPhasePriceOverride(plan.getAllPhases()[0].getName(), Currency.USD, BigDecimal.ONE, null);
+ final PlanPhasePriceOverride phase1 = new DefaultPlanPhasePriceOverride(plan.getAllPhases()[0].getName(), Currency.USD, BigDecimal.ONE, null, null);
overrides.add(phase1);
- final PlanPhasePriceOverride phase3 = new DefaultPlanPhasePriceOverride(plan.getAllPhases()[2].getName(), Currency.USD, null, new BigDecimal("142.41"));
+ final PlanPhasePriceOverride phase3 = new DefaultPlanPhasePriceOverride(plan.getAllPhases()[2].getName(), Currency.USD, null, new BigDecimal("142.41"),null);
overrides.add(phase3);
final DefaultPlan overriddenPlanCreated = priceOverride.getOrCreateOverriddenPlan(plan, new DateTime(catalog.getEffectiveDate()), overrides, internalCallContext);
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BlockPriceOverrideJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BlockPriceOverrideJson.java
new file mode 100644
index 0000000..e24a727
--- /dev/null
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BlockPriceOverrideJson.java
@@ -0,0 +1,102 @@
+/*
+ * 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.jaxrs.json;
+
+import java.math.BigDecimal;
+
+import javax.annotation.Nullable;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class BlockPriceOverrideJson {
+
+ private String unitName;
+
+ private Double size;
+
+ private BigDecimal price;
+
+ private Double max;
+
+ public BigDecimal getPrice() {
+ return price;
+ }
+
+ public Double getSize() {
+ return size;
+ }
+
+ public String getUnitName() {
+ return unitName;
+ }
+
+ public Double getMax() {
+ return max;
+ }
+
+ @JsonCreator
+ public BlockPriceOverrideJson(@Nullable @JsonProperty("unitName") final String unitName,
+ @Nullable @JsonProperty("size") final Double size,
+ @Nullable @JsonProperty("price") final BigDecimal price,
+ @Nullable @JsonProperty("max") final Double max) {
+ this.unitName = unitName;
+ this.size = size;
+ this.price = price;
+ this.max = max;
+ }
+
+ @Override
+ public String toString() {
+ return "BlockPriceOverrideJson{" +
+ "unitName='" + unitName + '\'' +
+ ",size=" + size +
+ ",price=" + price +
+ ",max=" + max +
+ '}';
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof BlockPriceOverrideJson)) {
+ return false;
+ }
+
+ final BlockPriceOverrideJson that = (BlockPriceOverrideJson) o;
+
+
+ if (unitName != null ? !unitName.equals(that.unitName) : that.unitName != null) {
+ return false;
+ }
+ if (size != null ? size.compareTo(that.size) != 0 : that.size != null) {
+ return false;
+ }
+
+ if (price != null ? price.compareTo(that.price) != 0 : that.price != null) {
+ return false;
+ }
+
+ if (max != null ? max.compareTo(that.max) != 0 : that.max != null) {
+ return false;
+ }
+ return true;
+ }
+}
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 d83acaa..379536e 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
@@ -18,16 +18,28 @@
package org.killbill.billing.jaxrs.json;
import java.math.BigDecimal;
+import java.util.LinkedList;
import java.util.List;
import javax.annotation.Nullable;
+import com.google.common.base.Preconditions;
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.api.CatalogApiException;
import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.catalog.api.PhaseType;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.PlanSpecifier;
+import org.killbill.billing.catalog.api.Tier;
+import org.killbill.billing.catalog.api.TierPriceOverride;
+import org.killbill.billing.catalog.api.TieredBlock;
+import org.killbill.billing.catalog.api.TieredBlockPriceOverride;
+import org.killbill.billing.catalog.api.Usage;
+import org.killbill.billing.catalog.api.UsagePriceOverride;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
@@ -41,16 +53,51 @@ public class PhasePriceOverrideJson {
private final String phaseType;
private final BigDecimal fixedPrice;
private final BigDecimal recurringPrice;
+ private final List<UsagePriceOverrideJson> usagePriceOverrides;
@JsonCreator
public PhasePriceOverrideJson(@JsonProperty("phaseName") final String phaseName,
@JsonProperty("phaseType") final String phaseType,
@Nullable @JsonProperty("fixedPrice") final BigDecimal fixedPrice,
- @Nullable @JsonProperty("recurringPrice") final BigDecimal recurringPrice) {
+ @Nullable @JsonProperty("recurringPrice") final BigDecimal recurringPrice,
+ @Nullable @JsonProperty("usageOverrides") final List<UsagePriceOverrideJson> usagePriceOverrides) {
this.phaseName = phaseName;
this.phaseType = phaseType;
this.fixedPrice = fixedPrice;
this.recurringPrice = recurringPrice;
+ this.usagePriceOverrides = usagePriceOverrides;
+ }
+
+ public PhasePriceOverrideJson(final String phaseName,
+ final String phaseType,
+ final BigDecimal fixedPrice,
+ final BigDecimal recurringPrice,
+ final Usage[] usagePriceOverrides,
+ final Currency currency) throws CatalogApiException {
+ this.phaseName = phaseName;
+ this.phaseType = phaseType;
+ this.fixedPrice = fixedPrice;
+ this.recurringPrice = recurringPrice;
+ this.usagePriceOverrides = new LinkedList<UsagePriceOverrideJson>();
+
+ for (final Usage usage : usagePriceOverrides) {
+ List <TierPriceOverrideJson> tierPriceOverridesJson = new LinkedList<TierPriceOverrideJson>();
+ for(final Tier tier :usage.getTiers())
+ {
+ List <BlockPriceOverrideJson> blockPriceOverridesJson = new LinkedList<BlockPriceOverrideJson>();
+
+ for(final TieredBlock block : tier.getTieredBlocks())
+ {
+ BlockPriceOverrideJson blockPriceOverrideJson = new BlockPriceOverrideJson(block.getUnit().getName(), block.getSize(), block.getPrice().getPrice(currency), block.getMax());
+ blockPriceOverridesJson.add(blockPriceOverrideJson);
+ }
+ TierPriceOverrideJson tierPriceOverrideJson = new TierPriceOverrideJson(blockPriceOverridesJson);
+ tierPriceOverridesJson.add(tierPriceOverrideJson);
+ }
+ final UsagePriceOverrideJson usagePriceOverrideJson = new UsagePriceOverrideJson(usage.getName(), usage.getUsageType(),usage.getBillingMode(), tierPriceOverridesJson);
+ this.usagePriceOverrides.add(usagePriceOverrideJson);
+ }
+
}
public BigDecimal getFixedPrice() {
@@ -69,6 +116,11 @@ public class PhasePriceOverrideJson {
return phaseType;
}
+ public List<UsagePriceOverrideJson> getUsagePriceOverrides() {
+ return usagePriceOverrides;
+ }
+
+
@Override
public String toString() {
return "PhasePriceOverrideJson{" +
@@ -76,6 +128,7 @@ public class PhasePriceOverrideJson {
"phaseType='" + phaseType + '\'' +
", fixedPrice=" + fixedPrice +
", recurringPrice=" + recurringPrice +
+ ", usageOverrides=" + usagePriceOverrides +
'}';
}
@@ -103,6 +156,9 @@ public class PhasePriceOverrideJson {
if (recurringPrice != null ? recurringPrice.compareTo(that.recurringPrice) != 0 : that.recurringPrice != null) {
return false;
}
+ if (usagePriceOverrides != null ? !usagePriceOverrides.equals(that.usagePriceOverrides) : that.usagePriceOverrides != null) {
+ return false;
+ }
return true;
}
@@ -112,6 +168,7 @@ public class PhasePriceOverrideJson {
result = 31 * result + (recurringPrice != null ? recurringPrice.hashCode() : 0);
result = 31 * result + (phaseType != null ? phaseType.hashCode() : 0);
result = 31 * result + (recurringPrice != null ? recurringPrice.hashCode() : 0);
+ result = 31 * result + (usagePriceOverrides != null ? usagePriceOverrides.hashCode() : 0);
return result;
}
@@ -123,14 +180,36 @@ public class PhasePriceOverrideJson {
@Nullable
@Override
public PlanPhasePriceOverride apply(@Nullable final PhasePriceOverrideJson input) {
+
+ List <UsagePriceOverride> usagePriceOverrides = new LinkedList<UsagePriceOverride>();
+ Preconditions.checkNotNull(input);
+ if(input.getUsagePriceOverrides()!= null) {
+ for (final UsagePriceOverrideJson usageOverrideJson : input.getUsagePriceOverrides()) {
+ List<TierPriceOverride> tierPriceOverrides = new LinkedList<TierPriceOverride>();
+ 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());
+ blockPriceOverrides.add(tieredBlockPriceOverride);
+ }
+ DefaultTierPriceOverride tierPriceOverride = new DefaultTierPriceOverride(blockPriceOverrides);
+ tierPriceOverrides.add(tierPriceOverride);
+ }
+ final DefaultUsagePriceOverride usageOverride = new DefaultUsagePriceOverride(usageOverrideJson.getUsageName(), usageOverrideJson.getUsageType(), tierPriceOverrides);
+ usagePriceOverrides.add(usageOverride);
+ }
+ }
+
if (input.getPhaseName() != null) {
- return new DefaultPlanPhasePriceOverride(input.getPhaseName(), currency, input.getFixedPrice(), input.getRecurringPrice());
+ return new DefaultPlanPhasePriceOverride(input.getPhaseName(), currency, input.getFixedPrice(), input.getRecurringPrice(), usagePriceOverrides);
} else {
final PhaseType phaseType = input.getPhaseType() != null ? PhaseType.valueOf(input.getPhaseType()) : null;
+
final PlanPhaseSpecifier planPhaseSpecifier = spec.getPlanName() != null ?
new PlanPhaseSpecifier(spec.getPlanName(), phaseType) :
new PlanPhaseSpecifier(spec.getProductName(), spec.getBillingPeriod(), spec.getPriceListName(), phaseType);
- return new DefaultPlanPhasePriceOverride(planPhaseSpecifier, currency, input.getFixedPrice(), input.getRecurringPrice());
+ return new DefaultPlanPhasePriceOverride(planPhaseSpecifier, currency, input.getFixedPrice(), input.getRecurringPrice(), usagePriceOverrides);
+
}
}
}));
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubscriptionJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubscriptionJson.java
index fd64e0a..13e4b82 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubscriptionJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubscriptionJson.java
@@ -389,7 +389,7 @@ public class SubscriptionJson extends JsonBase {
for (final PlanPhase cur : plan.getAllPhases()) {
final BigDecimal fixedPrice = cur.getFixed() != null ? cur.getFixed().getPrice().getPrice(currency) : null;
final BigDecimal recurringPrice = cur.getRecurring() != null ? cur.getRecurring().getRecurringPrice().getPrice(currency) : null;
- final PhasePriceOverrideJson phase = new PhasePriceOverrideJson(cur.getName(), cur.getPhaseType().toString(), fixedPrice, recurringPrice);
+ final PhasePriceOverrideJson phase = new PhasePriceOverrideJson(cur.getName(), cur.getPhaseType().toString(), fixedPrice, recurringPrice, cur.getUsages(),currency);
priceOverrides.add(phase);
}
}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TierPriceOverrideJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TierPriceOverrideJson.java
new file mode 100644
index 0000000..c60c499
--- /dev/null
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TierPriceOverrideJson.java
@@ -0,0 +1,69 @@
+/*
+ * 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.jaxrs.json;
+
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class TierPriceOverrideJson {
+
+ private final List<BlockPriceOverrideJson> blockPriceOverrides;
+
+ @JsonCreator
+ public TierPriceOverrideJson(@JsonProperty("blockPriceOverrides") final List<BlockPriceOverrideJson> blockPriceOverrides) {
+ this.blockPriceOverrides = blockPriceOverrides;
+ }
+
+ public List<BlockPriceOverrideJson> getBlockPriceOverrides() {
+ return blockPriceOverrides;
+ }
+
+ @Override
+ public String toString() {
+ return "TierPriceOverrideJson{" +
+ "blockPriceOverrides='" + blockPriceOverrides + '\'' +
+ '}';
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof TierPriceOverrideJson)) {
+ return false;
+ }
+
+ final TierPriceOverrideJson that = (TierPriceOverrideJson) o;
+
+ if (blockPriceOverrides != null ? !blockPriceOverrides.equals(that.blockPriceOverrides) : that.blockPriceOverrides != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = blockPriceOverrides != null ? blockPriceOverrides.hashCode() : 0;
+ result = 31 * result + (blockPriceOverrides != null ? blockPriceOverrides.hashCode() : 0);
+ return result;
+ }
+}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/UsagePriceOverrideJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/UsagePriceOverrideJson.java
new file mode 100644
index 0000000..c101f63
--- /dev/null
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/UsagePriceOverrideJson.java
@@ -0,0 +1,112 @@
+/*
+ * 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.jaxrs.json;
+
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+import org.killbill.billing.catalog.api.BillingMode;
+import org.killbill.billing.catalog.api.UsageType;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class UsagePriceOverrideJson {
+
+ private final String usageName;
+
+ private final UsageType usageType;
+
+ private final BillingMode billingMode;
+
+ private final List<TierPriceOverrideJson> tierPriceOverrides;
+
+ @JsonCreator
+ public UsagePriceOverrideJson(@JsonProperty("usageName") final String usageName,
+ @Nullable @JsonProperty("usageType") final UsageType usageType,
+ @Nullable @JsonProperty("billingMode") final BillingMode billingMode,
+ @Nullable @JsonProperty("tierPriceOverrides") final List<TierPriceOverrideJson> tierPriceOverrides ) {
+ this.usageName = usageName;
+ this.usageType = usageType;
+ this.billingMode = billingMode;
+ this.tierPriceOverrides = tierPriceOverrides;
+ }
+
+ public String getUsageName() {
+ return usageName;
+ }
+
+ public UsageType getUsageType() {
+ return usageType;
+ }
+
+ public BillingMode getBillingMode() {
+ return billingMode;
+ }
+
+ public List<TierPriceOverrideJson> getTierPriceOverrides() {
+ return tierPriceOverrides;
+ }
+
+ @Override
+ public String toString() {
+ return "UsagePriceOverrideJson{" +
+ "usageName='" + usageName + '\'' +
+ "usageType='" + usageType + '\'' +
+ ", billingMode=" + billingMode +
+ ", tierPriceOverrides=" + tierPriceOverrides +
+ '}';
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof UsagePriceOverrideJson)) {
+ return false;
+ }
+
+ final UsagePriceOverrideJson that = (UsagePriceOverrideJson) o;
+
+ if (usageName != null ? !usageName.equals(that.usageName) : that.usageName != null) {
+ return false;
+ }
+ if (usageType != null ? !usageType.equals(that.usageType) : that.usageType != null) {
+ return false;
+ }
+ if (billingMode != null ? !billingMode.equals(that.billingMode) : that.billingMode != null) {
+ return false;
+ }
+ if (tierPriceOverrides != null ? !tierPriceOverrides.equals(that.tierPriceOverrides) : that.tierPriceOverrides != null) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = usageName != null ? usageName.hashCode() : 0;
+ result = 31 * result + (usageType != null ? usageType.hashCode() : 0);
+ result = 31 * result + (billingMode != null ? billingMode.hashCode() : 0);
+ result = 31 * result + (tierPriceOverrides != null ? tierPriceOverrides.hashCode() : 0);
+ return result;
+ }
+
+}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
index 2b6f285..7a0e59c 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
@@ -1059,9 +1059,10 @@ public class InvoiceResource extends JaxRsResourceBase {
@Override
public PlanPhasePriceOverride apply(@Nullable final PhasePriceOverrideJson input) {
if (input.getPhaseName() != null) {
- return new DefaultPlanPhasePriceOverride(input.getPhaseName(), account.getCurrency(), input.getFixedPrice(), input.getRecurringPrice());
+
+ return new DefaultPlanPhasePriceOverride(input.getPhaseName(), account.getCurrency(), input.getFixedPrice(), input.getRecurringPrice(), null);
} else {
- return new DefaultPlanPhasePriceOverride(planPhaseSpecifier, account.getCurrency(), input.getFixedPrice(), input.getRecurringPrice());
+ return new DefaultPlanPhasePriceOverride(planPhaseSpecifier, account.getCurrency(), input.getFixedPrice(), input.getRecurringPrice(), null);
}
}
})) : ImmutableList.<PlanPhasePriceOverride>of();
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestBundleJsonWithSubscriptions.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestBundleJsonWithSubscriptions.java
index 3dcd46f..3230c8b 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestBundleJsonWithSubscriptions.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestBundleJsonWithSubscriptions.java
@@ -55,7 +55,7 @@ public class TestBundleJsonWithSubscriptions extends JaxrsTestSuiteNoDB {
UUID.randomUUID().toString(),
null);
- final PhasePriceOverrideJson priceOverride = new PhasePriceOverrideJson(null, "somePhaseType", BigDecimal.ONE, null);
+ final PhasePriceOverrideJson priceOverride = new PhasePriceOverrideJson(null, "somePhaseType", BigDecimal.ONE, null, null);
final SubscriptionJson subscription = new SubscriptionJson(UUID.randomUUID().toString(),
UUID.randomUUID().toString(),
@@ -88,5 +88,6 @@ public class TestBundleJsonWithSubscriptions extends JaxrsTestSuiteNoDB {
final String asJson = mapper.writeValueAsString(bundleJson);
final BundleJson fromJson = mapper.readValue(asJson, BundleJson.class);
Assert.assertEquals(fromJson, bundleJson);
- }
+
+ }
}
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestEntitlementJsonWithEvents.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestEntitlementJsonWithEvents.java
index f9e58bb..adceb4a 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestEntitlementJsonWithEvents.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestEntitlementJsonWithEvents.java
@@ -19,6 +19,7 @@
package org.killbill.billing.jaxrs.json;
import java.math.BigDecimal;
+import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@@ -49,6 +50,7 @@ public class TestEntitlementJsonWithEvents extends JaxrsTestSuiteNoDB {
final DateTime effectiveDate = DefaultClock.toUTCDateTime(new DateTime(DateTimeZone.UTC));
final UUID eventId = UUID.randomUUID();
final List<AuditLogJson> auditLogs = createAuditLogsJson(clock.getUTCNow());
+
final EventSubscriptionJson newEvent = new EventSubscriptionJson(eventId.toString(),
BillingPeriod.NO_BILLING_PERIOD.toString(),
effectiveDate.toLocalDate(),
@@ -62,7 +64,7 @@ public class TestEntitlementJsonWithEvents extends JaxrsTestSuiteNoDB {
PhaseType.DISCOUNT.toString(),
auditLogs);
- final PhasePriceOverrideJson priceOverride = new PhasePriceOverrideJson("bar", null, BigDecimal.TEN, BigDecimal.ONE);
+ final PhasePriceOverrideJson priceOverride = new PhasePriceOverrideJson("bar", null, BigDecimal.TEN, BigDecimal.ONE,null);
final SubscriptionJson entitlementJsonWithEvents = new SubscriptionJson(accountId,
bundleId,
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestEntitlement.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestEntitlement.java
index fe19bb1..54c6495 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestEntitlement.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestEntitlement.java
@@ -224,7 +224,7 @@ public class TestEntitlement extends TestJaxrsBase {
input.setBillingPeriod(BillingPeriod.MONTHLY);
input.setPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
final List<PhasePriceOverride> overrides = new ArrayList<PhasePriceOverride>();
- overrides.add(new PhasePriceOverride(null, PhaseType.TRIAL.toString(), BigDecimal.TEN, null));
+ overrides.add(new PhasePriceOverride(null, PhaseType.TRIAL.toString(), BigDecimal.TEN, null, null));
input.setPriceOverrides(overrides);
final Subscription subscription = killBillClient.createSubscription(input, null, DEFAULT_WAIT_COMPLETION_TIMEOUT_SEC, basicRequestOptions());