FINERACT-1968: Progressive Loan schedule handling - interest handling (FLAT interest, Same as repayment period, Equal installments)
This commit is contained in:
+4
-4
@@ -232,7 +232,7 @@ public class LoanScheduleAssembler {
|
||||
Boolean allowPartialPeriodInterestCalcualtion = this.fromApiJsonHelper
|
||||
.extractBooleanNamed(LoanProductConstants.ALLOW_PARTIAL_PERIOD_INTEREST_CALCUALTION_PARAM_NAME, element);
|
||||
if (allowPartialPeriodInterestCalcualtion == null) {
|
||||
allowPartialPeriodInterestCalcualtion = loanProduct.getLoanProductRelatedDetail().isAllowPartialPeriodInterestCalcualtion();
|
||||
allowPartialPeriodInterestCalcualtion = loanProduct.getLoanProductRelatedDetail().isAllowPartialPeriodInterestCalculation();
|
||||
}
|
||||
|
||||
final BigDecimal interestRatePerPeriod = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("interestRatePerPeriod", element);
|
||||
@@ -1359,15 +1359,15 @@ public class LoanScheduleAssembler {
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.ALLOW_PARTIAL_PERIOD_INTEREST_CALCUALTION_PARAM_NAME,
|
||||
loanProductRelatedDetail.isAllowPartialPeriodInterestCalcualtion())) {
|
||||
loanProductRelatedDetail.isAllowPartialPeriodInterestCalculation())) {
|
||||
final boolean newValue = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ALLOW_PARTIAL_PERIOD_INTEREST_CALCUALTION_PARAM_NAME);
|
||||
changes.put(LoanProductConstants.ALLOW_PARTIAL_PERIOD_INTEREST_CALCUALTION_PARAM_NAME, newValue);
|
||||
loanProductRelatedDetail.setAllowPartialPeriodInterestCalcualtion(newValue);
|
||||
loanProductRelatedDetail.setAllowPartialPeriodInterestCalculation(newValue);
|
||||
}
|
||||
|
||||
if (loanProductRelatedDetail.getInterestCalculationPeriodMethod().isDaily()) {
|
||||
loanProductRelatedDetail.setAllowPartialPeriodInterestCalcualtion(false);
|
||||
loanProductRelatedDetail.setAllowPartialPeriodInterestCalculation(false);
|
||||
}
|
||||
|
||||
final String graceOnPrincipalPaymentParamName = "graceOnPrincipalPayment";
|
||||
|
||||
+36
-9
@@ -1667,14 +1667,20 @@ public final class LoanApplicationValidator {
|
||||
}
|
||||
}
|
||||
|
||||
public void validateLoanMultiDisbursementDate(final JsonElement element, LocalDate expectedDisbursementDate, BigDecimal principal) {
|
||||
public void validateLoanMultiDisbursementDate(final JsonElement element, LocalDate expectedDisbursementDate, BigDecimal principal,
|
||||
Loan loan) {
|
||||
Validator.validateOrThrow("loan", baseDataValidator -> {
|
||||
validateLoanMultiDisbursementDate(element, baseDataValidator, expectedDisbursementDate, principal);
|
||||
validateLoanMultiDisbursementDate(element, baseDataValidator, expectedDisbursementDate, principal, loan);
|
||||
});
|
||||
}
|
||||
|
||||
public void validateLoanMultiDisbursementDate(final JsonElement element, final DataValidatorBuilder baseDataValidator,
|
||||
LocalDate expectedDisbursement, BigDecimal totalPrincipal) {
|
||||
validateLoanMultiDisbursementDate(element, baseDataValidator, expectedDisbursement, totalPrincipal, null);
|
||||
}
|
||||
|
||||
public void validateLoanMultiDisbursementDate(final JsonElement element, final DataValidatorBuilder baseDataValidator,
|
||||
LocalDate expectedDisbursement, BigDecimal totalPrincipal, Loan loan) {
|
||||
this.validateDisbursementsAreDatewiseOrdered(element, baseDataValidator);
|
||||
|
||||
final JsonObject topLevelJsonElement = element.getAsJsonObject();
|
||||
@@ -1732,11 +1738,31 @@ public final class LoanApplicationValidator {
|
||||
baseDataValidator.reset().parameter(LoanApiConstants.disbursementPrincipalParameterName)
|
||||
.failWithCode(LoanApiConstants.APPROVED_AMOUNT_IS_LESS_THAN_SUM_OF_TRANCHES);
|
||||
}
|
||||
final Integer interestType = this.fromApiJsonHelper
|
||||
.extractIntegerSansLocaleNamed(LoanApiConstants.interestTypeParameterName, element);
|
||||
baseDataValidator.reset().parameter(LoanApiConstants.interestTypeParameterName).value(interestType).ignoreIfNull()
|
||||
.integerSameAsNumber(InterestMethod.DECLINING_BALANCE.getValue());
|
||||
|
||||
if (loan == null) {
|
||||
final String transactionProcessingStrategyCode = this.fromApiJsonHelper
|
||||
.extractStringNamed(LoanApiConstants.transactionProcessingStrategyCodeParameterName, element);
|
||||
if (transactionProcessingStrategyCode != null) {
|
||||
final Integer interestType = this.fromApiJsonHelper.extractIntegerNamed(LoanApiConstants.interestTypeParameterName,
|
||||
element, Locale.getDefault());
|
||||
String processorCode = loanRepaymentScheduleTransactionProcessorFactory
|
||||
.determineProcessor(transactionProcessingStrategyCode).getCode();
|
||||
boolean isProgressive = "advanced-payment-allocation-strategy".equals(processorCode);
|
||||
if (isProgressive) {
|
||||
baseDataValidator.reset().parameter(LoanApiConstants.interestTypeParameterName).value(interestType)
|
||||
.ignoreIfNull().inMinMaxRange(0, 1);
|
||||
} else {
|
||||
baseDataValidator.reset().parameter(LoanApiConstants.interestTypeParameterName).value(interestType)
|
||||
.ignoreIfNull().integerSameAsNumber(InterestMethod.DECLINING_BALANCE.getValue());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (loan.isCumulativeSchedule()) {
|
||||
baseDataValidator.reset().parameter(LoanApiConstants.interestTypeParameterName)
|
||||
.value(loan.getLoanProductRelatedDetail().getInterestMethod()).ignoreIfNull()
|
||||
.value(InterestMethod.DECLINING_BALANCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1756,7 +1782,7 @@ public final class LoanApplicationValidator {
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod
|
||||
.fromInt(interestCalculationPeriodType);
|
||||
boolean considerPartialPeriodUpdates = interestCalculationPeriodMethod.isDaily() ? interestCalculationPeriodMethod.isDaily()
|
||||
: loanProduct.getLoanProductRelatedDetail().isAllowPartialPeriodInterestCalcualtion();
|
||||
: loanProduct.getLoanProductRelatedDetail().isAllowPartialPeriodInterestCalculation();
|
||||
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.ALLOW_PARTIAL_PERIOD_INTEREST_CALCUALTION_PARAM_NAME,
|
||||
element)) {
|
||||
final Boolean considerPartialInterestEnabled = this.fromApiJsonHelper
|
||||
@@ -1780,7 +1806,8 @@ public final class LoanApplicationValidator {
|
||||
.failWithCode("not.supported.for.selected.interest.calcualtion.type");
|
||||
}
|
||||
|
||||
if (loanProduct.isMultiDisburseLoan()) {
|
||||
if (loanProduct.isMultiDisburseLoan()
|
||||
&& !"advanced-payment-allocation-strategy".equals(loanProduct.getTransactionProcessingStrategyCode())) {
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.MULTI_DISBURSE_LOAN_PARAMETER_NAME)
|
||||
.failWithCode("not.supported.for.selected.interest.calcualtion.type");
|
||||
}
|
||||
@@ -2045,7 +2072,7 @@ public final class LoanApplicationValidator {
|
||||
|
||||
LoanProduct loanProduct = loan.loanProduct();
|
||||
if (loanProduct.isMultiDisburseLoan()) {
|
||||
validateLoanMultiDisbursementDate(element, expectedDisbursementDate, principal);
|
||||
validateLoanMultiDisbursementDate(element, expectedDisbursementDate, principal, loan);
|
||||
|
||||
final JsonArray disbursementDataArray = this.fromApiJsonHelper
|
||||
.extractJsonArrayNamed(LoanApiConstants.disbursementDataParameterName, element);
|
||||
|
||||
+3
-3
@@ -201,15 +201,15 @@ public class LoanProductRelatedDetailUpdateUtil {
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.ALLOW_PARTIAL_PERIOD_INTEREST_CALCUALTION_PARAM_NAME,
|
||||
loanRepaymentScheduleDetail.isAllowPartialPeriodInterestCalcualtion())) {
|
||||
loanRepaymentScheduleDetail.isAllowPartialPeriodInterestCalculation())) {
|
||||
final boolean newValue = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ALLOW_PARTIAL_PERIOD_INTEREST_CALCUALTION_PARAM_NAME);
|
||||
actualChanges.put(LoanProductConstants.ALLOW_PARTIAL_PERIOD_INTEREST_CALCUALTION_PARAM_NAME, newValue);
|
||||
loanRepaymentScheduleDetail.setAllowPartialPeriodInterestCalcualtion(newValue);
|
||||
loanRepaymentScheduleDetail.setAllowPartialPeriodInterestCalculation(newValue);
|
||||
}
|
||||
|
||||
if (loanRepaymentScheduleDetail.getInterestCalculationPeriodMethod().isDaily()) {
|
||||
loanRepaymentScheduleDetail.setAllowPartialPeriodInterestCalcualtion(false);
|
||||
loanRepaymentScheduleDetail.setAllowPartialPeriodInterestCalculation(false);
|
||||
}
|
||||
|
||||
final String graceOnPrincipalPaymentParamName = "graceOnPrincipalPayment";
|
||||
|
||||
+3
-3
@@ -2232,7 +2232,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
}
|
||||
|
||||
private void validateMultiDisbursementData(final JsonCommand command, LocalDate expectedDisbursementDate,
|
||||
boolean isDisallowExpectedDisbursements) {
|
||||
boolean isDisallowExpectedDisbursements, Loan loan) {
|
||||
final String json = command.json();
|
||||
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||
|
||||
@@ -2254,7 +2254,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
final BigDecimal principal = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("approvedLoanAmount", element);
|
||||
|
||||
loanApplicationValidator.validateLoanMultiDisbursementDate(element, baseDataValidator, expectedDisbursementDate, principal);
|
||||
loanApplicationValidator.validateLoanMultiDisbursementDate(element, baseDataValidator, expectedDisbursementDate, principal, loan);
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
@@ -2296,7 +2296,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
final String errorMessage = "cannot.modify.tranches.if.loan.is.pendingapproval.closed.overpaid.writtenoff";
|
||||
throw new LoanMultiDisbursementException(errorMessage);
|
||||
}
|
||||
validateMultiDisbursementData(command, expectedDisbursementDate, loan.loanProduct().isDisallowExpectedDisbursements());
|
||||
validateMultiDisbursementData(command, expectedDisbursementDate, loan.loanProduct().isDisallowExpectedDisbursements(), loan);
|
||||
|
||||
this.validateForAddAndDeleteTranche(loan);
|
||||
|
||||
|
||||
+28
-7
@@ -786,7 +786,7 @@ public final class LoanProductDataValidator {
|
||||
}
|
||||
}
|
||||
|
||||
validateMultiDisburseLoanData(baseDataValidator, element);
|
||||
validateMultiDisburseLoanData(baseDataValidator, element, null);
|
||||
|
||||
validateLoanConfigurableAttributes(baseDataValidator, element);
|
||||
|
||||
@@ -1014,7 +1014,8 @@ public final class LoanProductDataValidator {
|
||||
}
|
||||
}
|
||||
|
||||
private void validateMultiDisburseLoanData(final DataValidatorBuilder baseDataValidator, final JsonElement element) {
|
||||
private void validateMultiDisburseLoanData(final DataValidatorBuilder baseDataValidator, final JsonElement element,
|
||||
final LoanProduct loanProduct) {
|
||||
Boolean multiDisburseLoan = false;
|
||||
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.MULTI_DISBURSE_LOAN_PARAMETER_NAME, element)) {
|
||||
multiDisburseLoan = this.fromApiJsonHelper.extractBooleanNamed(LoanProductConstants.MULTI_DISBURSE_LOAN_PARAMETER_NAME,
|
||||
@@ -1045,14 +1046,34 @@ public final class LoanProductDataValidator {
|
||||
.integerGreaterThanZero();
|
||||
|
||||
final Integer interestType = this.fromApiJsonHelper.extractIntegerNamed(INTEREST_TYPE, element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter(INTEREST_TYPE).value(interestType).ignoreIfNull()
|
||||
.integerSameAsNumber(InterestMethod.DECLINING_BALANCE.getValue());
|
||||
|
||||
boolean isProgressive = isProgressive(element, loanProduct);
|
||||
if (isProgressive) {
|
||||
baseDataValidator.reset().parameter(INTEREST_TYPE).value(interestType).ignoreIfNull().inMinMaxRange(0, 1);
|
||||
} else {
|
||||
baseDataValidator.reset().parameter(INTEREST_TYPE).value(interestType).ignoreIfNull()
|
||||
.integerSameAsNumber(InterestMethod.DECLINING_BALANCE.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
final String overAppliedCalculationType = this.fromApiJsonHelper.extractStringNamed(OVER_APPLIED_CALCULATION_TYPE, element);
|
||||
baseDataValidator.reset().parameter(OVER_APPLIED_CALCULATION_TYPE).value(overAppliedCalculationType).notExceedingLengthOf(10);
|
||||
}
|
||||
|
||||
private boolean isProgressive(JsonElement element, LoanProduct loanProduct) {
|
||||
String processorCode = null;
|
||||
if (loanProduct != null) {
|
||||
processorCode = loanProduct.getTransactionProcessingStrategyCode();
|
||||
}
|
||||
final String transactionProcessingStrategyCode = this.fromApiJsonHelper.extractStringNamed(TRANSACTION_PROCESSING_STRATEGY_CODE,
|
||||
element);
|
||||
if (transactionProcessingStrategyCode != null) {
|
||||
processorCode = loanRepaymentScheduleTransactionProcessorFactory.determineProcessor(transactionProcessingStrategyCode)
|
||||
.getCode();
|
||||
}
|
||||
return "advanced-payment-allocation-strategy".equals(processorCode);
|
||||
}
|
||||
|
||||
private void validateInterestRecalculationParams(final JsonElement element, final DataValidatorBuilder baseDataValidator,
|
||||
final LoanProduct loanProduct) {
|
||||
|
||||
@@ -1868,7 +1889,7 @@ public final class LoanProductDataValidator {
|
||||
}
|
||||
}
|
||||
|
||||
validateMultiDisburseLoanData(baseDataValidator, element);
|
||||
validateMultiDisburseLoanData(baseDataValidator, element, loanProduct);
|
||||
|
||||
// validateLoanConfigurableAttributes(baseDataValidator,element);
|
||||
|
||||
@@ -2549,7 +2570,7 @@ public final class LoanProductDataValidator {
|
||||
}
|
||||
} else if (loanProduct != null) {
|
||||
if (!interestCalculationPeriodMethod.isDaily()) {
|
||||
considerPartialPeriodUpdates = loanProduct.getLoanProductRelatedDetail().isAllowPartialPeriodInterestCalcualtion();
|
||||
considerPartialPeriodUpdates = loanProduct.getLoanProductRelatedDetail().isAllowPartialPeriodInterestCalculation();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2574,7 +2595,7 @@ public final class LoanProductDataValidator {
|
||||
} else if (loanProduct != null) {
|
||||
multiDisburseLoan = loanProduct.isMultiDisburseLoan();
|
||||
}
|
||||
if (multiDisburseLoan != null && multiDisburseLoan) {
|
||||
if (multiDisburseLoan != null && multiDisburseLoan && !isProgressive(element, loanProduct)) {
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.MULTI_DISBURSE_LOAN_PARAMETER_NAME)
|
||||
.failWithCode("not.supported.for.selected.interest.calculation.type");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user