Validation error in ChargeDefinition domain object was preventing
interest from being set.
diff --git a/api/src/main/java/io/mifos/portfolio/api/v1/client/PortfolioManager.java b/api/src/main/java/io/mifos/portfolio/api/v1/client/PortfolioManager.java
index c76e05a..3814efe 100644
--- a/api/src/main/java/io/mifos/portfolio/api/v1/client/PortfolioManager.java
+++ b/api/src/main/java/io/mifos/portfolio/api/v1/client/PortfolioManager.java
@@ -201,7 +201,7 @@
   void changeChargeDefinition(
           @PathVariable("productidentifier") final String productIdentifier,
           @PathVariable("chargedefinitionidentifier") final String chargeDefinitionIdentifier,
-          final ChargeDefinition taskDefinition);
+          final ChargeDefinition chargeDefinition);
 
   @RequestMapping(
           value = "/products/{productidentifier}/charges/{chargedefinitionidentifier}",
diff --git a/api/src/main/java/io/mifos/portfolio/api/v1/domain/ChargeDefinition.java b/api/src/main/java/io/mifos/portfolio/api/v1/domain/ChargeDefinition.java
index a7f1ffc..8cd4fc0 100644
--- a/api/src/main/java/io/mifos/portfolio/api/v1/domain/ChargeDefinition.java
+++ b/api/src/main/java/io/mifos/portfolio/api/v1/domain/ChargeDefinition.java
@@ -15,6 +15,7 @@
  */
 package io.mifos.portfolio.api.v1.domain;
 
+import io.mifos.portfolio.api.v1.validation.ValidChargeReference;
 import io.mifos.portfolio.api.v1.validation.ValidPaymentCycleUnit;
 import io.mifos.core.lang.validation.constraints.ValidIdentifier;
 import org.hibernate.validator.constraints.NotBlank;
@@ -61,7 +62,7 @@
   @NotNull
   private ChargeMethod chargeMethod;
 
-  @ValidIdentifier(optional = true)
+  @ValidChargeReference
   private String proportionalTo;
 
   @ValidIdentifier
diff --git a/api/src/main/java/io/mifos/portfolio/api/v1/validation/CheckChargeReference.java b/api/src/main/java/io/mifos/portfolio/api/v1/validation/CheckChargeReference.java
new file mode 100644
index 0000000..ab16e8b
--- /dev/null
+++ b/api/src/main/java/io/mifos/portfolio/api/v1/validation/CheckChargeReference.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.portfolio.api.v1.validation;
+
+import io.mifos.core.lang.validation.CheckIdentifier;
+import io.mifos.individuallending.api.v1.domain.product.ChargeIdentifiers;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+/**
+ * @author Myrle Krantz
+ */
+public class CheckChargeReference implements ConstraintValidator<ValidChargeReference, String> {
+
+  @Override
+  public void initialize(ValidChargeReference constraintAnnotation) {
+
+  }
+
+  @Override
+  public boolean isValid(String value, ConstraintValidatorContext context) {
+    if (value == null)
+      return true;
+
+    if (value.equals(ChargeIdentifiers.MAXIMUM_BALANCE_DESIGNATOR) ||
+        value.equals(ChargeIdentifiers.RUNNING_BALANCE_DESIGNATOR))
+      return true;
+
+    final CheckIdentifier identifierChecker = new CheckIdentifier();
+    return identifierChecker.isValid(value, context);
+  }
+}
diff --git a/api/src/main/java/io/mifos/portfolio/api/v1/validation/ValidChargeReference.java b/api/src/main/java/io/mifos/portfolio/api/v1/validation/ValidChargeReference.java
new file mode 100644
index 0000000..130ac59
--- /dev/null
+++ b/api/src/main/java/io/mifos/portfolio/api/v1/validation/ValidChargeReference.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.portfolio.api.v1.validation;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import java.lang.annotation.*;
+
+/**
+ * @author Myrle Krantz
+ */
+@SuppressWarnings("unused")
+@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Constraint(
+    validatedBy = {CheckChargeReference.class}
+)
+public @interface ValidChargeReference {
+  String message() default "Only valid identifiers or {delegates} can be charge references.";
+
+  Class<?>[] groups() default {};
+
+  Class<? extends Payload>[] payload() default {};
+}
diff --git a/api/src/test/java/io/mifos/portfolio/api/v1/domain/ChargeDefinitionTest.java b/api/src/test/java/io/mifos/portfolio/api/v1/domain/ChargeDefinitionTest.java
index 0838319..750be0b 100644
--- a/api/src/test/java/io/mifos/portfolio/api/v1/domain/ChargeDefinitionTest.java
+++ b/api/src/test/java/io/mifos/portfolio/api/v1/domain/ChargeDefinitionTest.java
@@ -103,6 +103,12 @@
               x.setProportionalTo(null);
             })
             .valid(true));
+    ret.add(new ValidationTestCase<ChargeDefinition>("proportionalToRunningBalance")
+        .adjustment(x -> x.setProportionalTo("{runningbalance}"))
+        .valid(true));
+    ret.add(new ValidationTestCase<ChargeDefinition>("proportionalToMaximumBalance")
+        .adjustment(x -> x.setProportionalTo("{maximumbalance}"))
+        .valid(true));
     return ret;
   }
 }
diff --git a/component-test/src/main/java/io/mifos/portfolio/Fixture.java b/component-test/src/main/java/io/mifos/portfolio/Fixture.java
index 5d60486..7a3a05c 100644
--- a/component-test/src/main/java/io/mifos/portfolio/Fixture.java
+++ b/component-test/src/main/java/io/mifos/portfolio/Fixture.java
@@ -23,6 +23,7 @@
 import io.mifos.individuallending.api.v1.domain.product.ProductParameters;
 
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.time.temporal.ChronoUnit;
 import java.util.*;
 import java.util.function.Consumer;
@@ -40,6 +41,7 @@
 
   public static final int MINOR_CURRENCY_UNIT_DIGITS = 2;
   private static int uniquenessSuffix = 0;
+  static final BigDecimal interestRate = BigDecimal.valueOf(0.10).setScale(4, RoundingMode.HALF_EVEN);
 
   static public Product getTestProduct() {
     final Product product = new Product();
diff --git a/component-test/src/main/java/io/mifos/portfolio/TestChargeDefinitions.java b/component-test/src/main/java/io/mifos/portfolio/TestChargeDefinitions.java
index b67db68..7de35f0 100644
--- a/component-test/src/main/java/io/mifos/portfolio/TestChargeDefinitions.java
+++ b/component-test/src/main/java/io/mifos/portfolio/TestChargeDefinitions.java
@@ -66,6 +66,7 @@
 
     try {
       portfolioManager.getChargeDefinition(product.getIdentifier(), chargeDefinitionToDelete.getIdentifier());
+      //noinspection ConstantConditions
       Assert.assertFalse(true);
     }
     catch (final NotFoundException ignored) { }
@@ -92,4 +93,26 @@
     final ChargeDefinition chargeDefinitionAsCreated = portfolioManager.getChargeDefinition(product.getIdentifier(), chargeDefinition.getIdentifier());
     Assert.assertEquals(chargeDefinition, chargeDefinitionAsCreated);
   }
+
+
+  @Test
+  public void shouldChangeInterestChargeDefinition() throws InterruptedException {
+    final Product product = createProduct();
+
+    final ChargeDefinition interestChargeDefinition
+        = portfolioManager.getChargeDefinition(product.getIdentifier(), ChargeIdentifiers.INTEREST_ID);
+    interestChargeDefinition.setAmount(Fixture.interestRate);
+
+    portfolioManager.changeChargeDefinition(
+        product.getIdentifier(),
+        interestChargeDefinition.getIdentifier(),
+        interestChargeDefinition);
+    Assert.assertTrue(this.eventRecorder.wait(EventConstants.PUT_CHARGE_DEFINITION,
+        new ChargeDefinitionEvent(product.getIdentifier(), interestChargeDefinition.getIdentifier())));
+
+    final ChargeDefinition chargeDefinitionAsChanged
+        = portfolioManager.getChargeDefinition(product.getIdentifier(), interestChargeDefinition.getIdentifier());
+
+    Assert.assertEquals(interestChargeDefinition, chargeDefinitionAsChanged);
+  }
 }
diff --git a/service/src/main/java/io/mifos/portfolio/service/rest/ChargeDefinitionRestController.java b/service/src/main/java/io/mifos/portfolio/service/rest/ChargeDefinitionRestController.java
index aefab79..d460ea7 100644
--- a/service/src/main/java/io/mifos/portfolio/service/rest/ChargeDefinitionRestController.java
+++ b/service/src/main/java/io/mifos/portfolio/service/rest/ChargeDefinitionRestController.java
@@ -112,8 +112,8 @@
   @RequestMapping(
           value = "{chargedefinitionidentifier}",
           method = RequestMethod.PUT,
-          consumes = MediaType.APPLICATION_JSON_VALUE,
-          produces = MediaType.ALL_VALUE
+          consumes = MediaType.ALL_VALUE,
+          produces = MediaType.APPLICATION_JSON_VALUE
   )
   public ResponseEntity<Void> changeChargeDefinition(
           @PathVariable("productidentifier") final String productIdentifier,