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 c032ac5..53cf0e3 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
@@ -24,6 +24,7 @@ import javax.inject.Inject;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
+import org.killbill.billing.ErrorCode;
import org.killbill.billing.account.api.Account;
import org.killbill.billing.account.api.AccountData;
import org.killbill.billing.api.TestApiListener.NextEvent;
@@ -58,6 +59,7 @@ import com.google.common.collect.ImmutableList;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.fail;
public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
@@ -136,7 +138,6 @@ public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
final Entitlement baseEntitlement2 = createEntitlement("xxx-14-monthly", false);
-
// Add a second plan for same product but with a 30 days trial
final SimplePlanDescriptor desc3 = new DefaultSimplePlanDescriptor("xxx-30-monthly", "XXX", ProductCategory.BASE, account.getCurrency(), BigDecimal.TEN, BillingPeriod.MONTHLY, 30, TimeUnit.DAYS, ImmutableList.<String>of());
catalogUserApi.addSimplePlan(desc3, init, testCallContext);
@@ -157,9 +158,40 @@ public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
assertListenerStatus();
}
+ @Test(groups = "slow")
+ public void testError_CAT_MULTIPLE_MATCHING_PLANS_FOR_PRICELIST() throws Exception {
+
+ // Create a per-tenant catalog with one plan
+ final SimplePlanDescriptor desc1 = new DefaultSimplePlanDescriptor("zoe-monthly", "Zoe", ProductCategory.BASE, account.getCurrency(), BigDecimal.TEN, BillingPeriod.MONTHLY, 0, TimeUnit.UNLIMITED, ImmutableList.<String>of());
+ catalogUserApi.addSimplePlan(desc1, init, testCallContext);
+ StaticCatalog catalog = catalogUserApi.getCurrentCatalog("dummy", testCallContext);
+ assertEquals(catalog.getCurrentPlans().length, 1);
+
+ final SimplePlanDescriptor desc2 = new DefaultSimplePlanDescriptor("zoe-14-monthly", "Zoe", ProductCategory.BASE, account.getCurrency(), BigDecimal.TEN, BillingPeriod.MONTHLY, 14, TimeUnit.DAYS, ImmutableList.<String>of());
+ catalogUserApi.addSimplePlan(desc2, init, testCallContext);
+ catalog = catalogUserApi.getCurrentCatalog("dummy", testCallContext);
+ assertEquals(catalog.getCurrentPlans().length, 2);
+
+ try {
+ final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Zoe", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
+ entitlementApi.createBaseEntitlement(account.getId(), spec, UUID.randomUUID().toString(), null, null, null, false, ImmutableList.<PluginProperty>of(), testCallContext);
+ fail("Creating entitlement should fail");
+ } catch (final EntitlementApiException e) {
+ assertEquals(e.getCode(), ErrorCode.CAT_MULTIPLE_MATCHING_PLANS_FOR_PRICELIST.getCode());
+ }
+ }
+
private Entitlement createEntitlement(final String planName, final boolean expectPayment) throws EntitlementApiException {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(planName, null);
+ return createEntitlement(spec, expectPayment);
+ }
+
+ private Entitlement createEntitlement(final String product, final BillingPeriod billingPeriod, final String priceList, final boolean expectPayment) throws EntitlementApiException {
+ final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(product, billingPeriod, priceList, null);
+ return createEntitlement(spec, expectPayment);
+ }
+ private Entitlement createEntitlement(final PlanPhaseSpecifier spec, final boolean expectPayment) throws EntitlementApiException {
if (expectPayment) {
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
} else {
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceList.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceList.java
index 0d3b457..9d4a134 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceList.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceList.java
@@ -16,7 +16,9 @@
package org.killbill.billing.catalog;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@@ -70,14 +72,15 @@ public class DefaultPriceList extends ValidatingConfig<StandaloneCatalog> implem
* @see org.killbill.billing.catalog.IPriceList#findPlan(org.killbill.billing.catalog.api.IProduct, org.killbill.billing.catalog.api.BillingPeriod)
*/
@Override
- public DefaultPlan findPlan(final Product product, final BillingPeriod period) {
+ public DefaultPlan[] findPlans(final Product product, final BillingPeriod period) {
+ final List<DefaultPlan> result = new ArrayList<DefaultPlan>(plans.length);
for (final DefaultPlan cur : getPlans()) {
if (cur.getProduct().equals(product) &&
(cur.getRecurringBillingPeriod() == null || cur.getRecurringBillingPeriod().equals(period))) {
- return cur;
+ result.add(cur);
}
}
- return null;
+ return result.toArray(new DefaultPlan[result.size()]);
}
@Override
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceListSet.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceListSet.java
index 236cdef..7e0f5e0 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceListSet.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceListSet.java
@@ -26,7 +26,6 @@ import java.util.List;
import org.killbill.billing.ErrorCode;
import org.killbill.billing.catalog.api.BillingPeriod;
import org.killbill.billing.catalog.api.CatalogApiException;
-import org.killbill.billing.catalog.api.Plan;
import org.killbill.billing.catalog.api.PriceList;
import org.killbill.billing.catalog.api.PriceListSet;
import org.killbill.billing.catalog.api.Product;
@@ -53,18 +52,25 @@ public class DefaultPriceListSet extends ValidatingConfig<StandaloneCatalog> imp
this.childPriceLists = childPriceLists != null ? childPriceLists : new DefaultPriceList[0];
}
- public DefaultPlan getPlanFrom(final String priceListName, final Product product,
- final BillingPeriod period) throws CatalogApiException {
- DefaultPlan result = null;
+ public DefaultPlan getPlanFrom(final Product product, final BillingPeriod period, final String priceListName) throws CatalogApiException {
+
+ DefaultPlan[] plans = null;
final DefaultPriceList pl = findPriceListFrom(priceListName);
if (pl != null) {
- result = pl.findPlan(product, period);
+ plans = pl.findPlans(product, period);
}
- if (result != null) {
- return result;
+ if (plans.length == 0) {
+ plans = defaultPricelist.findPlans(product, period);
+ }
+ switch(plans.length) {
+ case 0:
+ return null;
+ case 1:
+ return plans[0];
+ default:
+ throw new CatalogApiException(ErrorCode.CAT_MULTIPLE_MATCHING_PLANS_FOR_PRICELIST,
+ priceListName, product.getName(), period);
}
-
- return defaultPricelist.findPlan(product, period);
}
public DefaultPriceList findPriceListFrom(final String priceListName) throws CatalogApiException {
@@ -142,8 +148,4 @@ public class DefaultPriceListSet extends ValidatingConfig<StandaloneCatalog> imp
return result;
}
- @Override
- public Plan getPlanListFrom(final String s, final Product product, final BillingPeriod billingPeriod) {
- return null;
- }
}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalog.java b/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalog.java
index a7511f4..a2795e3 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalog.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalog.java
@@ -181,7 +181,7 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
}
final String inputOrDefaultPricelist = (spec.getPriceListName() == null) ? PriceListSet.DEFAULT_PRICELIST_NAME : spec.getPriceListName();
final Product product = findCurrentProduct(spec.getProductName());
- result = priceLists.getPlanFrom(inputOrDefaultPricelist, product, spec.getBillingPeriod());
+ result = priceLists.getPlanFrom(product, spec.getBillingPeriod(), inputOrDefaultPricelist);
}
if (result == null) {
throw new CatalogApiException(ErrorCode.CAT_PLAN_NOT_FOUND,
@@ -379,9 +379,9 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
for (BillingPeriod billingPeriod : BillingPeriod.values()) {
for (PriceList priceList : getPriceLists().getAllPriceLists()) {
if (priceListName == null || priceListName.equals(priceList.getName())) {
- Plan addonInList = priceList.findPlan(availAddon, billingPeriod);
- if ((addonInList != null)) {
- availAddons.add(new DefaultListing(addonInList, priceList));
+ Plan[] addonInList = priceList.findPlans(availAddon, billingPeriod);
+ for (Plan cur : addonInList) {
+ availAddons.add(new DefaultListing(cur, priceList));
}
}
}
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/TestPriceListSet.java b/catalog/src/test/java/org/killbill/billing/catalog/TestPriceListSet.java
index d38438a..6f82351 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/TestPriceListSet.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/TestPriceListSet.java
@@ -52,10 +52,10 @@ public class TestPriceListSet extends CatalogTestSuiteNoDB {
};
final DefaultPriceListSet set = new DefaultPriceListSet(defaultPriceList, childPriceLists);
- Assert.assertEquals(set.getPlanFrom(PriceListSet.DEFAULT_PRICELIST_NAME, foo, BillingPeriod.ANNUAL).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
- Assert.assertEquals(set.getPlanFrom(PriceListSet.DEFAULT_PRICELIST_NAME, foo, BillingPeriod.MONTHLY).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
- Assert.assertEquals(set.getPlanFrom("child", foo, BillingPeriod.ANNUAL).getFinalPhase().getPhaseType(), PhaseType.DISCOUNT);
- Assert.assertEquals(set.getPlanFrom("child", foo, BillingPeriod.MONTHLY).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
+ Assert.assertEquals(set.getPlanFrom(foo, BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
+ Assert.assertEquals(set.getPlanFrom(foo, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
+ Assert.assertEquals(set.getPlanFrom(foo, BillingPeriod.ANNUAL, "child").getFinalPhase().getPhaseType(), PhaseType.DISCOUNT);
+ Assert.assertEquals(set.getPlanFrom(foo, BillingPeriod.MONTHLY, "child").getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
}
@Test(groups = "fast")
@@ -79,9 +79,9 @@ public class TestPriceListSet extends CatalogTestSuiteNoDB {
};
final DefaultPriceListSet set = new DefaultPriceListSet(defaultPriceList, childPriceLists);
- Assert.assertEquals(set.getPlanFrom("child", foo, BillingPeriod.ANNUAL).getFinalPhase().getPhaseType(), PhaseType.DISCOUNT);
- Assert.assertEquals(set.getPlanFrom("child", foo, BillingPeriod.MONTHLY).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
- Assert.assertEquals(set.getPlanFrom(PriceListSet.DEFAULT_PRICELIST_NAME, foo, BillingPeriod.ANNUAL).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
- Assert.assertEquals(set.getPlanFrom(PriceListSet.DEFAULT_PRICELIST_NAME, foo, BillingPeriod.MONTHLY).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
+ Assert.assertEquals(set.getPlanFrom(foo, BillingPeriod.ANNUAL, "child").getFinalPhase().getPhaseType(), PhaseType.DISCOUNT);
+ Assert.assertEquals(set.getPlanFrom(foo, BillingPeriod.MONTHLY, "child").getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
+ Assert.assertEquals(set.getPlanFrom(foo, BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
+ Assert.assertEquals(set.getPlanFrom(foo, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
}
}
diff --git a/util/src/test/java/org/killbill/billing/mock/MockPriceList.java b/util/src/test/java/org/killbill/billing/mock/MockPriceList.java
index 3fddaf9..0d22447 100644
--- a/util/src/test/java/org/killbill/billing/mock/MockPriceList.java
+++ b/util/src/test/java/org/killbill/billing/mock/MockPriceList.java
@@ -42,8 +42,10 @@ public class MockPriceList implements PriceList {
}
@Override
- public Plan findPlan(final Product product, final BillingPeriod period) {
- return plan;
+ public Plan[] findPlans(final Product product, final BillingPeriod period) {
+ final Plan[] result = new Plan[1];
+ result[0] = plan;
+ return result;
}
public Plan getPlan() {