killbill-aplcache
Changes
catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseBillingAlignment.java 13(+13 -0)
catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseChangePlanAlignment.java 17(+17 -0)
Details
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 273f12c..c915227 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceList.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceList.java
@@ -141,4 +141,10 @@ public class DefaultPriceList extends ValidatingConfig<StandaloneCatalog> implem
result = 31 * result + (plans != null ? plans.hashCode() : 0);
return result;
}
+
+ @Override
+ public String toString() {
+ return "DefaultPriceList{" +
+ "name='" + name + '}';
+ }
}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/io/VersionedCatalogLoader.java b/catalog/src/main/java/org/killbill/billing/catalog/io/VersionedCatalogLoader.java
index 6014008..82e8ec5 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/io/VersionedCatalogLoader.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/io/VersionedCatalogLoader.java
@@ -92,13 +92,13 @@ public class VersionedCatalogLoader implements CatalogLoader {
return result;
} catch (final ValidationException e) {
logger.warn("Failed to load default catalog", e);
- throw new CatalogApiException(ErrorCode.CAT_INVALID_DEFAULT);
+ throw new CatalogApiException(ErrorCode.CAT_INVALID_DEFAULT, uriString);
} catch (final JAXBException e) {
logger.warn("Failed to load default catalog", e);
- throw new CatalogApiException(ErrorCode.CAT_INVALID_DEFAULT, e);
+ throw new CatalogApiException(ErrorCode.CAT_INVALID_DEFAULT, uriString);
} catch(IllegalArgumentException e) {
logger.warn("Failed to load default catalog", e);
- throw new CatalogApiException(ErrorCode.CAT_INVALID_DEFAULT, e);
+ throw new CatalogApiException(ErrorCode.CAT_INVALID_DEFAULT, uriString);
} catch (Exception e) {
logger.warn("Failed to load default catalog", e);
throw new IllegalStateException(e);
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseBillingAlignment.java b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseBillingAlignment.java
index fc2b8f5..31e56fc 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseBillingAlignment.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseBillingAlignment.java
@@ -74,4 +74,17 @@ public class DefaultCaseBillingAlignment extends DefaultCasePhase<BillingAlignme
result = 31 * result + (alignment != null ? alignment.hashCode() : 0);
return result;
}
+
+ @Override
+ public String toString() {
+ return "DefaultCaseBillingAlignment {" +
+ "alignment=" + alignment +
+ ", phaseType=" + getPhaseType() +
+ ", product=" + getProduct() +
+ ", productCategory=" + getProductCategory() +
+ ", billingPeriod=" + getBillingPeriod() +
+ ", priceList=" + getPriceList() +
+ '}';
+ }
+
}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseCancelPolicy.java b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseCancelPolicy.java
index b1a061c..11a3399 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseCancelPolicy.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseCancelPolicy.java
@@ -74,4 +74,17 @@ public class DefaultCaseCancelPolicy extends DefaultCasePhase<BillingActionPolic
result = 31 * result + (policy != null ? policy.hashCode() : 0);
return result;
}
+
+ @Override
+ public String toString() {
+ return "DefaultCaseCancelPolicy{" +
+ "policy =" + policy +
+ ", phaseType =" + getPhaseType() +
+ ", product=" + getProduct() +
+ ", productCategory=" + getProductCategory() +
+ ", billingPeriod=" + getBillingPeriod() +
+ ", priceList=" + getPriceList() +
+ '}';
+ }
+
}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseChange.java b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseChange.java
index 62a83cb..4ee86a2 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseChange.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseChange.java
@@ -303,4 +303,19 @@ public abstract class DefaultCaseChange<T> extends ValidatingConfig<StandaloneCa
public PriceList getToPriceList() {
return toPriceList;
}
+
+ @Override
+ public String toString() {
+ return "DefaultCaseChange{" +
+ "phaseType=" + phaseType +
+ ", fromProduct=" + fromProduct +
+ ", fromProductCategory=" + fromProductCategory +
+ ", fromBillingPeriod=" + fromBillingPeriod +
+ ", fromPriceList=" + fromPriceList +
+ ", toProduct=" + toProduct +
+ ", toProductCategory=" + toProductCategory +
+ ", toBillingPeriod=" + toBillingPeriod +
+ ", toPriceList=" + toPriceList +
+ '}';
+ }
}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseChangePlanAlignment.java b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseChangePlanAlignment.java
index f01860c..d3a95b6 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseChangePlanAlignment.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseChangePlanAlignment.java
@@ -68,4 +68,21 @@ public class DefaultCaseChangePlanAlignment extends DefaultCaseChange<PlanAlignm
result = 31 * result + (alignment != null ? alignment.hashCode() : 0);
return result;
}
+
+ @Override
+ public String toString() {
+ return "DefaultCaseChangePlanAlignment {" +
+ "alignment=" + alignment +
+ ", phaseType=" + getPhaseType() +
+ ", fromProduct=" + getFromProduct() +
+ ", fromProductCategory=" + getFromProductCategory() +
+ ", fromBillingPeriod=" + getFromBillingPeriod() +
+ ", fromPriceList=" + getFromPriceList() +
+ ", toProduct=" + getToProduct() +
+ ", toProductCategory=" + getToProductCategory() +
+ ", toBillingPeriod=" + getToBillingPeriod() +
+ ", toPriceList=" + getToPriceList() +
+ '}';
+ }
+
}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseChangePlanPolicy.java b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseChangePlanPolicy.java
index 1464b73..47ec574 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseChangePlanPolicy.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseChangePlanPolicy.java
@@ -16,16 +16,16 @@
package org.killbill.billing.catalog.rules;
+import java.net.URI;
+
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSeeAlso;
+import org.killbill.billing.catalog.CatalogSafetyInitializer;
+import org.killbill.billing.catalog.StandaloneCatalog;
import org.killbill.billing.catalog.api.BillingActionPolicy;
-import org.killbill.billing.catalog.api.BillingPeriod;
-import org.killbill.billing.catalog.api.PhaseType;
-import org.killbill.billing.catalog.api.PriceList;
-import org.killbill.billing.catalog.api.Product;
-import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.catalog.api.rules.CaseChangePlanPolicy;
+import org.killbill.xmlloader.ValidationErrors;
@XmlSeeAlso(DefaultCaseChange.class)
public class DefaultCaseChangePlanPolicy extends DefaultCaseChange<BillingActionPolicy> implements CaseChangePlanPolicy {
@@ -49,6 +49,17 @@ public class DefaultCaseChangePlanPolicy extends DefaultCaseChange<BillingAction
}
@Override
+ public ValidationErrors validate(final StandaloneCatalog catalog, final ValidationErrors errors) {
+ return errors;
+ }
+
+ @Override
+ public void initialize(final StandaloneCatalog catalog, final URI sourceURI) {
+ super.initialize(catalog, sourceURI);
+ CatalogSafetyInitializer.initializeNonRequiredArrayFields(this);
+ }
+
+ @Override
public boolean equals(final Object o) {
if (this == o) {
return true;
@@ -75,4 +86,20 @@ public class DefaultCaseChangePlanPolicy extends DefaultCaseChange<BillingAction
result = 31 * result + (policy != null ? policy.hashCode() : 0);
return result;
}
+
+ @Override
+ public String toString() {
+ return "DefaultCaseChangePlanPolicy {" +
+ "policy=" + policy +
+ ", phaseType=" + phaseType +
+ ", fromProduct=" + getFromProduct() +
+ ", fromProductCategory=" + getFromProductCategory() +
+ ", fromBillingPeriod=" + getFromBillingPeriod() +
+ ", fromPriceList=" + getFromPriceList() +
+ ", toProduct=" + getToProduct() +
+ ", toProductCategory=" + getToProductCategory() +
+ ", toBillingPeriod=" + getToBillingPeriod() +
+ ", toPriceList=" + getToPriceList() +
+ '}';
+ }
}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseCreateAlignment.java b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseCreateAlignment.java
index 5d7862d..5577db3 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseCreateAlignment.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseCreateAlignment.java
@@ -68,4 +68,16 @@ public class DefaultCaseCreateAlignment extends DefaultCaseStandardNaming<PlanAl
result = 31 * result + (alignment != null ? alignment.hashCode() : 0);
return result;
}
+
+ @Override
+ public String toString() {
+ return "DefaultCaseCreateAlignment {" +
+ "alignment =" + alignment +
+ ", product=" + getProduct() +
+ ", productCategory=" + getProductCategory() +
+ ", billingPeriod=" + getBillingPeriod() +
+ ", priceList=" + getPriceList() +
+ '}';
+ }
+
}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCasePriceList.java b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCasePriceList.java
index 7958365..4b9cf33 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCasePriceList.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCasePriceList.java
@@ -143,4 +143,16 @@ public class DefaultCasePriceList extends DefaultCaseStandardNaming<DefaultPrice
result = 31 * result + (toPriceList != null ? toPriceList.hashCode() : 0);
return result;
}
+
+
+ @Override
+ public String toString() {
+ return "DefaultCasePriceList {" +
+ "fromProduct=" + fromProduct +
+ ", fromProductCategory=" + fromProductCategory +
+ ", fromBillingPeriod=" + fromBillingPeriod +
+ ", fromPriceList=" + fromPriceList +
+ ", toPriceList=" + toPriceList +
+ '}';
+ }
}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseStandardNaming.java b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseStandardNaming.java
index 79c73aa..d23c55f 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseStandardNaming.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseStandardNaming.java
@@ -115,4 +115,5 @@ public abstract class DefaultCaseStandardNaming<T> extends DefaultCase<T> implem
result = 31 * result + (priceList != null ? priceList.hashCode() : 0);
return result;
}
+
}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultPlanRules.java b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultPlanRules.java
index 20c4e9c..f9d3238 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultPlanRules.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultPlanRules.java
@@ -18,6 +18,7 @@ package org.killbill.billing.catalog.rules;
import java.net.URI;
import java.util.Arrays;
+import java.util.HashSet;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@@ -45,6 +46,7 @@ import org.killbill.billing.catalog.api.rules.CaseCreateAlignment;
import org.killbill.billing.catalog.api.rules.CasePriceList;
import org.killbill.billing.catalog.api.rules.PlanRules;
import org.killbill.xmlloader.ValidatingConfig;
+import org.killbill.xmlloader.ValidationError;
import org.killbill.xmlloader.ValidationErrors;
import com.google.common.collect.ImmutableList;
@@ -157,7 +159,7 @@ public class DefaultPlanRules extends ValidatingConfig<StandaloneCatalog> implem
}
private DefaultPriceList findPriceList(final PlanSpecifier specifier, final StaticCatalog catalog) throws CatalogApiException {
- DefaultPriceList result = DefaultCase.getResult(priceListCase, specifier, catalog);
+ DefaultPriceList result = DefaultCasePriceList.getResult(priceListCase, specifier, catalog);
if (result == null) {
final String priceListName = specifier.getPlanName() != null ? catalog.findCurrentPlan(specifier.getPlanName()).getPriceListName() : specifier.getPriceListName();
result = (DefaultPriceList) catalog.findCurrentPricelist(priceListName);
@@ -165,13 +167,92 @@ public class DefaultPlanRules extends ValidatingConfig<StandaloneCatalog> implem
return result;
}
+
@Override
public ValidationErrors validate(final StandaloneCatalog catalog, final ValidationErrors errors) {
- //TODO: MDW - Validation: check that the plan change special case pairs are unique!
- //TODO: MDW - Validation: check that the each product appears in at most one tier.
- //TODO: MDW - Unit tests for rules
- //TODO: MDW - validate that there is a default policy for change AND cancel
+ //
+ // Validate that there is a default policy for change AND cancel rules and check unicity of rules
+ //
+ final HashSet<DefaultCaseChangePlanPolicy> caseChangePlanPoliciesSet = new HashSet<DefaultCaseChangePlanPolicy>();
+ boolean foundDefaultCase = false;
+ for (final DefaultCaseChangePlanPolicy cur : changeCase) {
+ if (caseChangePlanPoliciesSet.contains(cur)) {
+ errors.add(new ValidationError(String.format("Duplicate rule for change plan %s", cur.toString()), catalog.getCatalogURI(), DefaultPlanRules.class, ""));
+ } else {
+ caseChangePlanPoliciesSet.add(cur);
+ }
+ if (cur.getPhaseType() == null &&
+ cur.getFromProduct() == null &&
+ cur.getFromProductCategory() == null &&
+ cur.getFromBillingPeriod() == null &&
+ cur.getFromPriceList() == null &&
+ cur.getToProduct() == null &&
+ cur.getToProductCategory() == null &&
+ cur.getToBillingPeriod() == null &&
+ cur.getToPriceList() == null) {
+ foundDefaultCase = true;
+ }
+ }
+ if (!foundDefaultCase) {
+ errors.add(new ValidationError("Missing default rule case for plan change", catalog.getCatalogURI(), DefaultPlanRules.class, ""));
+ }
+
+ final HashSet<DefaultCaseCancelPolicy> defaultCaseCancelPoliciesSet = new HashSet<DefaultCaseCancelPolicy>();
+ foundDefaultCase = false;
+ for (final DefaultCaseCancelPolicy cur : cancelCase) {
+ if (defaultCaseCancelPoliciesSet.contains(cur)) {
+ errors.add(new ValidationError(String.format("Duplicate rule for plan cancellation %s", cur.toString()), catalog.getCatalogURI(), DefaultPlanRules.class, ""));
+ } else {
+ defaultCaseCancelPoliciesSet.add(cur);
+ }
+ if (cur.getPhaseType() == null &&
+ cur.getProduct() == null &&
+ cur.getProductCategory() == null &&
+ cur.getBillingPeriod() == null &&
+ cur.getPriceList() == null) {
+ foundDefaultCase = true;
+ }
+ }
+ if (!foundDefaultCase) {
+ errors.add(new ValidationError("Missing default rule case for plan cancellation", catalog.getCatalogURI(), DefaultPlanRules.class, ""));
+ }
+
+
+ final HashSet<DefaultCaseChangePlanAlignment> caseChangePlanAlignmentsSet = new HashSet<DefaultCaseChangePlanAlignment>();
+ for (final DefaultCaseChangePlanAlignment cur : changeAlignmentCase) {
+ if (caseChangePlanAlignmentsSet.contains(cur)) {
+ errors.add(new ValidationError(String.format("Duplicate rule for plan change alignment %s", cur.toString()), catalog.getCatalogURI(), DefaultPlanRules.class, ""));
+ } else {
+ caseChangePlanAlignmentsSet.add(cur);
+ }
+ }
+
+ final HashSet<DefaultCaseCreateAlignment> caseCreateAlignmentsSet = new HashSet<DefaultCaseCreateAlignment>();
+ for (final DefaultCaseCreateAlignment cur : createAlignmentCase) {
+ if (caseCreateAlignmentsSet.contains(cur)) {
+ errors.add(new ValidationError(String.format("Duplicate rule for create plan alignment %s", cur.toString()), catalog.getCatalogURI(), DefaultPlanRules.class, ""));
+ } else {
+ caseCreateAlignmentsSet.add(cur);
+ }
+ }
+ final HashSet<DefaultCaseBillingAlignment> caseBillingAlignmentsSet = new HashSet<DefaultCaseBillingAlignment>();
+ for (final DefaultCaseBillingAlignment cur : billingAlignmentCase) {
+ if (caseBillingAlignmentsSet.contains(cur)) {
+ errors.add(new ValidationError(String.format("Duplicate rule for billing alignment %s", cur.toString()), catalog.getCatalogURI(), DefaultPlanRules.class, ""));
+ } else {
+ caseBillingAlignmentsSet.add(cur);
+ }
+ }
+
+ final HashSet<DefaultCasePriceList> casePriceListsSet = new HashSet<DefaultCasePriceList>();
+ for (final DefaultCasePriceList cur : priceListCase) {
+ if (casePriceListsSet.contains(cur)) {
+ errors.add(new ValidationError(String.format("Duplicate rule for price list transition %s", cur.toString()), catalog.getCatalogURI(), DefaultPlanRules.class, ""));
+ } else {
+ casePriceListsSet.add(cur);
+ }
+ }
return errors;
}
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/TestStandaloneCatalog.java b/catalog/src/test/java/org/killbill/billing/catalog/TestStandaloneCatalog.java
index 32d839a..c7c411a 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/TestStandaloneCatalog.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/TestStandaloneCatalog.java
@@ -30,17 +30,26 @@ import com.google.common.io.Resources;
public class TestStandaloneCatalog extends CatalogTestSuiteNoDB {
@Test(groups = "fast")
- public void testLoadCatalogWithPlanInvalidProduct() throws Exception {
+ public void testLoadCatalogWithValidationIssues() throws Exception {
try {
XMLLoader.getObjectFromString(Resources.getResource("CatalogWithValidationErrors.xml").toExternalForm(), StandaloneCatalog.class);
Assert.fail();
} catch (final ValidationException e) {
- Assert.assertEquals(e.getErrors().size(), 5);
+ Assert.assertEquals(e.getErrors().size(), 13);
Assert.assertEquals(e.getErrors().get(0).getDescription(), "Invalid product for plan 'standard'");
Assert.assertEquals(e.getErrors().get(1).getDescription(), "Duration can only have 'UNLIMITED' unit if the number is omitted");
Assert.assertEquals(e.getErrors().get(2).getDescription(), "Finite Duration must have a well defined length");
Assert.assertEquals(e.getErrors().get(3).getDescription(), "Initial Phase standard-trial-evergreen of plan standard-trial cannot be of type EVERGREEN");
Assert.assertEquals(e.getErrors().get(4).getDescription(), "Final Phase standard-trial-trial of plan standard-trial cannot be of type TRIAL");
+ Assert.assertEquals(e.getErrors().get(5).getDescription(), "Duplicate rule for change plan DefaultCaseChangePlanPolicy {policy=IMMEDIATE, phaseType=null, fromProduct=DefaultProduct{name='Standard', category=BASE, included=org.killbill.billing.catalog.CatalogEntityCollection@0, available=org.killbill.billing.catalog.CatalogEntityCollection@0, limits=[], catalogName='CatalogWithValidationErrors'}, fromProductCategory=null, fromBillingPeriod=null, fromPriceList=null, toProduct=null, toProductCategory=null, toBillingPeriod=null, toPriceList=null}");
+ Assert.assertEquals(e.getErrors().get(6).getDescription(), "Missing default rule case for plan change");
+ Assert.assertEquals(e.getErrors().get(7).getDescription(), "Duplicate rule for plan cancellation DefaultCaseCancelPolicy{policy =IMMEDIATE, phaseType =null, product=DefaultProduct{name='Standard', category=BASE, included=org.killbill.billing.catalog.CatalogEntityCollection@0, available=org.killbill.billing.catalog.CatalogEntityCollection@0, limits=[], catalogName='CatalogWithValidationErrors'}, productCategory=null, billingPeriod=null, priceList=null}");
+ Assert.assertEquals(e.getErrors().get(8).getDescription(), "Missing default rule case for plan cancellation");
+ Assert.assertEquals(e.getErrors().get(9).getDescription(), "Duplicate rule for plan change alignment DefaultCaseChangePlanAlignment {alignment=START_OF_BUNDLE, phaseType=null, fromProduct=null, fromProductCategory=null, fromBillingPeriod=null, fromPriceList=null, toProduct=null, toProductCategory=null, toBillingPeriod=null, toPriceList=null}");
+ Assert.assertEquals(e.getErrors().get(10).getDescription(), "Duplicate rule for create plan alignment DefaultCaseCreateAlignment {alignment =START_OF_BUNDLE, product=null, productCategory=null, billingPeriod=null, priceList=null}");
+ Assert.assertEquals(e.getErrors().get(11).getDescription(), "Duplicate rule for billing alignment DefaultCaseBillingAlignment {alignment=ACCOUNT, phaseType=null, product=null, productCategory=null, billingPeriod=null, priceList=null}");
+ Assert.assertEquals(e.getErrors().get(12).getDescription(), "Duplicate rule for price list transition DefaultCasePriceList {fromProduct=null, fromProductCategory=null, fromBillingPeriod=null, fromPriceList=null, toPriceList=DefaultPriceList{name='DEFAULT}}");
+
}
}
diff --git a/catalog/src/test/resources/CatalogWithValidationErrors.xml b/catalog/src/test/resources/CatalogWithValidationErrors.xml
index 97cfb4d..26758f8 100644
--- a/catalog/src/test/resources/CatalogWithValidationErrors.xml
+++ b/catalog/src/test/resources/CatalogWithValidationErrors.xml
@@ -20,7 +20,7 @@
xsi:noNamespaceSchemaLocation="CatalogSchema.xsd ">
<effectiveDate>2013-02-08T00:00:00+00:00</effectiveDate>
- <catalogName>CatalogWithPlanInvalidProduct</catalogName>
+ <catalogName>CatalogWithValidationErrors</catalogName>
<recurringBillingMode>IN_ADVANCE</recurringBillingMode>
@@ -34,7 +34,64 @@
</product>
</products>
- <rules></rules>
+
+
+ <!-- Note we defined twice the same rule for each case and also we miss default rules for plan cancellation and change of plan -->
+ <rules>
+ <changePolicy>
+ <changePolicyCase>
+ <fromProduct>Standard</fromProduct>
+ <policy>IMMEDIATE</policy>
+ </changePolicyCase>
+ <changePolicyCase>
+ <fromProduct>Standard</fromProduct>
+ <policy>IMMEDIATE</policy>
+ </changePolicyCase>
+ </changePolicy>
+ <changeAlignment>
+ <changeAlignmentCase>
+ <alignment>START_OF_BUNDLE</alignment>
+ </changeAlignmentCase>
+ <changeAlignmentCase>
+ <alignment>START_OF_BUNDLE</alignment>
+ </changeAlignmentCase>
+ </changeAlignment>
+ <cancelPolicy>
+ <cancelPolicyCase>
+ <product>Standard</product>
+ <policy>IMMEDIATE</policy>
+ </cancelPolicyCase>
+ <cancelPolicyCase>
+ <product>Standard</product>
+ <policy>IMMEDIATE</policy>
+ </cancelPolicyCase>
+ </cancelPolicy>
+ <createAlignment>
+ <createAlignmentCase>
+ <alignment>START_OF_BUNDLE</alignment>
+ </createAlignmentCase>
+ <createAlignmentCase>
+ <alignment>START_OF_BUNDLE</alignment>
+ </createAlignmentCase>
+ </createAlignment>
+ <billingAlignment>
+ <billingAlignmentCase>
+ <alignment>ACCOUNT</alignment>
+ </billingAlignmentCase>
+ <billingAlignmentCase>
+ <alignment>ACCOUNT</alignment>
+ </billingAlignmentCase>
+ </billingAlignment>
+ <priceList>
+ <priceListCase>
+ <toPriceList>DEFAULT</toPriceList>
+ </priceListCase>
+ <priceListCase>
+ <toPriceList>DEFAULT</toPriceList>
+ </priceListCase>
+ </priceList>
+ </rules>
+
<plans>
<plan name="standard">