This is an automated email from the ASF dual-hosted git repository.
adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/develop by this push:
new 3e923bf48 FINERACT-2114: Interest rate modification, adjust reschedule
validation
3e923bf48 is described below
commit 3e923bf483205f8bb1f6415d0247a87ce481baf7
Author: Janos Meszaros <[email protected]>
AuthorDate: Sat Aug 10 15:15:29 2024 +0200
FINERACT-2114: Interest rate modification, adjust reschedule validation
---
.../infrastructure/core/api/JsonCommand.java | 4 +
.../core/serialization/FromJsonHelper.java | 7 ++
.../core/serialization/JsonParserHelper.java | 21 ++++
.../core/serialization/JsonParserHelperTest.java | 95 +++++++++++++++++
.../portfolio/loanaccount/domain/Loan.java | 15 +++
.../RescheduleLoansApiConstants.java | 5 +-
.../data/LoanRescheduleRequestDataValidator.java | 113 ++++++++++++++++-----
...nRescheduleRequestWritePlatformServiceImpl.java | 21 +---
8 files changed, 236 insertions(+), 45 deletions(-)
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/api/JsonCommand.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/api/JsonCommand.java
index 6cfeb4790..46f9f2ddb 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/api/JsonCommand.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/api/JsonCommand.java
@@ -262,6 +262,10 @@ public final class JsonCommand {
return parameterExists(parameterName);
}
+ public boolean hasParameterValue(final String parameterName) {
+ return this.fromApiJsonHelper.parameterHasValue(parameterName,
this.parsedCommand);
+ }
+
public String dateFormat() {
return stringValueOfParameterNamed("dateFormat");
}
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/FromJsonHelper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/FromJsonHelper.java
index 239276d0b..5bd35d56d 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/FromJsonHelper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/FromJsonHelper.java
@@ -157,6 +157,13 @@ public class FromJsonHelper {
return this.helperDelegator.parameterExists(parameterName, element);
}
+ /**
+ * Check Parameter has a non-blank value
+ */
+ public boolean parameterHasValue(final String parameterName, final
JsonElement element) {
+ return this.helperDelegator.parameterHasValue(parameterName, element);
+ }
+
public String extractStringNamed(final String parameterName, final
JsonElement element) {
return this.helperDelegator.extractStringNamed(parameterName, element,
new HashSet<String>());
}
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/JsonParserHelper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/JsonParserHelper.java
index a3cd2bd41..e0573cd7c 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/JsonParserHelper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/JsonParserHelper.java
@@ -61,6 +61,27 @@ public class JsonParserHelper {
return element.getAsJsonObject().has(parameterName);
}
+ /**
+ * Check Parameter has a non-blank value
+ */
+ public boolean parameterHasValue(final String parameterName, final
JsonElement element) {
+ if (element == null || !element.isJsonObject()) {
+ return false;
+ }
+
+ var valueObject = element.getAsJsonObject().get(parameterName);
+ if (valueObject == null || valueObject.isJsonNull()) {
+ return false;
+ }
+ if (valueObject instanceof JsonArray) {
+ return !valueObject.getAsJsonArray().isEmpty();
+ }
+ if (valueObject instanceof JsonObject) {
+ return !valueObject.getAsJsonObject().isEmpty();
+ }
+ return valueObject.isJsonPrimitive() &&
!valueObject.getAsJsonPrimitive().getAsString().isBlank();
+ }
+
public Boolean extractBooleanNamed(final String parameterName, final
JsonElement element, final Set<String> requestParamatersDetected) {
Boolean value = null;
if (element.isJsonObject()) {
diff --git
a/fineract-core/src/test/java/org/apache/fineract/infrastructure/core/serialization/JsonParserHelperTest.java
b/fineract-core/src/test/java/org/apache/fineract/infrastructure/core/serialization/JsonParserHelperTest.java
new file mode 100644
index 000000000..3ed490d7e
--- /dev/null
+++
b/fineract-core/src/test/java/org/apache/fineract/infrastructure/core/serialization/JsonParserHelperTest.java
@@ -0,0 +1,95 @@
+/**
+ * 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.
+ */
+package org.apache.fineract.infrastructure.core.serialization;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+class JsonParserHelperTest {
+
+ static final JsonParserHelper onTestUnit = new JsonParserHelper();
+
+ static final String testDataHasValues = "{\n" + " \"integerNumber\":
10,\n" + " \"doubleNumber\": 3.14,\n"
+ + " \"string\": \"example\",\n" + " \"arrayList\": [1, \"two\",
3.0],\n" + " \"localDate\": \"2024-08-10\",\n"
+ + " \"keyValue\": {\n" + " \"key\": \"sampleKey\",\n" + "
\"value\": \"sampleValue\"\n" + " }\n" + "}";
+
+ static final String testDataValuesEmpty = "{\n" + " \"integerNumber\":
null,\n" + " \"doubleNumber\": 0.0,\n"
+ + " \"string\": \"\",\n" + " \"arrayList\": [],\n" + "
\"localDate\": null,\n" + " \"keyValue\": {\n"
+ + " \"key\": \"\",\n" + " \"value\": null\n" + " }\n" + "}";
+
+ static final String testDataValuesMissing = "{}";
+
+ @Test
+ void parameterExists() {
+ JsonElement jsonHasValues = JsonParser.parseString(testDataHasValues);
+ JsonElement jsonValuesEmpty =
JsonParser.parseString(testDataValuesEmpty);
+ JsonElement jsonValuesMissing =
JsonParser.parseString(testDataValuesMissing);
+
+ Assertions.assertTrue(onTestUnit.parameterExists("integerNumber",
jsonHasValues));
+ Assertions.assertTrue(onTestUnit.parameterExists("doubleNumber",
jsonHasValues));
+ Assertions.assertTrue(onTestUnit.parameterExists("string",
jsonHasValues));
+ Assertions.assertTrue(onTestUnit.parameterExists("arrayList",
jsonHasValues));
+ Assertions.assertTrue(onTestUnit.parameterExists("localDate",
jsonHasValues));
+ Assertions.assertTrue(onTestUnit.parameterExists("keyValue",
jsonHasValues));
+
+ Assertions.assertTrue(onTestUnit.parameterExists("integerNumber",
jsonValuesEmpty));
+ Assertions.assertTrue(onTestUnit.parameterExists("doubleNumber",
jsonValuesEmpty));
+ Assertions.assertTrue(onTestUnit.parameterExists("string",
jsonValuesEmpty));
+ Assertions.assertTrue(onTestUnit.parameterExists("arrayList",
jsonValuesEmpty));
+ Assertions.assertTrue(onTestUnit.parameterExists("localDate",
jsonValuesEmpty));
+ Assertions.assertTrue(onTestUnit.parameterExists("keyValue",
jsonValuesEmpty));
+
+ Assertions.assertFalse(onTestUnit.parameterExists("integerNumber",
jsonValuesMissing));
+ Assertions.assertFalse(onTestUnit.parameterExists("doubleNumber",
jsonValuesMissing));
+ Assertions.assertFalse(onTestUnit.parameterExists("string",
jsonValuesMissing));
+ Assertions.assertFalse(onTestUnit.parameterExists("arrayList",
jsonValuesMissing));
+ Assertions.assertFalse(onTestUnit.parameterExists("localDate",
jsonValuesMissing));
+ Assertions.assertFalse(onTestUnit.parameterExists("keyValue",
jsonValuesMissing));
+ }
+
+ @Test
+ void parameterHasValue() {
+ JsonElement jsonHasValues = JsonParser.parseString(testDataHasValues);
+ JsonElement jsonValuesEmpty =
JsonParser.parseString(testDataValuesEmpty);
+ JsonElement jsonValuesMissing =
JsonParser.parseString(testDataValuesMissing);
+
+ Assertions.assertTrue(onTestUnit.parameterHasValue("integerNumber",
jsonHasValues));
+ Assertions.assertTrue(onTestUnit.parameterHasValue("doubleNumber",
jsonHasValues));
+ Assertions.assertTrue(onTestUnit.parameterHasValue("string",
jsonHasValues));
+ Assertions.assertTrue(onTestUnit.parameterHasValue("arrayList",
jsonHasValues));
+ Assertions.assertTrue(onTestUnit.parameterHasValue("localDate",
jsonHasValues));
+ Assertions.assertTrue(onTestUnit.parameterHasValue("keyValue",
jsonHasValues));
+
+ Assertions.assertFalse(onTestUnit.parameterHasValue("integerNumber",
jsonValuesEmpty));
+ Assertions.assertTrue(onTestUnit.parameterHasValue("doubleNumber",
jsonValuesEmpty));
+ Assertions.assertFalse(onTestUnit.parameterHasValue("string",
jsonValuesEmpty));
+ Assertions.assertFalse(onTestUnit.parameterHasValue("arrayList",
jsonValuesEmpty));
+ Assertions.assertFalse(onTestUnit.parameterHasValue("localDate",
jsonValuesEmpty));
+ Assertions.assertTrue(onTestUnit.parameterHasValue("keyValue",
jsonValuesEmpty));
+
+ Assertions.assertFalse(onTestUnit.parameterHasValue("integerNumber",
jsonValuesMissing));
+ Assertions.assertFalse(onTestUnit.parameterHasValue("doubleNumber",
jsonValuesMissing));
+ Assertions.assertFalse(onTestUnit.parameterHasValue("string",
jsonValuesMissing));
+ Assertions.assertFalse(onTestUnit.parameterHasValue("arrayList",
jsonValuesMissing));
+ Assertions.assertFalse(onTestUnit.parameterHasValue("localDate",
jsonValuesMissing));
+ Assertions.assertFalse(onTestUnit.parameterHasValue("keyValue",
jsonValuesMissing));
+ }
+}
diff --git
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
index 80fb57c04..008f9537e 100644
---
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
+++
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
@@ -4566,6 +4566,21 @@ public class Loan extends
AbstractAuditableWithUTCDateTimeCustom<Long> {
return installment;
}
+ /**
+ * @param date
+ * @return a schedule installment is related to the provided date
+ **/
+ public LoanRepaymentScheduleInstallment
getRelatedRepaymentScheduleInstallment(LocalDate date) {
+ if (date == null) {
+ return null;
+ }
+ return getRepaymentScheduleInstallments()//
+ .stream()//
+ .filter(installment -> date.isAfter(installment.getFromDate())
&& !date.isAfter(installment.getDueDate()))//
+ .findAny()//
+ .orElse(null);//
+ }
+
/**
* @return loan disbursement data
**/
diff --git
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/RescheduleLoansApiConstants.java
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/RescheduleLoansApiConstants.java
index 87f4ebbb0..eb0e41045 100644
---
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/RescheduleLoansApiConstants.java
+++
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/RescheduleLoansApiConstants.java
@@ -50,8 +50,9 @@ public final class RescheduleLoansApiConstants {
public static final String rescheduleReasonCommentParamName =
"rescheduleReasonComment";
public static final String submittedOnDateParamName = "submittedOnDate";
public static final String adjustedDueDateParamName = "adjustedDueDate";
- public static final String
resheduleForMultiDisbursementNotSupportedErrorCode =
"loan.reschedule.tranche.multidisbursement.error.code";
- public static final String
resheduleWithInterestRecalculationNotSupportedErrorCode =
"loan.reschedule.interestrecalculation.error.code";
+ public static final String
rescheduleForMultiDisbursementNotSupportedErrorCode =
"loan.reschedule.tranche.multidisbursement.error.code";
+ public static final String
rescheduleMultipleOperationsNotSupportedErrorCode =
"loan.reschedule.multioperations.error.code";
+ public static final String
rescheduleSelectedOperationNotSupportedErrorCode =
"loan.reschedule.selectedoperationnotsupported.error.code";
public static final String allCommandParamName = "all";
public static final String approveCommandParamName = "approve";
public static final String pendingCommandParamName = "pending";
diff --git
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/data/LoanRescheduleRequestDataValidator.java
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/data/LoanRescheduleRequestDataValidator.java
index 7f6f57abf..531225711 100644
---
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/data/LoanRescheduleRequestDataValidator.java
+++
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/data/LoanRescheduleRequestDataValidator.java
@@ -42,6 +42,7 @@ import
org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge;
import
org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
+import
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
import
org.apache.fineract.portfolio.loanaccount.rescheduleloan.RescheduleLoansApiConstants;
import
org.apache.fineract.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequest;
import org.springframework.stereotype.Component;
@@ -140,11 +141,77 @@ public class LoanRescheduleRequestDataValidator {
dataValidatorBuilder.reset().parameter(RescheduleLoansApiConstants.rescheduleReasonCommentParamName).value(rescheduleReasonComment)
.ignoreIfNull().notExceedingLengthOf(500);
- if
(this.fromJsonHelper.parameterExists(RescheduleLoansApiConstants.emiParamName,
jsonElement)
- ||
this.fromJsonHelper.parameterExists(RescheduleLoansApiConstants.endDateParamName,
jsonElement)) {
+ final LocalDate adjustedDueDate =
this.fromJsonHelper.extractLocalDateNamed(RescheduleLoansApiConstants.adjustedDueDateParamName,
+ jsonElement);
+
+ if (adjustedDueDate != null && DateUtils.isBefore(adjustedDueDate,
rescheduleFromDate)) {
+
dataValidatorBuilder.reset().parameter(RescheduleLoansApiConstants.rescheduleFromDateParamName).failWithCode(
+ "adjustedDueDate.before.rescheduleFromDate", "Adjusted due
date cannot be before the reschedule from date");
+ }
+
+ if
(loan.getLoanProduct().getLoanProductRelatedDetail().getLoanScheduleType() ==
LoanScheduleType.CUMULATIVE) {
final LocalDate endDate =
jsonCommand.localDateValueOfParameterNamed(RescheduleLoansApiConstants.endDateParamName);
final BigDecimal emi =
jsonCommand.bigDecimalValueOfParameterNamed(RescheduleLoansApiConstants.emiParamName);
+ validateForCumulativeLoan(dataValidatorBuilder, loan, jsonElement,
rescheduleFromDate, endDate, emi);
+ } else {
+ validateForProgressiveLoan(dataValidatorBuilder, loan,
jsonElement, rescheduleFromDate, adjustedDueDate);
+ }
+
+ if (!dataValidationErrors.isEmpty()) {
+ throw new PlatformApiDataValidationException(dataValidationErrors);
+ }
+ }
+
+ private void validateForProgressiveLoan(final DataValidatorBuilder
dataValidatorBuilder, final Loan loan, final JsonElement jsonElement,
+ final LocalDate rescheduleFromDate, final LocalDate
adjustedDueDate) {
+ final var unsupportedFields =
List.of(RescheduleLoansApiConstants.graceOnPrincipalParamName, //
+ RescheduleLoansApiConstants.graceOnInterestParamName, //
+ RescheduleLoansApiConstants.extraTermsParamName, //
+ RescheduleLoansApiConstants.emiParamName//
+ );
+
+ for (var unsupportedField : unsupportedFields) {
+ if (this.fromJsonHelper.parameterHasValue(unsupportedField,
jsonElement)) {
+
dataValidatorBuilder.reset().parameter(unsupportedField).failWithCode(
+
RescheduleLoansApiConstants.rescheduleSelectedOperationNotSupportedErrorCode,
+ "Selected operation is not supported by Progressive
Loan at a time during Loan Rescheduling");
+ return;
+ }
+ }
+
+ final LocalDate businessDate = DateUtils.getBusinessLocalDate();
+ LoanRepaymentScheduleInstallment installment = null;
+ if (rescheduleFromDate != null) {
+ boolean hasInterestRateChange =
this.fromJsonHelper.parameterHasValue(RescheduleLoansApiConstants.newInterestRateParamName,
+ jsonElement);
+ if (hasInterestRateChange && adjustedDueDate != null) {
+
dataValidatorBuilder.reset().parameter(RescheduleLoansApiConstants.adjustedDueDateParamName).failWithCode(
+
RescheduleLoansApiConstants.rescheduleMultipleOperationsNotSupportedErrorCode,
+ "Only one operation is supported at a time during Loan
Rescheduling");
+ return;
+ }
+
+ if (hasInterestRateChange &&
!rescheduleFromDate.isAfter(businessDate)) {
+
dataValidatorBuilder.reset().parameter(RescheduleLoansApiConstants.rescheduleFromDateParamName).failWithCode(
+
"loan.reschedule.interestratechange.reschedulefrom.shouldbefuture",
+ "Loan Reschedule From date should be in the future.");
+ }
+
+ if (adjustedDueDate != null) {
+ installment =
loan.getRepaymentScheduleInstallment(rescheduleFromDate);
+ } else if (hasInterestRateChange) {
+ installment =
loan.getRelatedRepaymentScheduleInstallment(rescheduleFromDate);
+ }
+ validateReschedulingInstallment(dataValidatorBuilder, installment);
+ }
+
+ validateForOverdueCharges(dataValidatorBuilder, loan, installment);
+ }
+
+ private void validateForCumulativeLoan(final DataValidatorBuilder
dataValidatorBuilder, final Loan loan, final JsonElement jsonElement,
+ final LocalDate rescheduleFromDate, final LocalDate endDate, final
BigDecimal emi) {
+ if (emi != null || endDate != null) {
dataValidatorBuilder.reset().parameter(RescheduleLoansApiConstants.endDateParamName).value(endDate).notNull();
dataValidatorBuilder.reset().parameter(RescheduleLoansApiConstants.emiParamName).value(emi).notNull().positiveAmount();
@@ -156,15 +223,6 @@ public class LoanRescheduleRequestDataValidator {
.failWithCode("repayment.schedule.installment.does.not.exist", "Repayment
schedule installment does not exist");
}
}
-
- }
-
- final LocalDate adjustedDueDate =
this.fromJsonHelper.extractLocalDateNamed(RescheduleLoansApiConstants.adjustedDueDateParamName,
- jsonElement);
-
- if (adjustedDueDate != null && DateUtils.isBefore(adjustedDueDate,
rescheduleFromDate)) {
-
dataValidatorBuilder.reset().parameter(RescheduleLoansApiConstants.rescheduleFromDateParamName).failWithCode(
- "adjustedDueDate.before.rescheduleFromDate", "Adjusted due
date cannot be before the reschedule from date");
}
// at least one of the following must be provided => graceOnPrincipal,
@@ -177,37 +235,38 @@ public class LoanRescheduleRequestDataValidator {
&&
!this.fromJsonHelper.parameterExists(RescheduleLoansApiConstants.emiParamName,
jsonElement)) {
dataValidatorBuilder.reset().parameter(RescheduleLoansApiConstants.graceOnPrincipalParamName).notNull();
}
- LoanRepaymentScheduleInstallment installment = null;
- if (rescheduleFromDate != null) {
- installment =
loan.getRepaymentScheduleInstallment(rescheduleFromDate);
- if (installment == null) {
-
dataValidatorBuilder.reset().parameter(RescheduleLoansApiConstants.rescheduleFromDateParamName)
-
.failWithCode("repayment.schedule.installment.does.not.exist", "Repayment
schedule installment does not exist");
- }
-
- if (installment != null && installment.isObligationsMet()) {
-
dataValidatorBuilder.reset().parameter(RescheduleLoansApiConstants.rescheduleFromDateParamName)
-
.failWithCode("repayment.schedule.installment.obligation.met", "Repayment
schedule installment obligation met");
- }
+ final LoanRepaymentScheduleInstallment installment =
loan.getRepaymentScheduleInstallment(rescheduleFromDate);
+ if (rescheduleFromDate != null) {
+ validateReschedulingInstallment(dataValidatorBuilder, installment);
}
if (loan.isMultiDisburmentLoan()) {
if (!loan.loanProduct().isDisallowExpectedDisbursements()) {
dataValidatorBuilder.reset().failWithCodeNoParameterAddedToErrorCode(
-
RescheduleLoansApiConstants.resheduleForMultiDisbursementNotSupportedErrorCode,
+
RescheduleLoansApiConstants.rescheduleForMultiDisbursementNotSupportedErrorCode,
"Loan rescheduling is not supported for
multidisbursement tranche loans");
}
}
validateForOverdueCharges(dataValidatorBuilder, loan, installment);
- if (!dataValidationErrors.isEmpty()) {
- throw new PlatformApiDataValidationException(dataValidationErrors);
+ }
+
+ private static void validateReschedulingInstallment(DataValidatorBuilder
dataValidatorBuilder,
+ LoanRepaymentScheduleInstallment installment) {
+ if (installment == null) {
+
dataValidatorBuilder.reset().parameter(RescheduleLoansApiConstants.rescheduleFromDateParamName)
+
.failWithCode("repayment.schedule.installment.does.not.exist", "Repayment
schedule installment does not exist");
+ }
+
+ if (installment != null && installment.isObligationsMet()) {
+
dataValidatorBuilder.reset().parameter(RescheduleLoansApiConstants.rescheduleFromDateParamName)
+
.failWithCode("repayment.schedule.installment.obligation.met", "Repayment
schedule installment obligation met");
}
}
- private void validateForOverdueCharges(DataValidatorBuilder
dataValidatorBuilder, final Loan loan,
+ private void validateForOverdueCharges(final DataValidatorBuilder
dataValidatorBuilder, final Loan loan,
final LoanRepaymentScheduleInstallment installment) {
if (installment != null) {
LocalDate rescheduleFromDate = installment.getFromDate();
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java
index 266514dac..751c3d41f 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java
@@ -195,29 +195,18 @@ public class
LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche
submittedOnDate =
jsonCommand.localDateValueOfParameterNamed(RescheduleLoansApiConstants.submittedOnDateParamName);
}
- // initially set the value to null
- LocalDate rescheduleFromDate = null;
-
// start point of the rescheduling exercise
Integer rescheduleFromInstallment = null;
// initially set the value to null
LocalDate adjustedDueDate = null;
+ LocalDate rescheduleFromDate = jsonCommand
+
.localDateValueOfParameterNamed(RescheduleLoansApiConstants.rescheduleFromDateParamName);
// check if the parameter is in the JsonCommand object
- if
(jsonCommand.hasParameter(RescheduleLoansApiConstants.rescheduleFromDateParamName))
{
- // create a LocalDate object from the "rescheduleFromDate" Date
- // string
- LocalDate localDate =
jsonCommand.localDateValueOfParameterNamed(RescheduleLoansApiConstants.rescheduleFromDateParamName);
-
- if (localDate != null) {
- // get installment by due date
- LoanRepaymentScheduleInstallment installment =
loan.getRepaymentScheduleInstallment(localDate);
- rescheduleFromInstallment =
installment.getInstallmentNumber();
-
- // update the value of the "rescheduleFromDate" variable
- rescheduleFromDate = localDate;
- }
+ if (rescheduleFromDate != null) {
+ // get installment by due date
+ rescheduleFromInstallment =
loan.getRelatedRepaymentScheduleInstallment(rescheduleFromDate).getInstallmentNumber();
}
if
(jsonCommand.hasParameter(RescheduleLoansApiConstants.adjustedDueDateParamName))
{