FINERACT-2081: Fix WholeTerm loan frequency saved on account level
This commit is contained in:
committed by
Adam Saghy
parent
51b6dfa08e
commit
474623b6e3
@@ -3765,6 +3765,10 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
|||||||
this.loanRepaymentScheduleDetail.setInterestPeriodFrequencyType(this.loanProduct.getInterestPeriodFrequencyType());
|
this.loanRepaymentScheduleDetail.setInterestPeriodFrequencyType(this.loanProduct.getInterestPeriodFrequencyType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateInterestRateFrequencyType(PeriodFrequencyType periodFrequencyType) {
|
||||||
|
this.loanRepaymentScheduleDetail.setInterestPeriodFrequencyType(periodFrequencyType);
|
||||||
|
}
|
||||||
|
|
||||||
public void addLoanTransaction(final LoanTransaction loanTransaction) {
|
public void addLoanTransaction(final LoanTransaction loanTransaction) {
|
||||||
this.loanTransactions.add(loanTransaction);
|
this.loanTransactions.add(loanTransaction);
|
||||||
}
|
}
|
||||||
|
|||||||
+4
@@ -1253,6 +1253,8 @@ final class LoansApiResourceSwagger {
|
|||||||
public Integer fixedLength;
|
public Integer fixedLength;
|
||||||
@Schema(example = "2")
|
@Schema(example = "2")
|
||||||
public BigDecimal interestRatePerPeriod;
|
public BigDecimal interestRatePerPeriod;
|
||||||
|
@Schema(example = "3")
|
||||||
|
public Integer interestRateFrequencyType;
|
||||||
@Schema(example = "1")
|
@Schema(example = "1")
|
||||||
public Integer amortizationType;
|
public Integer amortizationType;
|
||||||
@Schema(example = "5.5")
|
@Schema(example = "5.5")
|
||||||
@@ -1414,6 +1416,8 @@ final class LoansApiResourceSwagger {
|
|||||||
public Integer fixedLength;
|
public Integer fixedLength;
|
||||||
@Schema(example = "2")
|
@Schema(example = "2")
|
||||||
public BigDecimal interestRatePerPeriod;
|
public BigDecimal interestRatePerPeriod;
|
||||||
|
@Schema(example = "3")
|
||||||
|
public Integer interestRateFrequencyType;
|
||||||
@Schema(example = "0")
|
@Schema(example = "0")
|
||||||
public Integer interestType;
|
public Integer interestType;
|
||||||
@Schema(example = "0")
|
@Schema(example = "0")
|
||||||
|
|||||||
+13
-2
@@ -225,7 +225,12 @@ public class LoanScheduleAssembler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final BigDecimal interestRatePerPeriod = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("interestRatePerPeriod", element);
|
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;
|
BigDecimal annualNominalInterestRate = BigDecimal.ZERO;
|
||||||
if (interestRatePerPeriod != null) {
|
if (interestRatePerPeriod != null) {
|
||||||
@@ -647,7 +652,13 @@ public class LoanScheduleAssembler {
|
|||||||
|
|
||||||
public LoanProductRelatedDetail assembleLoanProductRelatedDetail(final JsonElement element, final LoanProduct loanProduct) {
|
public LoanProductRelatedDetail assembleLoanProductRelatedDetail(final JsonElement element, final LoanProduct loanProduct) {
|
||||||
final LoanApplicationTerms loanApplicationTerms = assembleLoanApplicationTermsFrom(element, 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) {
|
public LoanScheduleModel assembleLoanScheduleFrom(final JsonElement element) {
|
||||||
|
|||||||
+45
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.integrationtests;
|
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.InterestRateFrequencyType.YEARS;
|
||||||
import static org.apache.fineract.integrationtests.BaseLoanIntegrationTest.RepaymentFrequencyType.DAYS;
|
import static org.apache.fineract.integrationtests.BaseLoanIntegrationTest.RepaymentFrequencyType.DAYS;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
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.CreditAllocationData;
|
||||||
import org.apache.fineract.client.models.CreditAllocationOrder;
|
import org.apache.fineract.client.models.CreditAllocationOrder;
|
||||||
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
|
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.GetLoansLoanIdLoanChargeData;
|
||||||
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod;
|
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod;
|
||||||
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
|
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,
|
private Long applyAndApproveLoanProgressiveAdvancedPaymentAllocationStrategyMonthlyRepayments(Long clientId, Long loanProductId,
|
||||||
Integer numberOfRepayments, String loanDisbursementDate, double amount) {
|
Integer numberOfRepayments, String loanDisbursementDate, double amount) {
|
||||||
LOG.info("------------------------------APPLY AND APPROVE LOAN ---------------------------------------");
|
LOG.info("------------------------------APPLY AND APPROVE LOAN ---------------------------------------");
|
||||||
|
|||||||
Reference in New Issue
Block a user