FINERACT-2065: Fixed length loan configuration

This commit is contained in:
Peter Bagrij
2024-03-13 18:59:42 +01:00
committed by Peter Bagrij
parent 76ad2a2bc9
commit b2685ce9cf
20 changed files with 266 additions and 51 deletions
@@ -68,6 +68,8 @@ public final class LoanApplicationTerms {
private Integer actualNumberOfRepayments;
private final Integer repaymentEvery;
private final PeriodFrequencyType repaymentPeriodFrequencyType;
private final Integer fixedLength;
private final Integer nthDay;
private final DayOfWeekType weekDayType;
@@ -249,7 +251,7 @@ public final class LoanApplicationTerms {
final Boolean enableDownPayment, final BigDecimal disbursedAmountPercentageForDownPayment,
final Boolean isAutoRepaymentForDownPaymentEnabled, final RepaymentStartDateType repaymentStartDateType,
final LocalDate submittedOnDate, final LoanScheduleType loanScheduleType,
final LoanScheduleProcessingType loanScheduleProcessingType) {
final LoanScheduleProcessingType loanScheduleProcessingType, final Integer fixedLength) {
final LoanRescheduleStrategyMethod rescheduleStrategyMethod = null;
final CalendarHistoryDataWrapper calendarHistoryDataWrapper = null;
@@ -267,8 +269,8 @@ public final class LoanApplicationTerms {
isSkipRepaymentOnFirstDayOfMonth, holidayDetailDTO, allowCompoundingOnEod, isEqualAmortization, false,
isInterestToBeRecoveredFirstWhenGreaterThanEMI, fixedPrincipalPercentagePerInstallment,
isPrincipalCompoundingDisabledForOverdueLoans, enableDownPayment, disbursedAmountPercentageForDownPayment,
isAutoRepaymentForDownPaymentEnabled, repaymentStartDateType, submittedOnDate, loanScheduleType,
loanScheduleProcessingType);
isAutoRepaymentForDownPaymentEnabled, repaymentStartDateType, submittedOnDate, loanScheduleType, loanScheduleProcessingType,
fixedLength);
}
@@ -324,6 +326,7 @@ public final class LoanApplicationTerms {
}
LoanScheduleType loanScheduleType = loanProductRelatedDetail.getLoanScheduleType();
LoanScheduleProcessingType loanScheduleProcessingType = loanProductRelatedDetail.getLoanScheduleProcessingType();
final Integer fixedLength = loanProductRelatedDetail.getFixedLength();
return new LoanApplicationTerms(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments,
repaymentEvery, repaymentPeriodFrequencyType, ((nthDay != null) ? nthDay.getValue() : null), dayOfWeek, amortizationMethod,
interestMethod, interestRatePerPeriod, interestRatePeriodFrequencyType, annualNominalInterestRate,
@@ -339,8 +342,8 @@ public final class LoanApplicationTerms {
allowCompoundingOnEod, isEqualAmortization, isFirstRepaymentDateAllowedOnHoliday,
isInterestToBeRecoveredFirstWhenGreaterThanEMI, fixedPrincipalPercentagePerInstallment,
isPrincipalCompoundingDisabledForOverdueLoans, isDownPaymentEnabled, disbursedAmountPercentageForDownPayment,
isAutoRepaymentForDownPaymentEnabled, repaymentStartDateType, submittedOnDate, loanScheduleType,
loanScheduleProcessingType);
isAutoRepaymentForDownPaymentEnabled, repaymentStartDateType, submittedOnDate, loanScheduleType, loanScheduleProcessingType,
fixedLength);
}
private LoanApplicationTerms(final ApplicationCurrency currency, final Integer loanTermFrequency,
@@ -369,7 +372,7 @@ public final class LoanApplicationTerms {
final boolean isPrincipalCompoundingDisabledForOverdueLoans, final boolean isDownPaymentEnabled,
final BigDecimal disbursedAmountPercentageForDownPayment, final boolean isAutoRepaymentForDownPaymentEnabled,
final RepaymentStartDateType repaymentStartDateType, final LocalDate submittedOnDate, final LoanScheduleType loanScheduleType,
final LoanScheduleProcessingType loanScheduleProcessingType) {
final LoanScheduleProcessingType loanScheduleProcessingType, final Integer fixedLength) {
this.currency = currency;
this.loanTermFrequency = loanTermFrequency;
@@ -463,6 +466,7 @@ public final class LoanApplicationTerms {
this.submittedOnDate = submittedOnDate;
this.loanScheduleType = loanScheduleType;
this.loanScheduleProcessingType = loanScheduleProcessingType;
this.fixedLength = fixedLength;
}
public Money adjustPrincipalIfLastRepaymentPeriod(final Money principalForPeriod, final Money totalCumulativePrincipalToDate,
@@ -1326,7 +1330,7 @@ public final class LoanApplicationTerms {
this.graceOnArrearsAgeing, this.daysInMonthType.getValue(), this.daysInYearType.getValue(),
this.interestRecalculationEnabled, this.isEqualAmortization, this.isDownPaymentEnabled,
this.disbursedAmountPercentageForDownPayment, this.isAutoRepaymentForDownPaymentEnabled, this.loanScheduleType,
this.loanScheduleProcessingType);
this.loanScheduleProcessingType, this.fixedLength);
}
public Integer getLoanTermFrequency() {
@@ -161,4 +161,6 @@ public interface LoanProductConstants {
// Repayment Strategies
String ADVANCED_PAYMENT_ALLOCATION_STRATEGY = "advanced-payment-allocation-strategy";
String FIXED_LENGTH = "fixedLength";
}
@@ -429,6 +429,8 @@ public class LoanProduct extends AbstractPersistableCustom {
final boolean enableInstallmentLevelDelinquency = command
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY);
final Integer fixedLength = command.integerValueOfParameterNamed(LoanProductConstants.FIXED_LENGTH);
return new LoanProduct(fund, loanTransactionProcessingStrategy, loanProductPaymentAllocationRules, loanProductCreditAllocationRules,
name, shortName, description, currency, principal, minPrincipal, maxPrincipal, interestRatePerPeriod,
minInterestRatePerPeriod, maxInterestRatePerPeriod, interestFrequencyType, annualInterestRate, interestMethod,
@@ -447,7 +449,7 @@ public class LoanProduct extends AbstractPersistableCustom {
isEqualAmortization, productRates, fixedPrincipalPercentagePerInstallment, disallowExpectedDisbursements,
allowApprovedDisbursedAmountsOverApplied, overAppliedCalculationType, overAppliedNumber, dueDaysForRepaymentEvent,
overDueDaysForRepaymentEvent, enableDownPayment, disbursedAmountPercentageDownPayment, enableAutoRepaymentForDownPayment,
repaymentStartDateType, enableInstallmentLevelDelinquency, loanScheduleType, loanScheduleProcessingType);
repaymentStartDateType, enableInstallmentLevelDelinquency, loanScheduleType, loanScheduleProcessingType, fixedLength);
}
@@ -664,7 +666,7 @@ public class LoanProduct extends AbstractPersistableCustom {
final boolean enableDownPayment, final BigDecimal disbursedAmountPercentageForDownPayment,
final boolean enableAutoRepaymentForDownPayment, final RepaymentStartDateType repaymentStartDateType,
final boolean enableInstallmentLevelDelinquency, final LoanScheduleType loanScheduleType,
final LoanScheduleProcessingType loanScheduleProcessingType) {
final LoanScheduleProcessingType loanScheduleProcessingType, final Integer fixedLength) {
this.fund = fund;
this.transactionProcessingStrategyCode = transactionProcessingStrategyCode;
@@ -713,7 +715,7 @@ public class LoanProduct extends AbstractPersistableCustom {
recurringMoratoriumOnPrincipalPeriods, graceOnInterestPayment, graceOnInterestCharged, amortizationMethod,
inArrearsTolerance, graceOnArrearsAgeing, daysInMonthType.getValue(), daysInYearType.getValue(),
isInterestRecalculationEnabled, isEqualAmortization, enableDownPayment, disbursedAmountPercentageForDownPayment,
enableAutoRepaymentForDownPayment, loanScheduleType, loanScheduleProcessingType);
enableAutoRepaymentForDownPayment, loanScheduleType, loanScheduleProcessingType, fixedLength);
this.loanProductRelatedDetail.validateRepaymentPeriodWithGraceSettings();
@@ -1364,6 +1366,12 @@ public class LoanProduct extends AbstractPersistableCustom {
this.updateEnableInstallmentLevelDelinquency(newValue);
}
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.FIXED_LENGTH, loanProductRelatedDetail.getFixedLength())) {
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.FIXED_LENGTH);
actualChanges.put(LoanProductConstants.FIXED_LENGTH, newValue);
loanProductRelatedDetail.setFixedLength(newValue);
}
return actualChanges;
}
@@ -92,6 +92,9 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
@Column(name = "repayment_period_frequency_enum", nullable = false)
private PeriodFrequencyType repaymentPeriodFrequencyType;
@Column(name = "fixed_length", nullable = false)
private Integer fixedLength;
@Column(name = "number_of_repayments", nullable = false)
private Integer numberOfRepayments;
@@ -159,7 +162,7 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
final Integer daysInYearType, final boolean isInterestRecalculationEnabled, final boolean isEqualAmortization,
final boolean enableDownPayment, final BigDecimal disbursedAmountPercentageForDownPayment,
final boolean enableAutoRepaymentForDownPayment, final LoanScheduleType loanScheduleType,
final LoanScheduleProcessingType loanScheduleProcessingType) {
final LoanScheduleProcessingType loanScheduleProcessingType, final Integer fixedLength) {
return new LoanProductRelatedDetail(currency, principal, nominalInterestRatePerPeriod, interestRatePeriodFrequencyType,
nominalAnnualInterestRate, interestMethod, interestCalculationPeriodMethod, allowPartialPeriodInterestCalcualtion,
@@ -167,7 +170,7 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
recurringMoratoriumOnPrincipalPeriods, graceOnInterestPayment, graceOnInterestCharged, amortizationMethod,
inArrearsTolerance, graceOnArrearsAgeing, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
isEqualAmortization, enableDownPayment, disbursedAmountPercentageForDownPayment, enableAutoRepaymentForDownPayment,
loanScheduleType, loanScheduleProcessingType);
loanScheduleType, loanScheduleProcessingType, fixedLength);
}
protected LoanProductRelatedDetail() {
@@ -185,7 +188,7 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
final Integer daysInYearType, final boolean isInterestRecalculationEnabled, final boolean isEqualAmortization,
final boolean enableDownPayment, final BigDecimal disbursedAmountPercentageForDownPayment,
final boolean enableAutoRepaymentForDownPayment, final LoanScheduleType loanScheduleType,
final LoanScheduleProcessingType loanScheduleProcessingType) {
final LoanScheduleProcessingType loanScheduleProcessingType, final Integer fixedLength) {
this.currency = currency;
this.principal = defaultPrincipal;
this.nominalInterestRatePerPeriod = defaultNominalInterestRatePerPeriod;
@@ -197,6 +200,7 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
this.repayEvery = repayEvery;
this.repaymentPeriodFrequencyType = repaymentFrequencyType;
this.numberOfRepayments = defaultNumberOfRepayments;
this.fixedLength = fixedLength;
this.graceOnPrincipalPayment = defaultToNullIfZero(graceOnPrincipalPayment);
this.recurringMoratoriumOnPrincipalPeriods = recurringMoratoriumOnPrincipalPeriods;
this.graceOnInterestPayment = defaultToNullIfZero(graceOnInterestPayment);
@@ -753,4 +757,12 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
public LoanScheduleProcessingType getLoanScheduleProcessingType() {
return loanScheduleProcessingType;
}
public Integer getFixedLength() {
return this.fixedLength;
}
public void setFixedLength(Integer fixedLength) {
this.fixedLength = fixedLength;
}
}
@@ -41,4 +41,5 @@
<include relativeToChangelogFile="true" file="parts/1016_add_credit_allocation_rule.xml"/>
<include relativeToChangelogFile="true" file="parts/1017_add_fee_and_penalty_adjustments_to_loan.xml"/>
<include relativeToChangelogFile="true" file="parts/1018_rename_credited_principal_back_to_credits_amount.xml"/>
<include relativeToChangelogFile="true" file="parts/1019_add_fixed_length.xml"/>
</databaseChangeLog>
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd">
<changeSet author="fineract" id="1">
<addColumn tableName="m_product_loan">
<column name="fixed_length" type="SMALLINT"/>
</addColumn>
<addColumn tableName="m_loan">
<column name="fixed_length" type="SMALLINT"/>
</addColumn>
</changeSet>
</databaseChangeLog>