FINERACT-2081: Fix WholeTerm loan frequency saved on account level

This commit is contained in:
Jose Alberto Hernandez
2024-11-06 09:48:09 +01:00
committed by Adam Saghy
parent 51b6dfa08e
commit 474623b6e3
4 changed files with 66 additions and 2 deletions
@@ -3765,6 +3765,10 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
this.loanRepaymentScheduleDetail.setInterestPeriodFrequencyType(this.loanProduct.getInterestPeriodFrequencyType());
}
public void updateInterestRateFrequencyType(PeriodFrequencyType periodFrequencyType) {
this.loanRepaymentScheduleDetail.setInterestPeriodFrequencyType(periodFrequencyType);
}
public void addLoanTransaction(final LoanTransaction loanTransaction) {
this.loanTransactions.add(loanTransaction);
}
@@ -1253,6 +1253,8 @@ final class LoansApiResourceSwagger {
public Integer fixedLength;
@Schema(example = "2")
public BigDecimal interestRatePerPeriod;
@Schema(example = "3")
public Integer interestRateFrequencyType;
@Schema(example = "1")
public Integer amortizationType;
@Schema(example = "5.5")
@@ -1414,6 +1416,8 @@ final class LoansApiResourceSwagger {
public Integer fixedLength;
@Schema(example = "2")
public BigDecimal interestRatePerPeriod;
@Schema(example = "3")
public Integer interestRateFrequencyType;
@Schema(example = "0")
public Integer interestType;
@Schema(example = "0")
@@ -225,7 +225,12 @@ public class LoanScheduleAssembler {
}
final BigDecimal interestRatePerPeriod = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("interestRatePerPeriod", element);
final PeriodFrequencyType interestRatePeriodFrequencyType = loanProduct.getInterestPeriodFrequencyType();
PeriodFrequencyType interestRatePeriodFrequencyType = loanProduct.getInterestPeriodFrequencyType();
if (this.fromApiJsonHelper.parameterExists(LoanApiConstants.interestRateFrequencyTypeParameterName, element)) {
final Integer interestRateFrequencyType = this.fromApiJsonHelper
.extractIntegerWithLocaleNamed(LoanApiConstants.interestRateFrequencyTypeParameterName, element);
interestRatePeriodFrequencyType = PeriodFrequencyType.fromInt(interestRateFrequencyType);
}
BigDecimal annualNominalInterestRate = BigDecimal.ZERO;
if (interestRatePerPeriod != null) {
@@ -647,7 +652,13 @@ public class LoanScheduleAssembler {
public LoanProductRelatedDetail assembleLoanProductRelatedDetail(final JsonElement element, final LoanProduct loanProduct) {
final LoanApplicationTerms loanApplicationTerms = assembleLoanApplicationTermsFrom(element, loanProduct);
return loanApplicationTerms.toLoanProductRelatedDetail();
LoanProductRelatedDetail loanProductRelatedDetail = loanApplicationTerms.toLoanProductRelatedDetail();
final String interestRateFrequencyTypeParamName = "interestRateFrequencyType";
if (this.fromApiJsonHelper.parameterExists(interestRateFrequencyTypeParamName, element)) {
final Integer newValue = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(interestRateFrequencyTypeParamName, element);
loanProductRelatedDetail.setInterestPeriodFrequencyType(PeriodFrequencyType.fromInt(newValue));
}
return loanProductRelatedDetail;
}
public LoanScheduleModel assembleLoanScheduleFrom(final JsonElement element) {
@@ -18,6 +18,7 @@
*/
package org.apache.fineract.integrationtests;
import static org.apache.fineract.integrationtests.BaseLoanIntegrationTest.InterestRateFrequencyType.WHOLE_TERM;
import static org.apache.fineract.integrationtests.BaseLoanIntegrationTest.InterestRateFrequencyType.YEARS;
import static org.apache.fineract.integrationtests.BaseLoanIntegrationTest.RepaymentFrequencyType.DAYS;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -45,6 +46,7 @@ import org.apache.fineract.client.models.BusinessDateRequest;
import org.apache.fineract.client.models.CreditAllocationData;
import org.apache.fineract.client.models.CreditAllocationOrder;
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
import org.apache.fineract.client.models.GetLoansLoanIdInterestRateFrequencyType;
import org.apache.fineract.client.models.GetLoansLoanIdLoanChargeData;
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod;
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
@@ -5473,6 +5475,49 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
});
}
// UC150: Validate interestRateFrequencyType to set as Whole Term at the Loan account level
// 1. Create a Loan product with Adv. Pment. Alloc. and with Declining Balance and Interest rate frquency type in
// Years
// 2. Submit a Loan account to valedate interestRateFrequencyType attribute
@Test
public void uc150() {
String operationDate = "22 April 2024";
runAt(operationDate, () -> {
Long clientId = client.getClientId();
PostLoanProductsRequest product = createOnePeriod30DaysLongNoInterestPeriodicAccrualProductWithAdvancedPaymentAllocation()
.interestRateFrequencyType(YEARS).numberOfRepayments(4)//
.maxInterestRatePerPeriod((double) 12)//
.repaymentEvery(1)//
.repaymentFrequencyType(RepaymentFrequencyType.MONTHS.longValue())//
.allowPartialPeriodInterestCalcualtion(false)//
.multiDisburseLoan(false)//
.disallowExpectedDisbursements(null)//
.allowApprovedDisbursedAmountsOverApplied(null)//
.overAppliedCalculationType(null)//
.overAppliedNumber(null)//
.installmentAmountInMultiplesOf(null)//
.loanScheduleType(LoanScheduleType.PROGRESSIVE.toString()) //
;//
PostLoanProductsResponse loanProductResponse = loanProductHelper.createLoanProduct(product);
PostLoansRequest applicationRequest = applyLoanRequest(clientId, loanProductResponse.getResourceId(), operationDate, 400.0, 4);
final BigDecimal interestRatePerPeriod = BigDecimal.valueOf(4.0);
applicationRequest = applicationRequest.interestCalculationPeriodType(DAYS).interestRatePerPeriod(interestRatePerPeriod)
.interestRateFrequencyType(WHOLE_TERM).loanTermFrequencyType(RepaymentFrequencyType.MONTHS).repaymentEvery(1)
.repaymentFrequencyType(RepaymentFrequencyType.MONTHS).loanTermFrequency(4)
.transactionProcessingStrategyCode(LoanProductTestBuilder.ADVANCED_PAYMENT_ALLOCATION_STRATEGY);
PostLoansResponse loanResponse = loanTransactionHelper.applyLoan(applicationRequest);
GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
GetLoansLoanIdInterestRateFrequencyType interestRateFrequencyType = loanDetails.getInterestRateFrequencyType();
assertNotNull(interestRateFrequencyType);
assertEquals(interestRateFrequencyType.getId(), WHOLE_TERM);
// Annual Interest rate validation, in this case It must be 12 %
assertEquals(BigDecimal.valueOf(12), loanDetails.getAnnualInterestRate().stripTrailingZeros());
});
}
private Long applyAndApproveLoanProgressiveAdvancedPaymentAllocationStrategyMonthlyRepayments(Long clientId, Long loanProductId,
Integer numberOfRepayments, String loanDisbursementDate, double amount) {
LOG.info("------------------------------APPLY AND APPROVE LOAN ---------------------------------------");