Repository: fineract
Updated Branches:
  refs/heads/develop b2aeb81be -> fdac5fa6e


http://git-wip-us.apache.org/repos/asf/fineract/blob/2e00bff5/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/serialization/LoanProductDataValidator.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/serialization/LoanProductDataValidator.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/serialization/LoanProductDataValidator.java
index 8eb132c..04bfa7f 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/serialization/LoanProductDataValidator.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/serialization/LoanProductDataValidator.java
@@ -45,9 +45,9 @@ import 
org.apache.fineract.portfolio.loanproduct.domain.InterestMethod;
 import 
org.apache.fineract.portfolio.loanproduct.domain.InterestRecalculationCompoundingMethod;
 import 
org.apache.fineract.portfolio.loanproduct.domain.LoanPreClosureInterestCalculationStrategy;
 import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
-import 
org.apache.fineract.portfolio.loanproduct.domain.LoanProductConfigurableAttributes;
 import 
org.apache.fineract.portfolio.loanproduct.domain.LoanProductValueConditionType;
 import 
org.apache.fineract.portfolio.loanproduct.domain.RecalculationFrequencyType;
+import 
org.apache.fineract.portfolio.loanproduct.exception.EqualAmortizationUnsupportedFeatureException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
@@ -108,7 +108,7 @@ public final class LoanProductDataValidator {
             LoanProductConstants.recalculationRestFrequencyWeekdayParamName,
             LoanProductConstants.recalculationRestFrequencyNthDayParamName, 
LoanProductConstants.recalculationRestFrequencyOnDayParamName,
             
LoanProductConstants.isCompoundingToBePostedAsTransactionParamName, 
LoanProductConstants.allowCompoundingOnEodParamName,
-            LoanProductConstants.canUseForTopup));
+            LoanProductConstants.canUseForTopup, 
LoanProductConstants.isEqualAmortizationParam));
 
     private static final String[] supportedloanConfigurableAttributes = 
{LoanProductConstants.amortizationTypeParamName,
             LoanProductConstants.interestTypeParamName, 
LoanProductConstants.transactionProcessingStrategyIdParamName,
@@ -148,6 +148,13 @@ public final class LoanProductDataValidator {
             final Long fundId = 
this.fromApiJsonHelper.extractLongNamed("fundId", element);
             
baseDataValidator.reset().parameter("fundId").value(fundId).ignoreIfNull().integerGreaterThanZero();
         }
+        
+        boolean isEqualAmortization = false;
+        if 
(this.fromApiJsonHelper.parameterExists(LoanProductConstants.isEqualAmortizationParam,
 element)) {
+            isEqualAmortization = 
this.fromApiJsonHelper.extractBooleanNamed(LoanProductConstants.isEqualAmortizationParam,
 element);
+            
baseDataValidator.reset().parameter(LoanProductConstants.isEqualAmortizationParam).value(isEqualAmortization).ignoreIfNull()
+                    .validateForBooleanValue();
+        }
 
         if 
(this.fromApiJsonHelper.parameterExists(LoanProductConstants.minimumDaysBetweenDisbursalAndFirstRepayment,
 element)) {
             final Long minimumDaysBetweenDisbursalAndFirstRepayment = 
this.fromApiJsonHelper.extractLongNamed(
@@ -314,6 +321,8 @@ public final class LoanProductDataValidator {
 
         if (isInterestRecalculationEnabled != null) {
             if (isInterestRecalculationEnabled.booleanValue()) {
+                if (isEqualAmortization) { throw new 
EqualAmortizationUnsupportedFeatureException("interest.recalculation",
+                        "interest recalculation"); }
                 validateInterestRecalculationParams(element, 
baseDataValidator, null);
             }
         }
@@ -321,7 +330,9 @@ public final class LoanProductDataValidator {
         // interest rates
         if 
(this.fromApiJsonHelper.parameterExists("isLinkedToFloatingInterestRates", 
element)
                 && 
this.fromApiJsonHelper.extractBooleanNamed("isLinkedToFloatingInterestRates", 
element) == true) {
-            if 
(this.fromApiJsonHelper.parameterExists("interestRatePerPeriod", element)) {
+            if (isEqualAmortization) { throw new 
EqualAmortizationUnsupportedFeatureException("floating.interest.rate",
+                    "floating interest rate"); }       
+               if 
(this.fromApiJsonHelper.parameterExists("interestRatePerPeriod", element)) {
                 baseDataValidator
                         .reset()
                         .parameter("interestRatePerPeriod")
@@ -641,6 +652,13 @@ public final class LoanProductDataValidator {
     private void validateVariableInstallmentSettings(final 
DataValidatorBuilder baseDataValidator, final JsonElement element) {
         if 
(this.fromApiJsonHelper.parameterExists(LoanProductConstants.allowVariableInstallmentsParamName,
 element)
                 && 
this.fromApiJsonHelper.extractBooleanNamed(LoanProductConstants.allowVariableInstallmentsParamName,
 element)) {
+               
+            boolean isEqualAmortization = false;
+            if 
(this.fromApiJsonHelper.parameterExists(LoanProductConstants.isEqualAmortizationParam,
 element)) {
+                isEqualAmortization = 
this.fromApiJsonHelper.extractBooleanNamed(LoanProductConstants.isEqualAmortizationParam,
 element);
+            }
+            if (isEqualAmortization) { throw new 
EqualAmortizationUnsupportedFeatureException("variable.installment",
+                    "variable installment"); }
 
             Long minimumGapBetweenInstallments = null;
             if 
(this.fromApiJsonHelper.parameterExists(LoanProductConstants.minimumGapBetweenInstallments,
 element)) {
@@ -721,6 +739,13 @@ public final class LoanProductDataValidator {
             
baseDataValidator.reset().parameter(LoanProductConstants.multiDisburseLoanParameterName).value(multiDisburseLoan)
                     .ignoreIfNull().validateForBooleanValue();
         }
+        
+        boolean isEqualAmortization = false;
+        if 
(this.fromApiJsonHelper.parameterExists(LoanProductConstants.isEqualAmortizationParam,
 element)) {
+            isEqualAmortization = 
this.fromApiJsonHelper.extractBooleanNamed(LoanProductConstants.isEqualAmortizationParam,
 element);
+        }
+        if (isEqualAmortization && multiDisburseLoan) { throw new 
EqualAmortizationUnsupportedFeatureException("tranche.disbursal",
+                "tranche disbursal"); }
 
         if (multiDisburseLoan) {
             if 
(this.fromApiJsonHelper.parameterExists(LoanProductConstants.outstandingLoanBalanceParameterName,
 element)) {
@@ -1114,6 +1139,13 @@ public final class LoanProductDataValidator {
             
baseDataValidator.reset().parameter(LoanProductConstants.accountMovesOutOfNPAOnlyOnArrearsCompletionParamName)
                     .value(npaChangeConfig).notNull().isOneOfTheseValues(true, 
false);
         }
+        
+        boolean isEqualAmortization = loanProduct.isEqualAmortization();
+        if 
(this.fromApiJsonHelper.parameterExists(LoanProductConstants.isEqualAmortizationParam,
 element)) {
+            isEqualAmortization = 
this.fromApiJsonHelper.extractBooleanNamed(LoanProductConstants.isEqualAmortizationParam,
 element);
+            
baseDataValidator.reset().parameter(LoanProductConstants.isEqualAmortizationParam).value(isEqualAmortization).ignoreIfNull()
+                    .validateForBooleanValue();
+        }
 
         // Interest recalculation settings
         Boolean isInterestRecalculationEnabled = 
loanProduct.isInterestRecalculationEnabled();
@@ -1126,6 +1158,8 @@ public final class LoanProductDataValidator {
 
         if (isInterestRecalculationEnabled != null) {
             if (isInterestRecalculationEnabled) {
+                if (isEqualAmortization) { throw new 
EqualAmortizationUnsupportedFeatureException("interest.recalculation",
+                        "interest recalculation"); }
                 validateInterestRecalculationParams(element, 
baseDataValidator, loanProduct);
             }
         }
@@ -1136,6 +1170,9 @@ public final class LoanProductDataValidator {
             isLinkedToFloatingInterestRates = 
this.fromApiJsonHelper.extractBooleanNamed("isLinkedToFloatingInterestRates", 
element);
         }
         if (isLinkedToFloatingInterestRates) {
+               if(isEqualAmortization){
+               throw new 
EqualAmortizationUnsupportedFeatureException("floating.interest.rate", 
"floating interest rate");
+            }
             if 
(this.fromApiJsonHelper.parameterExists("interestRatePerPeriod", element)) {
                 baseDataValidator
                         .reset()

http://git-wip-us.apache.org/repos/asf/fineract/blob/2e00bff5/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java
index 078d74f..00808fa 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java
@@ -227,7 +227,7 @@ public class LoanProductReadPlatformServiceImpl implements 
LoanProductReadPlatfo
                     + "lp.allow_variabe_installments as 
isVariableIntallmentsAllowed, "
                     + "lvi.minimum_gap as minimumGap, "
                     + "lvi.maximum_gap as maximumGap, "
-                    + "lp.can_use_for_topup as canUseForTopup "
+                    + "lp.can_use_for_topup as canUseForTopup, 
lp.is_equal_amortization as isEqualAmortization "
                     + " from m_product_loan lp "
                     + " left join m_fund f on f.id = lp.fund_id "
                     + " left join m_product_loan_recalculation_details lpr on 
lpr.product_id=lp.id "
@@ -308,7 +308,8 @@ public class LoanProductReadPlatformServiceImpl implements 
LoanProductReadPlatfo
 
             final int amortizationTypeId = JdbcSupport.getInteger(rs, 
"amortizationMethod");
             final EnumOptionData amortizationType = 
LoanEnumerations.amortizationType(amortizationTypeId);
-
+            final boolean isEqualAmortization = 
rs.getBoolean("isEqualAmortization");
+            
             final Integer interestRateFrequencyTypeId = 
JdbcSupport.getInteger(rs, "interestRatePerPeriodFreq");
             final EnumOptionData interestRateFrequencyType = 
LoanEnumerations.interestRateFrequencyType(interestRateFrequencyTypeId);
 
@@ -464,7 +465,7 @@ public class LoanProductReadPlatformServiceImpl implements 
LoanProductReadPlatfo
                     installmentAmountInMultiplesOf, allowAttributeOverrides, 
isLinkedToFloatingInterestRates, floatingRateId,
                     floatingRateName, interestRateDifferential, 
minDifferentialLendingRate, defaultDifferentialLendingRate,
                     maxDifferentialLendingRate, 
isFloatingInterestRateCalculationAllowed, isVariableIntallmentsAllowed, 
minimumGap,
-                    maximumGap, syncExpectedWithDisbursementDate, 
canUseForTopup);
+                    maximumGap, syncExpectedWithDisbursementDate, 
canUseForTopup, isEqualAmortization);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/fineract/blob/2e00bff5/fineract-provider/src/main/resources/sql/migrations/core_db/V337__equal_amortization.sql
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/resources/sql/migrations/core_db/V337__equal_amortization.sql
 
b/fineract-provider/src/main/resources/sql/migrations/core_db/V337__equal_amortization.sql
new file mode 100644
index 0000000..a32ccf4
--- /dev/null
+++ 
b/fineract-provider/src/main/resources/sql/migrations/core_db/V337__equal_amortization.sql
@@ -0,0 +1,21 @@
+--
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements. See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership. The ASF 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.
+--
+
+ALTER TABLE `m_product_loan` ADD COLUMN `is_equal_amortization` TINYINT(1) NOT 
NULL DEFAULT '0';
+ALTER TABLE `m_loan` ADD COLUMN `is_equal_amortization` TINYINT(1) NOT NULL 
DEFAULT '0';
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/fineract/blob/2e00bff5/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/LoanProductRelatedDetailTestHelper.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/LoanProductRelatedDetailTestHelper.java
 
b/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/LoanProductRelatedDetailTestHelper.java
index c429578..c202ae9 100644
--- 
a/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/LoanProductRelatedDetailTestHelper.java
+++ 
b/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/LoanProductRelatedDetailTestHelper.java
@@ -153,10 +153,10 @@ public class LoanProductRelatedDetailTestHelper {
         final Integer daysInYearType = DaysInYearType.ACTUAL.getValue();
         final boolean isInterestRecalculationEnabled = false;
         final boolean considerPartialPeriodInterest = false;
-
+        final boolean isEqualAmortization = false;
         return new LoanProductRelatedDetail(currency, defaultPrincipal, 
defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
                 defaultAnnualNominalInterestRate, interestMethod, 
interestCalculationPeriodMethod, considerPartialPeriodInterest, repayEvery,
                 repaymentFrequencyType, defaultNumberOfRepayments, 
graceOnPrincipalPayment, recurringMoratoriumOnPrincipalPeriods, 
graceOnInterestPayment, graceOnInterestCharged,
-                amortizationMethod, inArrearsTolerance, graceOnArrearsAgeing, 
daysInMonthType, daysInYearType, isInterestRecalculationEnabled);
+                amortizationMethod, inArrearsTolerance, graceOnArrearsAgeing, 
daysInMonthType, daysInYearType, isInterestRecalculationEnabled, 
isEqualAmortization);
     }
 }
\ No newline at end of file

Reply via email to