[#FINERACT-2422] standardize use of aging vs. ageing (#5289)

This commit is contained in:
Kengne-yvana
2026-01-08 10:43:21 -06:00
committed by GitHub
parent 4c1016d239
commit 61034e6041
71 changed files with 321 additions and 321 deletions
@@ -413,7 +413,7 @@
},
{
"default": null,
"name": "graceOnArrearsAgeing",
"name": "graceOnArrearsAging",
"type": [
"null",
"int"
@@ -389,7 +389,7 @@
},
{
"default": null,
"name": "graceOnArrearsAgeing",
"name": "graceOnArrearsAging",
"type": [
"null",
"int"
@@ -20,7 +20,7 @@ package org.apache.fineract.infrastructure.jobs.service;
public enum JobName {
UPDATE_LOAN_ARREARS_AGEING("Update Loan Arrears Ageing"), //
UPDATE_LOAN_ARREARS_AGING("Update Loan Arrears Aging"), //
APPLY_ANNUAL_FEE_FOR_SAVINGS("Apply Annual Fee For Savings"), //
APPLY_HOLIDAYS_TO_LOANS("Apply Holidays To Loans"), //
POST_INTEREST_FOR_SAVINGS("Post Interest For Savings"), //
@@ -182,7 +182,7 @@ public class LoanProductsRequestFactory {
.daysInYearType(DAYS_IN_YEAR_TYPE)//
.daysInMonthType(DAYS_IN_MONTH_TYPE)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -199,7 +199,7 @@ public class LoanProductsRequestFactory {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))//
.graceOnArrearsAging(true))//
.allowPartialPeriodInterestCalculation(true)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0)//
@@ -292,7 +292,7 @@ public class LoanProductsRequestFactory {
.daysInYearType(DAYS_IN_YEAR_TYPE)//
.daysInMonthType(DAYS_IN_MONTH_TYPE)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -309,7 +309,7 @@ public class LoanProductsRequestFactory {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))
.graceOnArrearsAging(true))
.allowPartialPeriodInterestCalculation(true)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0)//
@@ -400,7 +400,7 @@ public class LoanProductsRequestFactory {
.daysInYearType(DAYS_IN_YEAR_TYPE)//
.daysInMonthType(DAYS_IN_MONTH_TYPE)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -417,7 +417,7 @@ public class LoanProductsRequestFactory {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))
.graceOnArrearsAging(true))
.allowPartialPeriodInterestCalculation(true)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0)//
@@ -507,7 +507,7 @@ public class LoanProductsRequestFactory {
.daysInYearType(DAYS_IN_YEAR_TYPE)//
.daysInMonthType(DAYS_IN_MONTH_TYPE)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -523,7 +523,7 @@ public class LoanProductsRequestFactory {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))
.graceOnArrearsAging(true))
.outstandingLoanBalance(10000.0)//
.charges(charges)//
.accountingRule(LOAN_ACCOUNTING_RULE)//
@@ -620,7 +620,7 @@ public class LoanProductsRequestFactory {
.daysInYearType(DAYS_IN_YEAR_TYPE)//
.daysInMonthType(DAYS_IN_MONTH_TYPE)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -636,7 +636,7 @@ public class LoanProductsRequestFactory {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))
.graceOnArrearsAging(true))
.outstandingLoanBalance(10000.0)//
.charges(charges)//
.accountingRule(LOAN_ACCOUNTING_RULE)//
@@ -705,7 +705,7 @@ public class LoanProductsRequestFactory {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))//
.graceOnArrearsAging(true))//
.allowPartialPeriodInterestCalculation(false)//
.allowVariableInstallments(false)//
.amortizationType(AMORTIZATION_TYPE)//
@@ -849,7 +849,7 @@ public class LoanProductsRequestFactory {
.daysInYearType(DAYS_IN_YEAR_TYPE)//
.daysInMonthType(DAYS_IN_MONTH_TYPE)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -866,7 +866,7 @@ public class LoanProductsRequestFactory {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))//
.graceOnArrearsAging(true))//
.allowPartialPeriodInterestCalculation(true)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0)//
@@ -962,7 +962,7 @@ public class LoanProductsRequestFactory {
.daysInYearType(DAYS_IN_YEAR_TYPE)//
.daysInMonthType(DAYS_IN_MONTH_TYPE)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -979,7 +979,7 @@ public class LoanProductsRequestFactory {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))
.graceOnArrearsAging(true))
.allowPartialPeriodInterestCalculation(true)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0)//
@@ -1073,7 +1073,7 @@ public class LoanProductsRequestFactory {
.daysInYearType(DAYS_IN_YEAR_TYPE)//
.daysInMonthType(DAYS_IN_MONTH_TYPE)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -1090,7 +1090,7 @@ public class LoanProductsRequestFactory {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))//
.graceOnArrearsAging(true))//
.allowPartialPeriodInterestCalculation(false)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0)//
@@ -1199,7 +1199,7 @@ public class LoanProductsRequestFactory {
.daysInYearType(DAYS_IN_YEAR_TYPE)//
.daysInMonthType(DAYS_IN_MONTH_TYPE)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -1220,7 +1220,7 @@ public class LoanProductsRequestFactory {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))//
.graceOnArrearsAging(true))//
.allowPartialPeriodInterestCalculation(false)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0)//
@@ -1321,7 +1321,7 @@ public class LoanProductsRequestFactory {
.daysInYearType(DAYS_IN_YEAR_TYPE)//
.daysInMonthType(DAYS_IN_MONTH_TYPE)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -1338,7 +1338,7 @@ public class LoanProductsRequestFactory {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))//
.graceOnArrearsAging(true))//
.allowPartialPeriodInterestCalculation(true)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0)//
@@ -1451,7 +1451,7 @@ public class LoanProductsRequestFactory {
.daysInYearType(DAYS_IN_YEAR_TYPE)//
.daysInMonthType(DAYS_IN_MONTH_TYPE)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -1472,7 +1472,7 @@ public class LoanProductsRequestFactory {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))//
.graceOnArrearsAging(true))//
.allowPartialPeriodInterestCalculation(false)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0)//
@@ -1560,7 +1560,7 @@ public class LoanProductsRequestFactory {
.daysInYearType(DAYS_IN_YEAR_TYPE)//
.daysInMonthType(DAYS_IN_MONTH_TYPE)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -1577,7 +1577,7 @@ public class LoanProductsRequestFactory {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))//
.graceOnArrearsAging(true))//
.allowPartialPeriodInterestCalculation(true)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0)//
@@ -1698,7 +1698,7 @@ public class LoanProductsRequestFactory {
.daysInYearType(DAYS_IN_YEAR_TYPE_360)//
.daysInMonthType(DAYS_IN_MONTH_TYPE_30)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -1715,7 +1715,7 @@ public class LoanProductsRequestFactory {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))//
.graceOnArrearsAging(true))//
.allowPartialPeriodInterestCalculation(false)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0)//
@@ -119,7 +119,7 @@ public class LoanRequestFactory {
.amortizationType(DEFAULT_AMORTIZATION_TYPE)//
.transactionProcessingStrategyCode(DEFAULT_TRANSACTION_PROCESSING_STRATEGY_CODE)//
.dateFormat(DATE_FORMAT)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.maxOutstandingLoanBalance(new BigDecimal(10000));
}
@@ -143,7 +143,7 @@ public class LoanRequestFactory {
.amortizationType(DEFAULT_AMORTIZATION_TYPE)//
.transactionProcessingStrategyCode(DEFAULT_PROGRESSIVE_TRANSACTION_PROCESSING_STRATEGY_CODE)//
.dateFormat(DATE_FORMAT)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.maxOutstandingLoanBalance(new BigDecimal(10000));
}
@@ -172,7 +172,7 @@ public class LoanRequestFactory {
.amortizationType(DEFAULT_AMORTIZATION_TYPE)//
.isEqualAmortization(false)//
.transactionProcessingStrategyCode(DEFAULT_TRANSACTION_PROCESSING_STRATEGY_CODE)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.loanIdToClose(null)//
.isTopup(null)//
.maxOutstandingLoanBalance(10000L)//
@@ -4048,7 +4048,7 @@ public class LoanProductGlobalInitializerStep implements FineractGlobalInitializ
.inArrearsTolerance(10) //
.graceOnPrincipalPayment(1) //
.graceOnInterestPayment(1) //
.graceOnArrearsAgeing(3) //
.graceOnArrearsAging(3) //
.numberOfRepayments(6) //
.allowAttributeOverrides(new AllowAttributeOverrides() //
.amortizationType(true) //
@@ -4058,7 +4058,7 @@ public class LoanProductGlobalInitializerStep implements FineractGlobalInitializ
.inArrearsTolerance(true) //
.repaymentEvery(true) //
.graceOnPrincipalAndInterestPayment(true) //
.graceOnArrearsAgeing(true));
.graceOnArrearsAging(true));
final PostLoanProductsResponse responseWithOverrides = createLoanProductIdempotent(loanProductsRequestWithOverrides);
TestContext.INSTANCE.set(TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP1_WITH_OVERRIDES, responseWithOverrides);
@@ -4071,7 +4071,7 @@ public class LoanProductGlobalInitializerStep implements FineractGlobalInitializ
.inArrearsTolerance(10) //
.graceOnPrincipalPayment(1) //
.graceOnInterestPayment(1) //
.graceOnArrearsAgeing(3) //
.graceOnArrearsAging(3) //
.numberOfRepayments(6) //
.allowAttributeOverrides(new AllowAttributeOverrides() //
.amortizationType(false) //
@@ -4081,7 +4081,7 @@ public class LoanProductGlobalInitializerStep implements FineractGlobalInitializ
.inArrearsTolerance(false) //
.repaymentEvery(false) //
.graceOnPrincipalAndInterestPayment(false) //
.graceOnArrearsAgeing(false));
.graceOnArrearsAging(false));
final PostLoanProductsResponse responseNoOverrides = createLoanProductIdempotent(loanProductsRequestNoOverrides);
TestContext.INSTANCE.set(TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP1_NO_OVERRIDES, responseNoOverrides);
@@ -72,7 +72,7 @@ public class LoanOverrideFieldsStepDef extends AbstractStepDef {
case "inArrearsTolerance" -> loanDetails.getInArrearsTolerance();
case "graceOnPrincipalPayment" -> loanDetails.getGraceOnPrincipalPayment();
case "graceOnInterestPayment" -> loanDetails.getGraceOnInterestPayment();
case "graceOnArrearsAgeing" -> loanDetails.getGraceOnArrearsAgeing();
case "graceOnArrearsAging" -> loanDetails.getGraceOnArrearsAging();
default -> throw new IllegalArgumentException("Unknown override field: " + fieldName);
};
}
@@ -113,7 +113,7 @@ public class LoanOverrideFieldsStepDef extends AbstractStepDef {
case "inArrearsTolerance" -> request.inArrearsTolerance(isNull ? null : new BigDecimal(value));
case "graceOnInterestPayment" -> request.graceOnInterestPayment(isNull ? null : Integer.valueOf(value));
case "graceOnPrincipalPayment" -> request.graceOnPrincipalPayment(isNull ? null : Integer.valueOf(value));
case "graceOnArrearsAgeing" -> request.graceOnArrearsAgeing(isNull ? null : Integer.valueOf(value));
case "graceOnArrearsAging" -> request.graceOnArrearsAging(isNull ? null : Integer.valueOf(value));
default -> throw new IllegalArgumentException("Unknown override field: " + fieldName);
}
}
@@ -68,7 +68,7 @@ public class LoanReAgingStepDef extends AbstractStepDef {
PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
long loanId = loanResponse.getLoanId();
PostLoansLoanIdTransactionsRequest reAgingRequest = setReAgeingRequestProperties(//
PostLoansLoanIdTransactionsRequest reAgingRequest = setReAgingRequestProperties(//
LoanRequestFactory.defaultReAgingRequest(), //
table.row(0), //
table.row(1) //
@@ -84,7 +84,7 @@ public class LoanReAgingStepDef extends AbstractStepDef {
PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
String loanExternalId = loanResponse.getResourceExternalId();
PostLoansLoanIdTransactionsRequest reAgingRequest = setReAgeingRequestProperties(//
PostLoansLoanIdTransactionsRequest reAgingRequest = setReAgingRequestProperties(//
LoanRequestFactory.defaultReAgingRequest(), //
table.row(0), //
table.row(1) //
@@ -361,7 +361,7 @@ public class LoanReAgingStepDef extends AbstractStepDef {
return actualValues;
}
PostLoansLoanIdTransactionsRequest setReAgeingRequestProperties(PostLoansLoanIdTransactionsRequest request, List<String> headers,
PostLoansLoanIdTransactionsRequest setReAgingRequestProperties(PostLoansLoanIdTransactionsRequest request, List<String> headers,
List<String> values) {
for (int i = 0; i < headers.size(); i++) {
String header = headers.get(i).toLowerCase().trim().replaceAll(" ", "");
@@ -383,7 +383,7 @@ public class LoanReAgingStepDef extends AbstractStepDef {
PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
String loanExternalId = loanResponse.getResourceExternalId();
PostLoansLoanIdTransactionsRequest reAgingRequest = setReAgeingRequestProperties(//
PostLoansLoanIdTransactionsRequest reAgingRequest = setReAgingRequestProperties(//
LoanRequestFactory.defaultReAgingRequest(), //
table.row(0), //
table.row(1) //
@@ -399,7 +399,7 @@ public class LoanReAgingStepDef extends AbstractStepDef {
Assertions.assertNotNull(loanResponse);
final long loanId = loanResponse.getLoanId();
PostLoansLoanIdTransactionsRequest reAgingRequest = setReAgeingRequestProperties(//
PostLoansLoanIdTransactionsRequest reAgingRequest = setReAgingRequestProperties(//
LoanRequestFactory.defaultReAgingRequest(), //
table.row(0), //
table.row(1) //
@@ -678,10 +678,10 @@ public class LoanStepDef extends AbstractStepDef {
createFullyCustomizedLoanWithInterestRateFrequency(data.get(1));
}
@When("Admin creates a fully customized loan with graceOnArrearsAgeing and following data:")
public void createFullyCustomizedLoanWithGraceOnArrearsAgeing(final DataTable table) throws IOException {
@When("Admin creates a fully customized loan with graceOnArrearsAging and following data:")
public void createFullyCustomizedLoanWithGraceOnArrearsAging(final DataTable table) throws IOException {
final List<List<String>> data = table.asLists();
createFullyCustomizedLoanWithGraceOnArrearsAgeing(data.get(1));
createFullyCustomizedLoanWithGraceOnArrearsAging(data.get(1));
}
@When("Admin creates a fully customized loan with charges and following data:")
@@ -3617,7 +3617,7 @@ public class LoanStepDef extends AbstractStepDef {
eventCheckHelper.createLoanEventCheck(response);
}
public void createFullyCustomizedLoanWithGraceOnArrearsAgeing(final List<String> loanData) throws IOException {
public void createFullyCustomizedLoanWithGraceOnArrearsAging(final List<String> loanData) throws IOException {
final String loanProduct = loanData.get(0);
final String submitDate = loanData.get(1);
final String principal = loanData.get(2);
@@ -3634,7 +3634,7 @@ public class LoanStepDef extends AbstractStepDef {
final Integer graceOnInterestPayment = Integer.valueOf(loanData.get(13));
final Integer graceOnInterestCharged = Integer.valueOf(loanData.get(14));
final String transactionProcessingStrategyCode = loanData.get(15);
final String graceOnArrearsAgeingStr = loanData.get(16);
final String graceOnArrearsAgingStr = loanData.get(16);
final PostClientsResponse clientResponse = testContext().get(TestContextKey.CLIENT_CREATE_RESPONSE);
final Long clientId = clientResponse.getClientId();
@@ -3661,7 +3661,7 @@ public class LoanStepDef extends AbstractStepDef {
.valueOf(transactionProcessingStrategyCode);
final String transactionProcessingStrategyCodeValue = processingStrategyCode.getValue();
Integer graceOnArrearsAgeingValue = Integer.valueOf(graceOnArrearsAgeingStr);
Integer graceOnArrearsAgingValue = Integer.valueOf(graceOnArrearsAgingStr);
final PostLoansRequest loansRequest = loanRequestFactory//
.defaultLoansRequest(clientId)//
@@ -3682,7 +3682,7 @@ public class LoanStepDef extends AbstractStepDef {
.graceOnInterestPayment(graceOnInterestPayment)//
.graceOnInterestPayment(graceOnInterestCharged)//
.transactionProcessingStrategyCode(transactionProcessingStrategyCodeValue)//
.graceOnArrearsAgeing(graceOnArrearsAgeingValue);//
.graceOnArrearsAging(graceOnArrearsAgingValue);//
final PostLoansResponse response = ok(
() -> fineractClient.loans().calculateLoanScheduleOrSubmitLoanApplication(loansRequest, Map.of()));
@@ -2146,7 +2146,7 @@ Feature: LoanDelinquency
| 5 | RANGE_90 | 250.00 |
@TestRailId:C4140
Scenario: Verify that loan delinquent days are correct when graceOnArrearsAgeing is set on loan product level (value=3)
Scenario: Verify that loan delinquent days are correct when graceOnArrearsAging is set on loan product level (value=3)
When Admin sets the business date to "01 January 2025"
And Admin creates a client with random data
And Admin creates a fully customized loan with the following data:
@@ -2162,11 +2162,11 @@ Feature: LoanDelinquency
| RANGE_90 | 666.68 | 04 February 2025 | 100 | 103 |
@TestRailId:C4141
Scenario: Verify that loan delinquent days are correct when graceOnArrearsAgeing is overrided on loan level (value=5)
Scenario: Verify that loan delinquent days are correct when graceOnArrearsAging is overrided on loan level (value=5)
When Admin sets the business date to "01 January 2025"
And Admin creates a client with random data
And Admin creates a fully customized loan with graceOnArrearsAgeing and following data:
| LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy | graceOnArrearsAgeing |
And Admin creates a fully customized loan with graceOnArrearsAging and following data:
| LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy | graceOnArrearsAging |
| LP2_PROGRESSIVE_ADVANCED_PAYMENT_ALLOCATION_BUYDOWN_FEES | 01 January 2025 | 1000 | 0 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION | 5 |
And Admin successfully approves the loan on "01 January 2025" with "1000" amount and expected disbursement date on "01 January 2025"
And Admin successfully disburse the loan on "01 January 2025" with "1000" EUR transaction amount
@@ -10,11 +10,11 @@ Feature: LoanOverrideFields
| inArrearsTolerance | null |
| graceOnPrincipalPayment | null |
| graceOnInterestPayment | null |
| graceOnArrearsAgeing | null |
| graceOnArrearsAging | null |
Then LoanDetails has "inArrearsTolerance" field with value: "10"
Then LoanDetails has "graceOnPrincipalPayment" field with value: "1"
Then LoanDetails has "graceOnInterestPayment" field with value: "1"
Then LoanDetails has "graceOnArrearsAgeing" field with value: "3"
Then LoanDetails has "graceOnArrearsAging" field with value: "3"
@TestRailId:C4143
Scenario: Verify that all nullable fields ignore overrides when overrides not allowed
@@ -25,11 +25,11 @@ Feature: LoanOverrideFields
| inArrearsTolerance | 11 |
| graceOnPrincipalPayment | 2 |
| graceOnInterestPayment | 2 |
| graceOnArrearsAgeing | 4 |
| graceOnArrearsAging | 4 |
Then LoanDetails has "inArrearsTolerance" field with value: "10"
Then LoanDetails has "graceOnPrincipalPayment" field with value: "1"
Then LoanDetails has "graceOnInterestPayment" field with value: "1"
Then LoanDetails has "graceOnArrearsAgeing" field with value: "3"
Then LoanDetails has "graceOnArrearsAging" field with value: "3"
@TestRailId:C4144
Scenario: Verify that nullable fields default to product when override is allowed but not provided
@@ -40,11 +40,11 @@ Feature: LoanOverrideFields
| inArrearsTolerance | null |
| graceOnPrincipalPayment | null |
| graceOnInterestPayment | null |
| graceOnArrearsAgeing | null |
| graceOnArrearsAging | null |
Then LoanDetails has "inArrearsTolerance" field with value: "10"
Then LoanDetails has "graceOnPrincipalPayment" field with value: "1"
Then LoanDetails has "graceOnInterestPayment" field with value: "1"
Then LoanDetails has "graceOnArrearsAgeing" field with value: "3"
Then LoanDetails has "graceOnArrearsAging" field with value: "3"
@TestRailId:C4145
Scenario: Verify that nullable fields default to product when override is allowed and provided
@@ -55,8 +55,8 @@ Feature: LoanOverrideFields
| inArrearsTolerance | 11 |
| graceOnPrincipalPayment | 2 |
| graceOnInterestPayment | 2 |
| graceOnArrearsAgeing | 4 |
| graceOnArrearsAging | 4 |
Then LoanDetails has "inArrearsTolerance" field with value: "11"
Then LoanDetails has "graceOnPrincipalPayment" field with value: "2"
Then LoanDetails has "graceOnInterestPayment" field with value: "2"
Then LoanDetails has "graceOnArrearsAgeing" field with value: "4"
Then LoanDetails has "graceOnArrearsAging" field with value: "4"
@@ -518,7 +518,7 @@ Feature: LoanReAging
Then Loan is closed with zero outstanding balance and it's all installments have obligations met
@TestRailId:C3059 @AdvancedPaymentAllocation
Scenario: Verify Loan re-aging transaction - partial principal payment scenario + undo re-ageing
Scenario: Verify Loan re-aging transaction - partial principal payment scenario + undo re-aging
When Admin sets the business date to "01 January 2024"
When Admin creates a client with random data
When Admin set "LP2_DOWNPAYMENT_AUTO_ADVANCED_PAYMENT_ALLOCATION" loan product "DEFAULT" transaction type to "NEXT_INSTALLMENT" future installment allocation rule
@@ -113,8 +113,8 @@ public class LoanDelinquencyDomainServiceImpl implements LoanDelinquencyDomainSe
}
Integer graceDays = 0;
if (loan.getLoanProductRelatedDetail().getGraceOnArrearsAgeing() != null) {
graceDays = loan.getLoanProductRelatedDetail().getGraceOnArrearsAgeing();
if (loan.getLoanProductRelatedDetail().getGraceOnArrearsAging() != null) {
graceDays = loan.getLoanProductRelatedDetail().getGraceOnArrearsAging();
}
log.debug("Loan id {} with overdue since date {} and outstanding amount {}", loan.getId(), overdueSinceDate, outstandingAmount);
@@ -192,8 +192,8 @@ public class LoanDelinquencyDomainServiceImpl implements LoanDelinquencyDomainSe
}
Integer graceDays = 0;
if (loan.getLoanProductRelatedDetail().getGraceOnArrearsAgeing() != null) {
graceDays = loan.getLoanProductRelatedDetail().getGraceOnArrearsAgeing();
if (loan.getLoanProductRelatedDetail().getGraceOnArrearsAging() != null) {
graceDays = loan.getLoanProductRelatedDetail().getGraceOnArrearsAging();
}
log.debug("Loan id {} with overdue since date {} and outstanding amount {}", loan.getId(), overdueSinceDate, outstandingAmount);
@@ -128,7 +128,7 @@ public class LoanAccountData {
private Integer recurringMoratoriumOnPrincipalPeriods;
private Integer graceOnInterestPayment;
private Integer graceOnInterestCharged;
private Integer graceOnArrearsAgeing;
private Integer graceOnArrearsAging;
private LocalDate interestChargedFromDate;
private LocalDate expectedFirstRepaymentOnDate;
private Boolean syncDisbursementWithMeeting;
@@ -431,7 +431,7 @@ public class LoanAccountData {
.setGraceOnInterestCharged(product.getGraceOnInterestCharged()).setCharges(charges)
.setMultiDisburseLoan(product.getMultiDisburseLoan()).setCanDefineInstallmentAmount(product.isCanDefineInstallmentAmount())
.setMaxOutstandingLoanBalance(product.getOutstandingLoanBalance()).setProduct(product)
.setGraceOnArrearsAgeing(product.getGraceOnArrearsAgeing()).setOverdueCharges(product.overdueFeeCharges())
.setGraceOnArrearsAging(product.getGraceOnArrearsAging()).setOverdueCharges(product.overdueFeeCharges())
.setDaysInMonthType(product.getDaysInMonthType()).setDaysInYearType(product.getDaysInYearType())
.setInterestRecalculationEnabled(product.isInterestRecalculationEnabled())
.setInterestRecalculationData(product.toLoanInterestRecalculationData())
@@ -470,7 +470,7 @@ public class LoanAccountData {
final BigDecimal feeChargesDueAtDisbursementCharged, final Boolean syncDisbursementWithMeeting, final Integer loanCounter,
final Integer loanProductCounter, final Boolean multiDisburseLoan, Boolean canDefineInstallmentAmount,
final BigDecimal fixedEmiAmont, final BigDecimal outstandingLoanBalance, final Boolean inArrears,
final Integer graceOnArrearsAgeing, final Boolean isNPA, final EnumOptionData daysInMonthType,
final Integer graceOnArrearsAging, final Boolean isNPA, final EnumOptionData daysInMonthType,
final EnumOptionData daysInYearType, final boolean isInterestRecalculationEnabled,
final LoanInterestRecalculationData interestRecalculationData, final Boolean createStandingInstructionAtDisbursement,
final Boolean isVariableInstallmentsAllowed, Integer minimumGap, Integer maximumGap, final EnumOptionData subStatus,
@@ -517,7 +517,7 @@ public class LoanAccountData {
.setSyncDisbursementWithMeeting(syncDisbursementWithMeeting).setLoanCounter(loanCounter)
.setLoanProductCounter(loanProductCounter).setMultiDisburseLoan(multiDisburseLoan)
.setCanDefineInstallmentAmount(canDefineInstallmentAmount).setFixedEmiAmount(fixedEmiAmont)
.setMaxOutstandingLoanBalance(outstandingLoanBalance).setInArrears(inArrears).setGraceOnArrearsAgeing(graceOnArrearsAgeing)
.setMaxOutstandingLoanBalance(outstandingLoanBalance).setInArrears(inArrears).setGraceOnArrearsAging(graceOnArrearsAging)
.setIsNPA(isNPA).setDaysInMonthType(daysInMonthType).setDaysInYearType(daysInYearType)
.setInterestRecalculationEnabled(isInterestRecalculationEnabled).setInterestRecalculationData(interestRecalculationData)
.setCreateStandingInstructionAtDisbursement(createStandingInstructionAtDisbursement)
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.loanaccount.jobs.updateloanarrearsageing;
package org.apache.fineract.portfolio.loanaccount.jobs.updateloanarrearsaging;
import java.math.BigDecimal;
import java.sql.ResultSet;
@@ -44,7 +44,7 @@ import org.springframework.stereotype.Component;
@Slf4j
@Component
@RequiredArgsConstructor
public class LoanArrearsAgeingUpdateHandler {
public class LoanArrearsAgingUpdateHandler {
private final JdbcTemplate jdbcTemplate;
private final DatabaseSpecificSQLGenerator sqlGenerator;
@@ -61,10 +61,10 @@ public class LoanArrearsAgeingUpdateHandler {
}
}
public void updateLoanArrearsAgeingDetailsForAllLoans() {
public void updateLoanArrearsAgingDetailsForAllLoans() {
truncateLoanArrearsAgingDetails();
String insertSQLStatement = buildQueryForInsertAgeingDetails(Boolean.TRUE);
List<String> insertStatements = updateLoanArrearsAgeingDetailsWithOriginalScheduleForAllLoans();
String insertSQLStatement = buildQueryForInsertAgingDetails(Boolean.TRUE);
List<String> insertStatements = updateLoanArrearsAgingDetailsWithOriginalScheduleForAllLoans();
insertStatements.add(0, insertSQLStatement);
final int[] records = this.jdbcTemplate.batchUpdate(insertStatements.toArray(new String[0]));
if (log.isDebugEnabled()) {
@@ -72,14 +72,14 @@ public class LoanArrearsAgeingUpdateHandler {
for (int record : records) {
result += record;
}
log.debug("Records affected by updateLoanArrearsAgeingDetails: {}", result);
log.debug("Records affected by updateLoanArrearsAgingDetails: {}", result);
}
}
public void updateLoanArrearsAgeingDetails(List<Long> loanIdsForUpdate) {
public void updateLoanArrearsAgingDetails(List<Long> loanIdsForUpdate) {
deleteLoanArrearsAgingDetails(loanIdsForUpdate);
String insertSQLStatement = buildQueryForInsertAgeingDetails(Boolean.FALSE);
String insertSQLStatement = buildQueryForInsertAgingDetails(Boolean.FALSE);
List<Object[]> batch = new ArrayList<Object[]>();
if (!loanIdsForUpdate.isEmpty()) {
for (Long loanId : loanIdsForUpdate) {
@@ -89,7 +89,7 @@ public class LoanArrearsAgeingUpdateHandler {
}
final int[] recordsUpdatedWithoutOriginalSchedule = this.jdbcTemplate.batchUpdate(insertSQLStatement, batch);
int[] recordsUpdatedWithOriginalSchedule = new int[0];
List<String> insertStatements = updateLoanArrearsAgeingDetailsWithOriginalSchedule(loanIdsForUpdate);
List<String> insertStatements = updateLoanArrearsAgingDetailsWithOriginalSchedule(loanIdsForUpdate);
if (!insertStatements.isEmpty()) {
recordsUpdatedWithOriginalSchedule = this.jdbcTemplate.batchUpdate(insertStatements.toArray(new String[0]));
@@ -104,12 +104,12 @@ public class LoanArrearsAgeingUpdateHandler {
result += recordWithOriginalSchedule;
}
}
log.debug("Records affected by updateLoanArrearsAgeingDetails: {}", result);
log.debug("Records affected by updateLoanArrearsAgingDetails: {}", result);
}
}
private String buildQueryForInsertAgeingDetails(boolean isForAllLoans) {
private String buildQueryForInsertAgingDetails(boolean isForAllLoans) {
final StringBuilder insertSqlStatementBuilder = new StringBuilder(900);
final String principalOverdueCalculationSql = "SUM(COALESCE(mr.principal_amount, 0) - coalesce(mr.principal_completed_derived, 0) - coalesce(mr.principal_writtenoff_derived, 0))";
final String interestOverdueCalculationSql = "SUM(COALESCE(mr.interest_amount, 0) - coalesce(mr.interest_writtenoff_derived, 0) - coalesce(mr.interest_waived_derived, 0) - "
@@ -139,7 +139,7 @@ public class LoanArrearsAgeingUpdateHandler {
}
insertSqlStatementBuilder.append(" and mr.completed_derived is false ");
insertSqlStatementBuilder.append(" and mr.duedate < ")
.append(sqlGenerator.subDate(sqlGenerator.currentBusinessDate(), "COALESCE(ml.grace_on_arrears_ageing, 0)", "day"))
.append(sqlGenerator.subDate(sqlGenerator.currentBusinessDate(), "COALESCE(ml.grace_on_arrears_aging, 0)", "day"))
.append(" ");
insertSqlStatementBuilder
.append(" and (prd.arrears_based_on_original_schedule = false or prd.arrears_based_on_original_schedule is null) ");
@@ -147,7 +147,7 @@ public class LoanArrearsAgeingUpdateHandler {
return insertSqlStatementBuilder.toString();
}
private List<String> updateLoanArrearsAgeingDetailsWithOriginalSchedule(List<Long> loanIdsForUpdate) {
private List<String> updateLoanArrearsAgingDetailsWithOriginalSchedule(List<Long> loanIdsForUpdate) {
List<String> insertStatement = new ArrayList<>();
String sqlForLoanIdentifiers = buildQueryForLoanIdentifiersWithOriginalSchedule(Boolean.FALSE);
List<Object> loanIdsForQuery = new ArrayList<>();
@@ -166,7 +166,7 @@ public class LoanArrearsAgeingUpdateHandler {
return insertStatement;
}
private List<String> updateLoanArrearsAgeingDetailsWithOriginalScheduleForAllLoans() {
private List<String> updateLoanArrearsAgingDetailsWithOriginalScheduleForAllLoans() {
List<String> insertStatement = new ArrayList<>();
String sqlForLoanIdentifiers = buildQueryForLoanIdentifiersWithOriginalSchedule(Boolean.TRUE);
List<Long> loanIds = this.jdbcTemplate.queryForList(sqlForLoanIdentifiers, Long.class);
@@ -191,7 +191,7 @@ public class LoanArrearsAgeingUpdateHandler {
loanIdentifier.append(" and ml.id IN (?)");
}
loanIdentifier.append(" and mr.completed_derived is false and mr.duedate < ")
.append(sqlGenerator.subDate(sqlGenerator.currentBusinessDate(), "COALESCE(ml.grace_on_arrears_ageing, 0)", "day"))
.append(sqlGenerator.subDate(sqlGenerator.currentBusinessDate(), "COALESCE(ml.grace_on_arrears_aging, 0)", "day"))
.append(" group by ml.id");
return loanIdentifier.toString();
}
@@ -233,7 +233,7 @@ public class LoanArrearsAgeingUpdateHandler {
"mr.interest_amount as interestAmount, mr.fee_charges_amount as feeAmount, mr.penalty_charges_amount as penaltyAmount ");
scheduleDetail.append("from m_loan ml INNER JOIN m_loan_repayment_schedule_history mr on mr.loan_id = ml.id ");
scheduleDetail.append("where mr.duedate < "
+ sqlGenerator.subDate(sqlGenerator.currentBusinessDate(), "COALESCE(ml.grace_on_arrears_ageing, 0)", "day") + " and ");
+ sqlGenerator.subDate(sqlGenerator.currentBusinessDate(), "COALESCE(ml.grace_on_arrears_aging, 0)", "day") + " and ");
scheduleDetail.append("ml.id IN(:loanIds)").append(" and mr.version = (");
scheduleDetail.append("select max(lrs.version) from m_loan_repayment_schedule_history lrs where mr.loan_id = lrs.loan_id");
scheduleDetail.append(") order by ml.id,mr.duedate");
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.loanaccount.jobs.updateloanarrearsageing;
package org.apache.fineract.portfolio.loanaccount.jobs.updateloanarrearsaging;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.infrastructure.jobs.service.JobName;
@@ -32,27 +32,27 @@ import org.springframework.transaction.PlatformTransactionManager;
@Configuration
@RequiredArgsConstructor
public class UpdateLoanArrearsAgeingConfig {
public class UpdateLoanArrearsAgingConfig {
private final JobRepository jobRepository;
private final PlatformTransactionManager transactionManager;
private final LoanArrearsAgeingUpdateHandler updateLoanArrearsAgingService;
private final LoanArrearsAgingUpdateHandler updateLoanArrearsAgingService;
@Bean
protected Step updateLoanArrearsAgeingStep() {
return new StepBuilder(JobName.UPDATE_LOAN_ARREARS_AGEING.name(), jobRepository)
.tasklet(updateLoanArrearsAgeingTasklet(), transactionManager).build();
protected Step updateLoanArrearsAgingStep() {
return new StepBuilder(JobName.UPDATE_LOAN_ARREARS_AGING.name(), jobRepository)
.tasklet(updateLoanArrearsAgingTasklet(), transactionManager).build();
}
@Bean
public Job updateLoanArrearsAgeingJob() {
return new JobBuilder(JobName.UPDATE_LOAN_ARREARS_AGEING.name(), jobRepository).start(updateLoanArrearsAgeingStep())
public Job updateLoanArrearsAgingJob() {
return new JobBuilder(JobName.UPDATE_LOAN_ARREARS_AGING.name(), jobRepository).start(updateLoanArrearsAgingStep())
.incrementer(new RunIdIncrementer()).build();
}
@Bean
public UpdateLoanArrearsAgeingTasklet updateLoanArrearsAgeingTasklet() {
return new UpdateLoanArrearsAgeingTasklet(updateLoanArrearsAgingService);
public UpdateLoanArrearsAgingTasklet updateLoanArrearsAgingTasklet() {
return new UpdateLoanArrearsAgingTasklet(updateLoanArrearsAgingService);
}
}
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.loanaccount.jobs.updateloanarrearsageing;
package org.apache.fineract.portfolio.loanaccount.jobs.updateloanarrearsaging;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -27,13 +27,13 @@ import org.springframework.batch.repeat.RepeatStatus;
@Slf4j
@RequiredArgsConstructor
public class UpdateLoanArrearsAgeingTasklet implements Tasklet {
public class UpdateLoanArrearsAgingTasklet implements Tasklet {
private final LoanArrearsAgeingUpdateHandler loanArrearsAgeingUpdateHandler;
private final LoanArrearsAgingUpdateHandler loanArrearsAgingUpdateHandler;
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
loanArrearsAgeingUpdateHandler.updateLoanArrearsAgeingDetailsForAllLoans();
loanArrearsAgingUpdateHandler.updateLoanArrearsAgingDetailsForAllLoans();
return RepeatStatus.FINISHED;
}
@@ -134,7 +134,7 @@ public final class LoanApplicationTerms {
private LocalDate interestChargedFromDate;
private Money inArrearsTolerance;
private Integer graceOnArrearsAgeing;
private Integer graceOnArrearsAging;
// added
private LocalDate loanEndDate;
@@ -556,7 +556,7 @@ public final class LoanApplicationTerms {
final Integer recurringMoratoriumOnPrincipalPeriods, final Integer graceOnInterestPayment, final Integer graceOnInterestCharged,
final LocalDate interestChargedFromDate, final Money inArrearsTolerance, final boolean multiDisburseLoan,
final BigDecimal emiAmount, final List<DisbursementData> disbursementDatas, final BigDecimal maxOutstandingBalance,
final Integer graceOnArrearsAgeing, final DaysInMonthType daysInMonthType, final DaysInYearType daysInYearType,
final Integer graceOnArrearsAging, final DaysInMonthType daysInMonthType, final DaysInYearType daysInYearType,
final boolean isInterestRecalculationEnabled, final RecalculationFrequencyType recalculationFrequencyType,
final CalendarInstance restCalendarInstance,
final InterestRecalculationCompoundingMethod interestRecalculationCompoundingMethod,
@@ -589,7 +589,7 @@ public final class LoanApplicationTerms {
allowPartialPeriodInterestCalculation, principalMoney, expectedDisbursementDate, repaymentsStartingFromDate,
calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment, recurringMoratoriumOnPrincipalPeriods,
graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, inArrearsTolerance, multiDisburseLoan, emiAmount,
disbursementDatas, maxOutstandingBalance, graceOnArrearsAgeing, daysInMonthType, daysInYearType,
disbursementDatas, maxOutstandingBalance, graceOnArrearsAging, daysInMonthType, daysInYearType,
isInterestRecalculationEnabled, rescheduleStrategyMethod, interestRecalculationCompoundingMethod, restCalendarInstance,
recalculationFrequencyType, compoundingCalendarInstance, compoundingFrequencyType, principalThresholdForLastInstalment,
installmentAmountInMultiplesOf, preClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations,
@@ -664,7 +664,7 @@ public final class LoanApplicationTerms {
allowPartialPeriodInterestCalculation, principalMoney, expectedDisbursementDate, repaymentsStartingFromDate,
calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment, recurringMoratoriumOnPrincipalPeriods,
graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, inArrearsTolerance, multiDisburseLoan, emiAmount,
disbursementDatas, maxOutstandingBalance, loanProductRelatedDetail.getGraceOnArrearsAgeing(), daysInMonthType,
disbursementDatas, maxOutstandingBalance, loanProductRelatedDetail.getGraceOnArrearsAging(), daysInMonthType,
daysInYearType, isInterestRecalculationEnabled, rescheduleStrategyMethod, compoundingMethod, restCalendarInstance,
recalculationFrequencyType, compoundingCalendarInstance, compoundingFrequencyType, principalThresholdForLastInstalment,
installmentAmountInMultiplesOf, loanPreClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations,
@@ -694,7 +694,7 @@ public final class LoanApplicationTerms {
final Integer recurringMoratoriumOnPrincipalPeriods, final Integer interestPaymentGrace, final Integer interestChargingGrace,
final LocalDate interestChargedFromDate, final Money inArrearsTolerance, final boolean multiDisburseLoan,
final BigDecimal emiAmount, final List<DisbursementData> disbursementDatas, final BigDecimal maxOutstandingBalance,
final Integer graceOnArrearsAgeing, final DaysInMonthType daysInMonthType, final DaysInYearType daysInYearType,
final Integer graceOnArrearsAging, final DaysInMonthType daysInMonthType, final DaysInYearType daysInYearType,
final boolean isInterestRecalculationEnabled, final LoanRescheduleStrategyMethod rescheduleStrategyMethod,
final InterestRecalculationCompoundingMethod interestRecalculationCompoundingMethod,
final CalendarInstance restCalendarInstance, final RecalculationFrequencyType recalculationFrequencyType,
@@ -753,7 +753,7 @@ public final class LoanApplicationTerms {
this.actualFixedEmiAmount = emiAmount;
this.disbursementDatas = disbursementDatas;
this.maxOutstandingBalance = maxOutstandingBalance;
this.graceOnArrearsAgeing = graceOnArrearsAgeing;
this.graceOnArrearsAging = graceOnArrearsAging;
this.daysInMonthType = daysInMonthType;
this.daysInYearType = daysInYearType;
this.interestRecalculationEnabled = isInterestRecalculationEnabled;
@@ -1684,7 +1684,7 @@ public final class LoanApplicationTerms {
this.interestCalculationPeriodMethod, this.allowPartialPeriodInterestCalculation, this.repaymentEvery,
this.repaymentPeriodFrequencyType, this.numberOfRepayments, this.principalGrace, this.recurringMoratoriumOnPrincipalPeriods,
this.interestPaymentGrace, this.interestChargingGrace, this.amortizationMethod, this.inArrearsTolerance.getAmount(),
this.graceOnArrearsAgeing, this.daysInMonthType.getValue(), this.daysInYearType.getValue(),
this.graceOnArrearsAging, this.daysInMonthType.getValue(), this.daysInYearType.getValue(),
this.interestRecalculationEnabled, this.isEqualAmortization, this.isDownPaymentEnabled,
this.disbursedAmountPercentageForDownPayment, this.isAutoRepaymentForDownPaymentEnabled, this.loanScheduleType,
this.loanScheduleProcessingType, this.fixedLength, this.enableAccrualActivityPosting, this.supportedInterestRefundTypes,
@@ -26,11 +26,11 @@ import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanScheduleP
public interface LoanArrearsAgingService {
void updateLoanArrearsAgeingDetailsWithOriginalSchedule(Loan loan);
void updateLoanArrearsAgingDetailsWithOriginalSchedule(Loan loan);
Map<Long, List<LoanSchedulePeriodData>> getScheduleDate(String loanId);
void updateLoanArrearsAgeingDetails(Loan loan);
void updateLoanArrearsAgingDetails(Loan loan);
void createInsertStatements(List<String> insertStatement, Map<Long, List<LoanSchedulePeriodData>> scheduleDate,
boolean isInsertStatement);
@@ -98,7 +98,7 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService {
}
@Override
public void updateLoanArrearsAgeingDetailsWithOriginalSchedule(final Loan loan) {
public void updateLoanArrearsAgingDetailsWithOriginalSchedule(final Loan loan) {
int count = this.jdbcTemplate.queryForObject("select count(mla.loan_id) from m_loan_arrears_aging mla where mla.loan_id =?",
Integer.class, loan.getId());
List<String> updateStatement = new ArrayList<>();
@@ -125,7 +125,7 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService {
}
@Override
public void updateLoanArrearsAgeingDetails(final Loan loan) {
public void updateLoanArrearsAgingDetails(final Loan loan) {
if (loan != null) {
int count = this.jdbcTemplate.queryForObject("select count(mla.loan_id) from m_loan_arrears_aging mla where mla.loan_id =?",
Integer.class, loan.getId());
@@ -373,7 +373,7 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService {
"mr.interest_amount as interestAmount, mr.fee_charges_amount as feeAmount, mr.penalty_charges_amount as penaltyAmount ");
scheduleDetail.append("from m_loan ml INNER JOIN m_loan_repayment_schedule_history mr on mr.loan_id = ml.id ");
scheduleDetail.append("where mr.duedate < "
+ sqlGenerator.subDate(sqlGenerator.currentBusinessDate(), "COALESCE(ml.grace_on_arrears_ageing, 0)", "day") + " and ");
+ sqlGenerator.subDate(sqlGenerator.currentBusinessDate(), "COALESCE(ml.grace_on_arrears_aging, 0)", "day") + " and ");
scheduleDetail.append("ml.id IN(").append(loanIdsAsString).append(") and mr.version = (");
scheduleDetail.append("select max(lrs.version) from m_loan_repayment_schedule_history lrs where mr.loan_id = lrs.loan_id");
scheduleDetail.append(") order by ml.id,mr.duedate");
@@ -413,9 +413,9 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService {
private void handleArrearsForLoan(Loan loan) {
if (loan != null && loan.isOpen() && loan.isInterestBearingAndInterestRecalculationEnabled()
&& loan.loanProduct().isArrearsBasedOnOriginalSchedule()) {
updateLoanArrearsAgeingDetailsWithOriginalSchedule(loan);
updateLoanArrearsAgingDetailsWithOriginalSchedule(loan);
} else {
updateLoanArrearsAgeingDetails(loan);
updateLoanArrearsAgingDetails(loan);
}
}
@@ -528,7 +528,7 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService {
@Override
public void onBusinessEvent(LoanDisbursalBusinessEvent event) {
Loan loan = event.get();
updateLoanArrearsAgeingDetails(loan);
updateLoanArrearsAgingDetails(loan);
}
}
@@ -74,7 +74,7 @@ public interface LoanProductConstants {
String OUTSTANDING_LOAN_BALANCE_PARAMETER_NAME = "outstandingLoanBalance";
String ALLOW_FULL_TERM_FOR_TRANCHE_PARAM_NAME = "allowFullTermForTranche";
String GRACE_ON_ARREARS_AGEING_PARAMETER_NAME = "graceOnArrearsAgeing";
String GRACE_ON_ARREARS_AGING_PARAMETER_NAME = "graceOnArrearsAging";
String OVERDUE_DAYS_FOR_NPA_PARAMETER_NAME = "overdueDaysForNPA";
String MINIMUM_DAYS_BETWEEN_DISBURSAL_AND_FIRST_REPAYMENT = "minimumDaysBetweenDisbursalAndFirstRepayment";
String ACCOUNT_MOVES_OUT_OF_NPA_ONLY_ON_ARREARS_COMPLETION_PARAM_NAME = "accountMovesOutOfNPAOnlyOnArrearsCompletion";
@@ -169,7 +169,7 @@ public final class LoanProductsApiResourceSwagger {
@Schema(example = "90")
public Integer inArrearsTolerance;
@Schema(example = "3")
public Integer graceOnArrearsAgeing;
public Integer graceOnArrearsAging;
@Schema(example = "false")
public Boolean accountMovesOutOfNPAOnlyOnArrearsCompletion;
@Schema(example = "false")
@@ -352,7 +352,7 @@ public final class LoanProductsApiResourceSwagger {
@Schema(example = "true")
public boolean graceOnPrincipalAndInterestPayment;
@Schema(example = "true")
public boolean graceOnArrearsAgeing;
public boolean graceOnArrearsAging;
}
static final class RateData {
@@ -1672,7 +1672,7 @@ public final class LoanProductsApiResourceSwagger {
@Schema(example = "90")
public Integer inArrearsTolerance;
@Schema(example = "3")
public Integer graceOnArrearsAgeing;
public Integer graceOnArrearsAging;
@Schema(example = "false")
public Boolean accountMovesOutOfNPAOnlyOnArrearsCompletion;
@Schema(example = "false")
@@ -175,7 +175,7 @@ public class LoanConfigurationDetails implements ILoanConfigurationDetails {
}
@Override
public Integer getGraceOnArrearsAgeing() {
public Integer getGraceOnArrearsAging() {
return 0;
}
@@ -137,7 +137,7 @@ public class LoanProductData implements Serializable {
private final Integer recurringMoratoriumOnPrincipalPeriods;
private final Integer graceOnInterestPayment;
private final Integer graceOnInterestCharged;
private final Integer graceOnArrearsAgeing;
private final Integer graceOnArrearsAging;
private final Integer overdueDaysForNPA;
private final EnumOptionData daysInMonthType;
private final EnumOptionData daysInYearType;
@@ -314,7 +314,7 @@ public class LoanProductData implements Serializable {
final Integer recurringMoratoriumOnPrincipalPeriods = null;
final Integer graceOnInterestPayment = null;
final Integer graceOnInterestCharged = null;
final Integer graceOnArrearsAgeing = null;
final Integer graceOnArrearsAging = null;
final Integer overdueDaysForNPA = null;
final Collection<ChargeData> charges = null;
final Collection<LoanProductBorrowerCycleVariationData> principalVariations = new ArrayList<>(1);
@@ -394,7 +394,7 @@ public class LoanProductData implements Serializable {
includeInBorrowerCycle, useBorrowerCycle, startDate, closeDate, status, externalId, principalVariations,
interestRateVariations, numberOfRepaymentVariations, multiDisburseLoan, maxTrancheCount, outstandingLoanBalance,
disallowExpectedDisbursements, allowApprovedDisbursedAmountsOverApplied, overAppliedCalculationType, overAppliedNumber,
allowFullTermForTranche, graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType,
allowFullTermForTranche, graceOnArrearsAging, overdueDaysForNPA, daysInMonthType, daysInYearType,
isInterestRecalculationEnabled, interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment, holdGuaranteeFunds,
productGuaranteeData, principalThresholdForLastInstallment, accountMovesOutOfNPAOnlyOnArrearsCompletion,
canDefineInstallmentAmount, installmentAmountInMultiplesOf, loanProductConfigurableAttributes,
@@ -453,7 +453,7 @@ public class LoanProductData implements Serializable {
final Integer recurringMoratoriumOnPrincipalPeriods = null;
final Integer graceOnInterestPayment = null;
final Integer graceOnInterestCharged = null;
final Integer graceOnArrearsAgeing = null;
final Integer graceOnArrearsAging = null;
final Integer overdueDaysForNPA = null;
final Collection<ChargeData> charges = null;
@@ -535,7 +535,7 @@ public class LoanProductData implements Serializable {
includeInBorrowerCycle, useBorrowerCycle, startDate, closeDate, status, externalId, principalVariations,
interestRateVariations, numberOfRepaymentVariations, multiDisburseLoan, maxTrancheCount, outstandingLoanBalance,
disallowExpectedDisbursements, allowApprovedDisbursedAmountsOverApplied, overAppliedCalculationType, overAppliedNumber,
allowFullTermForTranche, graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType,
allowFullTermForTranche, graceOnArrearsAging, overdueDaysForNPA, daysInMonthType, daysInYearType,
isInterestRecalculationEnabled, interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment, holdGuaranteeFunds,
productGuaranteeData, principalThresholdForLastInstallment, accountMovesOutOfNPAOnlyOnArrearsCompletion,
canDefineInstallmentAmount, installmentAmountInMultiplesOf, loanProductConfigurableAttributes,
@@ -600,7 +600,7 @@ public class LoanProductData implements Serializable {
final Integer recurringMoratoriumOnPrincipalPeriods = null;
final Integer graceOnInterestPayment = null;
final Integer graceOnInterestCharged = null;
final Integer graceOnArrearsAgeing = null;
final Integer graceOnArrearsAging = null;
final Integer overdueDaysForNPA = null;
final Collection<ChargeData> charges = null;
@@ -683,7 +683,7 @@ public class LoanProductData implements Serializable {
includeInBorrowerCycle, useBorrowerCycle, startDate, closeDate, status, externalId, principalVariationsForBorrowerCycle,
interestRateVariationsForBorrowerCycle, numberOfRepaymentVariationsForBorrowerCycle, multiDisburseLoan, maxTrancheCount,
outstandingLoanBalance, disallowExpectedDisbursements, allowApprovedDisbursedAmountsOverApplied, overAppliedCalculationType,
overAppliedNumber, allowFullTermForTranche, graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType,
overAppliedNumber, allowFullTermForTranche, graceOnArrearsAging, overdueDaysForNPA, daysInMonthType, daysInYearType,
isInterestRecalculationEnabled, interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment, holdGuaranteeFunds,
productGuaranteeData, principalThresholdForLastInstallment, accountMovesOutOfNPAOnlyOnArrearsCompletion,
canDefineInstallmentAmount, installmentAmountInMultiplesOf, loanProductConfigurableAttributes,
@@ -742,7 +742,7 @@ public class LoanProductData implements Serializable {
final Integer recurringMoratoriumOnPrincipalPeriods = null;
final Integer graceOnInterestPayment = null;
final Integer graceOnInterestCharged = null;
final Integer graceOnArrearsAgeing = null;
final Integer graceOnArrearsAging = null;
final Integer overdueDaysForNPA = null;
final Collection<ChargeData> charges = null;
@@ -825,7 +825,7 @@ public class LoanProductData implements Serializable {
includeInBorrowerCycle, useBorrowerCycle, startDate, closeDate, status, externalId, principalVariationsForBorrowerCycle,
interestRateVariationsForBorrowerCycle, numberOfRepaymentVariationsForBorrowerCycle, multiDisburseLoan, maxTrancheCount,
outstandingLoanBalance, disallowExpectedDisbursements, allowApprovedDisbursedAmountsOverApplied, overAppliedCalculationType,
overAppliedNumber, allowFullTermForTranche, graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType,
overAppliedNumber, allowFullTermForTranche, graceOnArrearsAging, overdueDaysForNPA, daysInMonthType, daysInYearType,
isInterestRecalculationEnabled, interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment, holdGuaranteeFunds,
productGuaranteeData, principalThresholdForLastInstallment, accountMovesOutOfNPAOnlyOnArrearsCompletion,
canDefineInstallmentAmount, installmentAmountInMultiplesOf, loanProductConfigurableAttributes,
@@ -878,7 +878,7 @@ public class LoanProductData implements Serializable {
Collection<LoanProductBorrowerCycleVariationData> numberOfRepaymentVariations, Boolean multiDisburseLoan,
Integer maxTrancheCount, BigDecimal outstandingLoanBalance, final Boolean disallowExpectedDisbursements,
final Boolean allowApprovedDisbursedAmountsOverApplied, final String overAppliedCalculationType,
final Integer overAppliedNumber, final Boolean allowFullTermForTranche, final Integer graceOnArrearsAgeing,
final Integer overAppliedNumber, final Boolean allowFullTermForTranche, final Integer graceOnArrearsAging,
final Integer overdueDaysForNPA, final EnumOptionData daysInMonthType, final EnumOptionData daysInYearType,
final boolean isInterestRecalculationEnabled, final LoanProductInterestRecalculationData interestRecalculationData,
final Integer minimumDaysBetweenDisbursalAndFirstRepayment, boolean holdGuaranteeFunds,
@@ -1007,7 +1007,7 @@ public class LoanProductData implements Serializable {
this.overAppliedNumber = overAppliedNumber;
this.allowFullTermForTranche = allowFullTermForTranche;
this.graceOnArrearsAgeing = graceOnArrearsAgeing;
this.graceOnArrearsAging = graceOnArrearsAging;
this.overdueDaysForNPA = overdueDaysForNPA;
this.daysInMonthType = daysInMonthType;
this.daysInYearType = daysInYearType;
@@ -1210,7 +1210,7 @@ public class LoanProductData implements Serializable {
this.accountingMappingOptions = accountingMappingOptions;
this.accountingRuleOptions = accountingRuleOptions;
this.valueConditionTypeOptions = valueConditionTypeOptions;
this.graceOnArrearsAgeing = productData.graceOnArrearsAgeing;
this.graceOnArrearsAging = productData.graceOnArrearsAging;
this.overdueDaysForNPA = productData.overdueDaysForNPA;
this.daysInMonthType = productData.daysInMonthType;
@@ -58,7 +58,7 @@ public interface ILoanConfigurationDetails {
AmortizationMethod getAmortizationMethod();
Integer getGraceOnArrearsAgeing();
Integer getGraceOnArrearsAging();
Integer getDaysInMonthType();
@@ -262,7 +262,7 @@ public class LoanProduct extends AbstractPersistableCustom<Long> {
final boolean includeInBorrowerCycle, final LocalDate startDate, final LocalDate closeDate, final ExternalId externalId,
final boolean useBorrowerCycle, final Set<LoanProductBorrowerCycleVariations> loanProductBorrowerCycleVariations,
final boolean multiDisburseLoan, final Integer maxTrancheCount, final BigDecimal outstandingLoanBalance,
final Integer graceOnArrearsAgeing, final Integer overdueDaysForNPA, final DaysInMonthType daysInMonthType,
final Integer graceOnArrearsAging, final Integer overdueDaysForNPA, final DaysInMonthType daysInMonthType,
final DaysInYearType daysInYearType, final boolean isInterestRecalculationEnabled,
final LoanProductInterestRecalculationDetails productInterestRecalculationDetails,
final Integer minimumDaysBetweenDisbursalAndFirstRepayment, final boolean holdGuarantorFunds,
@@ -335,7 +335,7 @@ public class LoanProduct extends AbstractPersistableCustom<Long> {
interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod,
considerPartialPeriodInterest, repayEvery, repaymentFrequencyType, defaultNumberOfInstallments, graceOnPrincipalPayment,
recurringMoratoriumOnPrincipalPeriods, graceOnInterestPayment, graceOnInterestCharged, amortizationMethod,
inArrearsTolerance, graceOnArrearsAgeing, daysInMonthType.getValue(), daysInYearType.getValue(),
inArrearsTolerance, graceOnArrearsAging, daysInMonthType.getValue(), daysInYearType.getValue(),
isInterestRecalculationEnabled, isEqualAmortization, enableDownPayment, disbursedAmountPercentageForDownPayment,
enableAutoRepaymentForDownPayment, loanScheduleType, loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting,
supportedInterestRefundTypes, chargeOffBehaviour, isInterestRecognitionOnDisbursementDate, daysInYearCustomStrategy,
@@ -58,14 +58,14 @@ public class LoanProductConfigurableAttributes extends AbstractPersistableCustom
@Column(name = "moratorium")
private Boolean graceOnPrincipalAndInterestPayment;
@Column(name = "grace_on_arrears_ageing")
private Boolean graceOnArrearsAgeing;
@Column(name = "grace_on_arrears_aging")
private Boolean graceOnArrearsAging;
private static final String[] supportedLoanConfigurableAttributes = { LoanProductConstants.amortizationTypeParamName,
LoanProductConstants.interestTypeParamName, LoanProductConstants.transactionProcessingStrategyCodeParamName,
LoanProductConstants.interestCalculationPeriodTypeParamName, LoanProductConstants.inArrearsToleranceParamName,
LoanProductConstants.repaymentEveryParamName, LoanProductConstants.graceOnPrincipalAndInterestPaymentParamName,
LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME };
LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME };
public static LoanProductConfigurableAttributes createFrom(JsonCommand command) {
@@ -92,7 +92,7 @@ public class LoanProductConfigurableAttributes extends AbstractPersistableCustom
.getAsJsonPrimitive(LoanProductConstants.graceOnPrincipalAndInterestPaymentParamName).getAsBoolean();
final Boolean graceOnArrearsAging = command.parsedJson().getAsJsonObject()
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
.getAsJsonPrimitive(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME).getAsBoolean();
.getAsJsonPrimitive(LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME).getAsBoolean();
return new LoanProductConfigurableAttributes(amortization, interestMethod, transactionProcessingStrategy, interestCalcPeriod,
arrearsTolerance, repaymentEvery, graceOnPrincipalAndInterestPayment, graceOnArrearsAging);
@@ -122,7 +122,7 @@ public class LoanProductConfigurableAttributes extends AbstractPersistableCustom
this.amortizationType = amortization;
this.interestType = interestMethod;
this.inArrearsTolerance = arrearsTolerance;
this.graceOnArrearsAgeing = graceOnArrearsAging;
this.graceOnArrearsAging = graceOnArrearsAging;
this.interestCalculationPeriodType = interestCalcPeriod;
this.graceOnPrincipalAndInterestPayment = graceOnPrincipalAndInterestPayment;
this.repaymentEvery = repaymentEvery;
@@ -170,7 +170,7 @@ public class LoanProductConfigurableAttributes extends AbstractPersistableCustom
}
public Boolean getGraceOnArrearsAgingBoolean() {
return graceOnArrearsAgeing;
return graceOnArrearsAging;
}
public void setLoanProduct(LoanProduct loanProduct) {
@@ -205,8 +205,8 @@ public class LoanProductConfigurableAttributes extends AbstractPersistableCustom
this.graceOnPrincipalAndInterestPayment = graceOnPrincipalAndInterestPayment;
}
public void setGraceOnArrearsAgeing(Boolean graceOnArrearsAgeing) {
this.graceOnArrearsAgeing = graceOnArrearsAgeing;
public void setGraceOnArrearsAging(Boolean graceOnArrearsAging) {
this.graceOnArrearsAging = graceOnArrearsAging;
}
@Override
@@ -227,12 +227,12 @@ public class LoanProductConfigurableAttributes extends AbstractPersistableCustom
&& Objects.equals(interestCalculationPeriodType, that.interestCalculationPeriodType)
&& Objects.equals(inArrearsTolerance, that.inArrearsTolerance) && Objects.equals(repaymentEvery, that.repaymentEvery)
&& Objects.equals(graceOnPrincipalAndInterestPayment, that.graceOnPrincipalAndInterestPayment)
&& Objects.equals(graceOnArrearsAgeing, that.graceOnArrearsAgeing);
&& Objects.equals(graceOnArrearsAging, that.graceOnArrearsAging);
}
@Override
public int hashCode() {
return Objects.hash(loanProduct, amortizationType, interestType, transactionProcessingStrategyCode, interestCalculationPeriodType,
inArrearsTolerance, repaymentEvery, graceOnPrincipalAndInterestPayment, graceOnArrearsAgeing);
inArrearsTolerance, repaymentEvery, graceOnPrincipalAndInterestPayment, graceOnArrearsAging);
}
}
@@ -124,8 +124,8 @@ public class LoanProductRelatedDetail {
@Column(name = "arrearstolerance_amount", scale = 6, precision = 19)
private BigDecimal inArrearsTolerance;
@Column(name = "grace_on_arrears_ageing")
private Integer graceOnArrearsAgeing;
@Column(name = "grace_on_arrears_aging")
private Integer graceOnArrearsAging;
@Column(name = "days_in_month_enum", nullable = false)
private Integer daysInMonthType;
@@ -217,7 +217,7 @@ public class LoanProductRelatedDetail {
final Integer repaymentEvery, final PeriodFrequencyType repaymentPeriodFrequencyType, final Integer numberOfRepayments,
final Integer graceOnPrincipalPayment, final Integer recurringMoratoriumOnPrincipalPeriods,
final Integer graceOnInterestPayment, final Integer graceOnInterestCharged, final AmortizationMethod amortizationMethod,
final BigDecimal inArrearsTolerance, final Integer graceOnArrearsAgeing, final Integer daysInMonthType,
final BigDecimal inArrearsTolerance, final Integer graceOnArrearsAging, final Integer daysInMonthType,
final Integer daysInYearType, final boolean isInterestRecalculationEnabled, final boolean isEqualAmortization,
final boolean enableDownPayment, final BigDecimal disbursedAmountPercentageForDownPayment,
final boolean enableAutoRepaymentForDownPayment, final LoanScheduleType loanScheduleType,
@@ -236,7 +236,7 @@ public class LoanProductRelatedDetail {
nominalAnnualInterestRate, interestMethod, interestCalculationPeriodMethod, allowPartialPeriodInterestCalculation,
repaymentEvery, repaymentPeriodFrequencyType, numberOfRepayments, graceOnPrincipalPayment,
recurringMoratoriumOnPrincipalPeriods, graceOnInterestPayment, graceOnInterestCharged, amortizationMethod,
inArrearsTolerance, graceOnArrearsAgeing, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
inArrearsTolerance, graceOnArrearsAging, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
isEqualAmortization, enableDownPayment, disbursedAmountPercentageForDownPayment, enableAutoRepaymentForDownPayment,
loanScheduleType, loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes,
chargeOffBehaviour, interestRecognitionOnDisbursementDate, daysInYearCustomStrategy, enableIncomeCapitalization,
@@ -255,7 +255,7 @@ public class LoanProductRelatedDetail {
final Integer repayEvery, final PeriodFrequencyType repaymentFrequencyType, final Integer defaultNumberOfRepayments,
final Integer graceOnPrincipalPayment, final Integer recurringMoratoriumOnPrincipalPeriods,
final Integer graceOnInterestPayment, final Integer graceOnInterestCharged, final AmortizationMethod amortizationMethod,
final BigDecimal inArrearsTolerance, final Integer graceOnArrearsAgeing, final Integer daysInMonthType,
final BigDecimal inArrearsTolerance, final Integer graceOnArrearsAging, final Integer daysInMonthType,
final Integer daysInYearType, final boolean isInterestRecalculationEnabled, final boolean isEqualAmortization,
final boolean enableDownPayment, final BigDecimal disbursedAmountPercentageForDownPayment,
final boolean enableAutoRepaymentForDownPayment, final LoanScheduleType loanScheduleType,
@@ -290,7 +290,7 @@ public class LoanProductRelatedDetail {
} else {
this.inArrearsTolerance = inArrearsTolerance;
}
this.graceOnArrearsAgeing = graceOnArrearsAgeing;
this.graceOnArrearsAging = graceOnArrearsAging;
this.daysInMonthType = daysInMonthType;
this.daysInYearType = daysInYearType;
this.isInterestRecalculationEnabled = isInterestRecalculationEnabled;
@@ -872,7 +872,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
if (!paidBalancesFromTransactionDate.getOutstandingInterest().isZero()
|| !paidBalancesFromTransactionDate.getOutstandingPrincipal().isZero()) {
createRepaymentPeriodForEarlyRepaidAmountsDuringReAgeing(scheduleModel,
createRepaymentPeriodForEarlyRepaidAmountsDuringReAging(scheduleModel,
paidBalancesFromTransactionDate.getOutstandingPrincipal(), paidBalancesFromTransactionDate.getOutstandingInterest(),
false);
}
@@ -1827,7 +1827,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
EqualAmortizationValues feesPenaltiesEqualAmortizationValues) {
LocalDate originalMaturityDate = interestSchedule.getMaturityDate();
List<RepaymentPeriod> reAgedRepaymentPeriods = new ArrayList<>(reageParameter.getNumberOfInstallments());
OutstandingDetails reAgeingAmounts = precalculateReAgeEqualAmortizationAmount(interestSchedule, transactionDate, reageParameter);
OutstandingDetails reAgingAmounts = precalculateReAgeEqualAmortizationAmount(interestSchedule, transactionDate, reageParameter);
Money zero = interestSchedule.zero();
// calculate already paid balances from transaction date
@@ -1856,15 +1856,15 @@ public final class ProgressiveEMICalculator implements EMICalculator {
interestSchedule.getLastRepaymentPeriod().setNoUnrecognisedInterest(true);
if (!originalMaturityDate.isBefore(transactionDate)) {
createRepaymentPeriodForEarlyRepaidAmountsDuringReAgeing(interestSchedule,
createRepaymentPeriodForEarlyRepaidAmountsDuringReAging(interestSchedule,
paidBalancesFromTransactionDate.getOutstandingPrincipal(), paidBalancesFromTransactionDate.getOutstandingInterest(),
true);
}
updateModelForReageEqualAmortization(interestSchedule, reageParameter, reAgedRepaymentPeriods);
updateEMIForReAgeEqualAmortization(reAgedRepaymentPeriods, reAgeingAmounts.getOutstandingPrincipal(),
reAgeingAmounts.getOutstandingInterest(), feesPenaltiesOutstanding, feesPenaltiesEqualAmortizationValues,
updateEMIForReAgeEqualAmortization(reAgedRepaymentPeriods, reAgingAmounts.getOutstandingPrincipal(),
reAgingAmounts.getOutstandingInterest(), feesPenaltiesOutstanding, feesPenaltiesEqualAmortizationValues,
zero.getCurrency());
calculateOutstandingBalance(interestSchedule);
@@ -1898,7 +1898,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
}
}
private void createRepaymentPeriodForEarlyRepaidAmountsDuringReAgeing(final ProgressiveLoanInterestScheduleModel interestSchedule,
private void createRepaymentPeriodForEarlyRepaidAmountsDuringReAging(final ProgressiveLoanInterestScheduleModel interestSchedule,
final Money totalPaidPrincipal, final Money totalPaidInterest, final boolean isReAged) {
final RepaymentPeriod targetPeriod = interestSchedule.getLastRepaymentPeriod();
@@ -4277,7 +4277,7 @@ class ProgressiveEMICalculatorTest {
}
@Test
public void test_chargeBackOn2ndRP_ReAgeingOn1stRPsDueDate_EQUAL_AMORTIZATION_FULL_INTEREST() {
public void test_chargeBackOn2ndRP_ReAgingOn1stRPsDueDate_EQUAL_AMORTIZATION_FULL_INTEREST() {
ProgressiveLoanInterestScheduleModel interestSchedule = generateSchedule();
emiCalculator.payPrincipal(interestSchedule, LocalDate.of(2024, 1, 1), LocalDate.of(2024, 2, 1), LocalDate.of(2024, 2, 1),
@@ -4312,7 +4312,7 @@ class ProgressiveEMICalculatorTest {
}
@Test
public void test_chargeBackOn2ndRP_ReAgeingOn2stRPsDueDate_EQUAL_AMORTIZATION_FULL_INTEREST() {
public void test_chargeBackOn2ndRP_ReAgingOn2stRPsDueDate_EQUAL_AMORTIZATION_FULL_INTEREST() {
ProgressiveLoanInterestScheduleModel interestSchedule = generateSchedule();
emiCalculator.payPrincipal(interestSchedule, LocalDate.of(2024, 1, 1), LocalDate.of(2024, 2, 1), LocalDate.of(2024, 2, 1),
@@ -4347,7 +4347,7 @@ class ProgressiveEMICalculatorTest {
}
@Test
public void test_chargeBackOn2ndRP_ReAgeingDuring2stRP_EQUAL_AMORTIZATION_FULL_INTEREST() {
public void test_chargeBackOn2ndRP_ReAgingDuring2stRP_EQUAL_AMORTIZATION_FULL_INTEREST() {
ProgressiveLoanInterestScheduleModel interestSchedule = generateSchedule();
emiCalculator.payPrincipal(interestSchedule, LocalDate.of(2024, 1, 1), LocalDate.of(2024, 2, 1), LocalDate.of(2024, 2, 1),
@@ -21,19 +21,19 @@ package org.apache.fineract.cob.loan;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.jobs.updateloanarrearsageing.LoanArrearsAgeingUpdateHandler;
import org.apache.fineract.portfolio.loanaccount.jobs.updateloanarrearsaging.LoanArrearsAgingUpdateHandler;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class UpdateLoanArrearsAgingBusinessStep implements LoanCOBBusinessStep {
private final LoanArrearsAgeingUpdateHandler loanArrearsAgeingUpdateHandler;
private final LoanArrearsAgingUpdateHandler loanArrearsAgingUpdateHandler;
@Override
public Loan execute(Loan loan) {
Long loanId = loan.getId();
loanArrearsAgeingUpdateHandler.updateLoanArrearsAgeingDetails(Arrays.asList(loanId));
loanArrearsAgingUpdateHandler.updateLoanArrearsAgingDetails(Arrays.asList(loanId));
return loan;
}
@@ -211,8 +211,8 @@ import org.springframework.util.CollectionUtils;
+ "graceOnInterestPayment\n"
+ "Optional: Integer - represents the number of repayment periods that grace should apply to the interest component of a repayment period. Interest is still calculated but offset to later repayment periods.\n"
+ "graceOnInterestCharged\n" + "Optional: Integer - represents the number of repayment periods that should be interest-free.\n"
+ "graceOnArrearsAgeing\n"
+ "Optional: Integer - Used in Arrears calculation to only take into account loans that are more than graceOnArrearsAgeing days overdue.\n"
+ "graceOnArrearsAging\n"
+ "Optional: Integer - Used in Arrears calculation to only take into account loans that are more than graceOnArrearsAging days overdue.\n"
+ "interestChargedFromDate\n" + "Optional: Date - The date from with interest is to start being charged.\n"
+ "expectedDisbursementDate\n" + "The proposed disbursement date of the loan so a proposed repayment schedule can be provided.\n"
+ "submittedOnDate\n" + "The date the loan application was submitted by applicant.\n" + "linkAccountId\n"
@@ -552,7 +552,7 @@ public class LoansApiResource {
@Operation(summary = "Calculate loan repayment schedule | Submit a new Loan Application", description = "It calculates the loan repayment Schedule\n"
+ "Submits a new loan application\n"
+ "Mandatory Fields: clientId, productId, principal, loanTermFrequency, loanTermFrequencyType, loanType, numberOfRepayments, repaymentEvery, repaymentFrequencyType, interestRatePerPeriod, amortizationType, interestType, interestCalculationPeriodType, transactionProcessingStrategyCode, expectedDisbursementDate, submittedOnDate, loanType\n"
+ "Optional Fields: graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, linkAccountId, allowPartialPeriodInterestCalculation, fixedEmiAmount, maxOutstandingLoanBalance, disbursementData, graceOnArrearsAgeing, createStandingInstructionAtDisbursement (requires linkedAccountId if set to true)\n"
+ "Optional Fields: graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, linkAccountId, allowPartialPeriodInterestCalculation, fixedEmiAmount, maxOutstandingLoanBalance, disbursementData, graceOnArrearsAging, createStandingInstructionAtDisbursement (requires linkedAccountId if set to true)\n"
+ "Additional Mandatory Fields if interest recalculation is enabled for product and Rest frequency not same as repayment period: recalculationRestFrequencyDate\n"
+ "Additional Mandatory Fields if interest recalculation with interest/fee compounding is enabled for product and compounding frequency not same as repayment period: recalculationCompoundingFrequencyDate\n"
+ "Additional Mandatory Field if Entity-Datatable Check is enabled for the entity of type loan: datatables")
@@ -1227,7 +1227,7 @@ final class LoansApiResourceSwagger {
@Schema(example = "0")
public Integer graceOnInterestCharged;
@Schema(example = "3")
public Integer graceOnArrearsAgeing;
public Integer graceOnArrearsAging;
@Schema(example = "false")
public Boolean enableDownPayment;
@Schema(example = "0.000000")
@@ -1361,7 +1361,7 @@ final class LoansApiResourceSwagger {
@Schema(example = "1")
public Integer graceOnInterestPayment;
@Schema(example = "1")
public Integer graceOnArrearsAgeing;
public Integer graceOnArrearsAging;
@Schema(example = "10")
public BigDecimal inArrearsTolerance;
@Schema(example = "HORIZONTAL")
@@ -1542,7 +1542,7 @@ final class LoansApiResourceSwagger {
@Schema(example = "true")
public Boolean fraud;
@Schema(example = "1")
public Integer graceOnArrearsAgeing;
public Integer graceOnArrearsAging;
@Schema(example = "1")
public Long loanIdToClose;
@Schema(example = "true")
@@ -365,10 +365,10 @@ public class LoanScheduleAssembler {
final Boolean isInterestChargedFromDateSameAsDisbursalDateEnabled = this.configurationDomainService
.isInterestChargedFromDateSameAsDisbursementDate();
Integer graceOnArrearsAgeing = this.fromApiJsonHelper
.extractIntegerWithLocaleNamed(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME, element);
if (!allowOverridingGraceOnArrearsAging || graceOnArrearsAgeing == null) {
graceOnArrearsAgeing = loanProduct.getLoanProductRelatedDetail().getGraceOnArrearsAgeing();
Integer graceOnArrearsAging = this.fromApiJsonHelper
.extractIntegerWithLocaleNamed(LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME, element);
if (!allowOverridingGraceOnArrearsAging || graceOnArrearsAging == null) {
graceOnArrearsAging = loanProduct.getLoanProductRelatedDetail().getGraceOnArrearsAging();
}
// other
@@ -539,7 +539,7 @@ public class LoanScheduleAssembler {
allowPartialPeriodInterestCalculation, principalMoney, expectedDisbursementDate, repaymentsStartingFromDate,
calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment, recurringMoratoriumOnPrincipalPeriods,
graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, inArrearsToleranceMoney,
loanProduct.isMultiDisburseLoan(), emiAmount, disbursementDatas, maxOutstandingBalance, graceOnArrearsAgeing,
loanProduct.isMultiDisburseLoan(), emiAmount, disbursementDatas, maxOutstandingBalance, graceOnArrearsAging,
daysInMonthType, daysInYearType, isInterestRecalculationEnabled, recalculationFrequencyType, restCalendarInstance,
compoundingMethod, compoundingCalendarInstance, compoundingFrequencyType, principalThresholdForLastInstalment,
loanProduct.getLoanProductRelatedDetail().getInstallmentAmountInMultiplesOf(),
@@ -1243,7 +1243,7 @@ public class LoanScheduleAssembler {
.setInArrearsTolerance(loan.loanProduct().getLoanProductRelatedDetail().getInArrearsTolerance().getAmount());
}
if (!graceOnArrearsAging) {
productRelatedDetail.setGraceOnArrearsAgeing(loan.loanProduct().getLoanProductRelatedDetail().getGraceOnArrearsAgeing());
productRelatedDetail.setGraceOnArrearsAging(loan.loanProduct().getLoanProductRelatedDetail().getGraceOnArrearsAging());
}
if (!interestCalcPeriod) {
productRelatedDetail.setInterestCalculationPeriodMethod(
@@ -1413,12 +1413,12 @@ public class LoanScheduleAssembler {
loanProductRelatedDetail.setGraceOnInterestCharged(newValue);
}
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME,
loanProductRelatedDetail.getGraceOnArrearsAgeing())) {
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME);
changes.put(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME, newValue);
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME,
loanProductRelatedDetail.getGraceOnArrearsAging())) {
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME);
changes.put(LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME, newValue);
changes.put("locale", localeAsInput);
loanProductRelatedDetail.setGraceOnArrearsAgeing(newValue);
loanProductRelatedDetail.setGraceOnArrearsAging(newValue);
}
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.DAYS_IN_MONTH_TYPE_PARAMETER_NAME,
@@ -165,7 +165,7 @@ public final class LoanApplicationValidator {
LoanApiConstants.syncDisbursementWithMeetingParameterName, // optional
LoanApiConstants.linkAccountIdParameterName, LoanApiConstants.disbursementDataParameterName,
LoanApiConstants.fixedEmiAmountParameterName, LoanApiConstants.maxOutstandingBalanceParameterName,
LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME,
LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME,
LoanApiConstants.createStandingInstructionAtDisbursementParameterName, LoanApiConstants.isTopup, LoanApiConstants.loanIdToClose,
LoanApiConstants.datatables, LoanApiConstants.isEqualAmortizationParam, LoanProductConstants.RATES_PARAM_NAME,
LoanApiConstants.applicationId, // glim specific
@@ -500,9 +500,9 @@ public final class LoanApplicationValidator {
baseDataValidator.reset().parameter(LoanApiConstants.graceOnInterestChargedParameterName).value(graceOnInterestCharged)
.zeroOrPositiveAmount();
final Integer graceOnArrearsAgeing = this.fromApiJsonHelper
.extractIntegerWithLocaleNamed(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME, element);
baseDataValidator.reset().parameter(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME).value(graceOnArrearsAgeing)
final Integer graceOnArrearsAging = this.fromApiJsonHelper
.extractIntegerWithLocaleNamed(LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME, element);
baseDataValidator.reset().parameter(LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME).value(graceOnArrearsAging)
.zeroOrPositiveAmount();
if (this.fromApiJsonHelper.parameterExists(LoanApiConstants.interestChargedFromDateParameterName, element)) {
@@ -1219,10 +1219,10 @@ public final class LoanApplicationValidator {
.zeroOrPositiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME, element)) {
final Integer graceOnArrearsAgeing = this.fromApiJsonHelper
.extractIntegerWithLocaleNamed(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME, element);
baseDataValidator.reset().parameter(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME).value(graceOnArrearsAgeing)
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME, element)) {
final Integer graceOnArrearsAging = this.fromApiJsonHelper
.extractIntegerWithLocaleNamed(LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME, element);
baseDataValidator.reset().parameter(LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME).value(graceOnArrearsAging)
.zeroOrPositiveAmount();
}
@@ -67,7 +67,7 @@ public final class LoanScheduleValidator {
LoanApiConstants.chargesParameterName, LoanApiConstants.collateralParameterName,
LoanApiConstants.syncDisbursementWithMeetingParameterName, LoanApiConstants.linkAccountIdParameterName,
LoanApiConstants.disbursementDataParameterName, LoanApiConstants.fixedEmiAmountParameterName,
LoanApiConstants.maxOutstandingBalanceParameterName, LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME,
LoanApiConstants.maxOutstandingBalanceParameterName, LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME,
LoanApiConstants.createStandingInstructionAtDisbursementParameterName, LoanApiConstants.isFloatingInterestRateParameterName,
LoanApiConstants.interestRateDifferentialParameterName, LoanApiConstants.repaymentFrequencyNthDayTypeParameterName,
LoanApiConstants.repaymentFrequencyDayOfWeekTypeParameterName, LoanApiConstants.isTopup, LoanApiConstants.loanIdToClose,
@@ -197,8 +197,8 @@ public class LoanProductAssembler {
maxTrancheCount = command.integerValueOfParameterNamed(LoanProductConstants.MAX_TRANCHE_COUNT_PARAMETER_NAME);
}
final Integer graceOnArrearsAgeing = command
.integerValueOfParameterNamed(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME);
final Integer graceOnArrearsAging = command
.integerValueOfParameterNamed(LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME);
final Integer overdueDaysForNPA = command.integerValueOfParameterNamed(LoanProductConstants.OVERDUE_DAYS_FOR_NPA_PARAMETER_NAME);
@@ -342,7 +342,7 @@ public class LoanProductAssembler {
recurringMoratoriumOnPrincipalPeriods, graceOnInterestPayment, graceOnInterestCharged, amortizationMethod,
inArrearsTolerance, productCharges, accountingRuleType, includeInBorrowerCycle, startDate, closeDate, externalId,
useBorrowerCycle, loanProductBorrowerCycleVariations, multiDisburseLoan, maxTrancheCount, outstandingLoanBalance,
graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
graceOnArrearsAging, overdueDaysForNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
interestRecalculationSettings, minimumDaysBetweenDisbursalAndFirstRepayment, holdGuarantorFunds,
loanProductGuaranteeDetails, principalThresholdForLastInstallment, accountMovesOutOfNPAOnlyOnArrearsCompletion,
canDefineEmiAmount, installmentAmountInMultiplesOf, loanConfigurableAttributes, isLinkedToFloatingInterestRates,
@@ -248,12 +248,12 @@ public class LoanProductRelatedDetailUpdateUtil {
loanRepaymentScheduleDetail.setGraceOnInterestCharged(newValue);
}
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME,
loanRepaymentScheduleDetail.getGraceOnArrearsAgeing())) {
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME);
actualChanges.put(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME, newValue);
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME,
loanRepaymentScheduleDetail.getGraceOnArrearsAging())) {
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME);
actualChanges.put(LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME, newValue);
actualChanges.put("locale", localeAsInput);
loanRepaymentScheduleDetail.setGraceOnArrearsAgeing(newValue);
loanRepaymentScheduleDetail.setGraceOnArrearsAging(newValue);
}
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.DAYS_IN_MONTH_TYPE_PARAMETER_NAME,
@@ -357,12 +357,12 @@ public class LoanProductUpdateUtil {
}
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
.getAsJsonPrimitive(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME)
.getAsJsonPrimitive(LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME)
.getAsBoolean() != loanProduct.getLoanConfigurableAttributes().getGraceOnArrearsAgingBoolean()) {
loanProduct.getLoanConfigurableAttributes()
.setGraceOnArrearsAgeing(command.parsedJson().getAsJsonObject()
.setGraceOnArrearsAging(command.parsedJson().getAsJsonObject()
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
.getAsJsonPrimitive(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME).getAsBoolean());
.getAsJsonPrimitive(LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME).getAsBoolean());
}
} else {
loanProduct.setLoanConfigurableAttributes(LoanProductConfigurableAttributes.populateDefaultsForConfigurableAttributes());
@@ -793,7 +793,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
+ " l.closedon_date as closedOnDate, cbu.username as closedByUsername, cbu.firstname as closedByFirstname, cbu.lastname as closedByLastname, l.writtenoffon_date as writtenOffOnDate, "
+ " l.expected_firstrepaymenton_date as expectedFirstRepaymentOnDate, l.interest_calculated_from_date as interestChargedFromDate, l.maturedon_date as actualMaturityDate, l.expected_maturedon_date as expectedMaturityDate, "
+ " l.principal_amount_proposed as proposedPrincipal, l.principal_amount as principal, l.total_principal_derived as totalPrincipal, l.approved_principal as approvedPrincipal, l.net_disbursal_amount as netDisbursalAmount, l.arrearstolerance_amount as inArrearsTolerance, l.number_of_repayments as numberOfRepayments, l.repay_every as repaymentEvery,"
+ " l.grace_on_principal_periods as graceOnPrincipalPayment, l.recurring_moratorium_principal_periods as recurringMoratoriumOnPrincipalPeriods, l.grace_on_interest_periods as graceOnInterestPayment, l.grace_interest_free_periods as graceOnInterestCharged,l.grace_on_arrears_ageing as graceOnArrearsAgeing,"
+ " l.grace_on_principal_periods as graceOnPrincipalPayment, l.recurring_moratorium_principal_periods as recurringMoratoriumOnPrincipalPeriods, l.grace_on_interest_periods as graceOnInterestPayment, l.grace_interest_free_periods as graceOnInterestCharged,l.grace_on_arrears_aging as graceOnArrearsAging,"
+ " l.nominal_interest_rate_per_period as interestRatePerPeriod, l.annual_nominal_interest_rate as annualInterestRate, "
+ " l.repayment_period_frequency_enum as repaymentFrequencyType, l.interest_period_frequency_enum as interestRateFrequencyType, "
+ " l.fixed_length as fixedLength, "
@@ -1019,7 +1019,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
"recurringMoratoriumOnPrincipalPeriods");
final Integer graceOnInterestPayment = JdbcSupport.getIntegerDefaultToNullIfZero(rs, "graceOnInterestPayment");
final Integer graceOnInterestCharged = JdbcSupport.getIntegerDefaultToNullIfZero(rs, "graceOnInterestCharged");
final Integer graceOnArrearsAgeing = JdbcSupport.getIntegerDefaultToNullIfZero(rs, "graceOnArrearsAgeing");
final Integer graceOnArrearsAging = JdbcSupport.getIntegerDefaultToNullIfZero(rs, "graceOnArrearsAging");
final Integer termFrequency = JdbcSupport.getInteger(rs, "termFrequency");
final Integer termPeriodFrequencyTypeInt = JdbcSupport.getInteger(rs, "termPeriodFrequencyType");
@@ -1267,7 +1267,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
allowPartialPeriodInterestCalculation, expectedFirstRepaymentOnDate, graceOnPrincipalPayment,
recurringMoratoriumOnPrincipalPeriods, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate,
timeline, loanSummary, feeChargesDueAtDisbursementCharged, syncDisbursementWithMeeting, loanCounter, loanProductCounter,
multiDisburseLoan, canDefineInstallmentAmount, fixedEmiAmount, outstandingLoanBalance, inArrears, graceOnArrearsAgeing,
multiDisburseLoan, canDefineInstallmentAmount, fixedEmiAmount, outstandingLoanBalance, inArrears, graceOnArrearsAging,
isNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, interestRecalculationData,
createStandingInstructionAtDisbursement, isvariableInstallmentsAllowed, minimumGap, maximumGap, loanSubStatus,
canUseForTopup, isTopup, closureLoanId, closureLoanAccountNo, topupAmount, isEqualAmortization,
@@ -178,7 +178,7 @@ public class LoanProductsApiResource {
@Operation(summary = "Create a Loan Product", description = "Depending of the Accounting Rule (accountingRule) selected, additional fields with details of the appropriate Ledger Account identifiers would need to be passed in.\n"
+ "\n" + "Refer MifosX Accounting Specs Draft for more details regarding the significance of the selected accounting rule\n\n"
+ "Mandatory Fields: name, shortName, currencyCode, digitsAfterDecimal, inMultiplesOf, principal, numberOfRepayments, repaymentEvery, repaymentFrequencyType, interestRatePerPeriod, interestRateFrequencyType, amortizationType, interestType, interestCalculationPeriodType, transactionProcessingStrategyCode, accountingRule, isInterestRecalculationEnabled, daysInYearType, daysInMonthType\n\n"
+ "Optional Fields: inArrearsTolerance, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, graceOnArrearsAgeing, charges, paymentChannelToFundSourceMappings, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, chargeOffReasonToExpenseAccountMappings, includeInBorrowerCycle, useBorrowerCycle,principalVariationsForBorrowerCycle, numberOfRepaymentVariationsForBorrowerCycle, interestRateVariationsForBorrowerCycle, multiDisburseLoan,maxTrancheCount, outstandingLoanBalance,overdueDaysForNPA,holdGuaranteeFunds, principalThresholdForLastInstalment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf, allowAttributeOverrides, allowPartialPeriodInterestCalculation,dueDaysForRepaymentEvent,overDueDaysForRepaymentEvent,enableDownPayment,disbursedAmountPercentageDownPayment,enableAutoRepaymentForDownPayment,repaymentStartDateType,enableBuyDownFee\n\n"
+ "Optional Fields: inArrearsTolerance, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, graceOnArrearsAging, charges, paymentChannelToFundSourceMappings, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, chargeOffReasonToExpenseAccountMappings, includeInBorrowerCycle, useBorrowerCycle,principalVariationsForBorrowerCycle, numberOfRepaymentVariationsForBorrowerCycle, interestRateVariationsForBorrowerCycle, multiDisburseLoan,maxTrancheCount, outstandingLoanBalance,overdueDaysForNPA,holdGuaranteeFunds, principalThresholdForLastInstalment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf, allowAttributeOverrides, allowPartialPeriodInterestCalculation,dueDaysForRepaymentEvent,overDueDaysForRepaymentEvent,enableDownPayment,disbursedAmountPercentageDownPayment,enableAutoRepaymentForDownPayment,repaymentStartDateType,enableBuyDownFee\n\n"
+ "Additional Mandatory Fields for Cash(2) based accounting: fundSourceAccountId, loanPortfolioAccountId, interestOnLoanAccountId, incomeFromFeeAccountId, incomeFromPenaltyAccountId, writeOffAccountId, transfersInSuspenseAccountId, overpaymentLiabilityAccountId\n\n"
+ "Additional Mandatory Fields for periodic (3) and upfront (4)accrual accounting: fundSourceAccountId, loanPortfolioAccountId, interestOnLoanAccountId, incomeFromFeeAccountId, incomeFromPenaltyAccountId, writeOffAccountId, receivableInterestAccountId, receivableFeeAccountId, receivablePenaltyAccountId, transfersInSuspenseAccountId, overpaymentLiabilityAccountId\n\n"
+ "Additional Mandatory Fields if interest recalculation is enabled(true): interestRecalculationCompoundingMethod, rescheduleStrategyMethod, recalculationRestFrequencyType\n\n"
@@ -164,7 +164,7 @@ public final class LoanProductDataValidator {
LoanProductConstants.INTEREST_RATE_VARIATIONS_FOR_BORROWER_CYCLE_PARAMETER_NAME,
LoanProductConstants.NUMBER_OF_REPAYMENT_VARIATIONS_FOR_BORROWER_CYCLE_PARAMETER_NAME, LoanProductConstants.SHORT_NAME,
LoanProductConstants.MULTI_DISBURSE_LOAN_PARAMETER_NAME, LoanProductConstants.OUTSTANDING_LOAN_BALANCE_PARAMETER_NAME,
LoanProductConstants.MAX_TRANCHE_COUNT_PARAMETER_NAME, LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME,
LoanProductConstants.MAX_TRANCHE_COUNT_PARAMETER_NAME, LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME,
LoanProductConstants.OVERDUE_DAYS_FOR_NPA_PARAMETER_NAME, LoanProductConstants.IS_INTEREST_RECALCULATION_ENABLED_PARAMETER_NAME,
LoanProductConstants.DAYS_IN_YEAR_TYPE_PARAMETER_NAME, LoanProductConstants.DAYS_IN_MONTH_TYPE_PARAMETER_NAME,
LoanProductConstants.rescheduleStrategyMethodParameterName,
@@ -216,7 +216,7 @@ public final class LoanProductDataValidator {
LoanProductConstants.interestTypeParamName, LoanProductConstants.transactionProcessingStrategyCodeParamName,
LoanProductConstants.interestCalculationPeriodTypeParamName, LoanProductConstants.inArrearsToleranceParamName,
LoanProductConstants.repaymentEveryParamName, LoanProductConstants.graceOnPrincipalAndInterestPaymentParamName,
LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME };
LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME };
public static final String LOANPRODUCT = "loanproduct";
public static final String OVER_APPLIED_CALCULATION_TYPE = "overAppliedCalculationType";
public static final String OPENING_SQUARE_BRACKET = "[";
@@ -397,9 +397,9 @@ public final class LoanProductDataValidator {
final Integer graceOnInterestCharged = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(GRACE_ON_INTEREST_CHARGED, element);
baseDataValidator.reset().parameter(GRACE_ON_INTEREST_CHARGED).value(graceOnInterestCharged).zeroOrPositiveAmount();
final Integer graceOnArrearsAgeing = this.fromApiJsonHelper
.extractIntegerWithLocaleNamed(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME, element);
baseDataValidator.reset().parameter(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME).value(graceOnArrearsAgeing)
final Integer graceOnArrearsAging = this.fromApiJsonHelper
.extractIntegerWithLocaleNamed(LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME, element);
baseDataValidator.reset().parameter(LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME).value(graceOnArrearsAging)
.integerZeroOrGreater();
final Integer overdueDaysForNPA = this.fromApiJsonHelper
@@ -1472,10 +1472,10 @@ public final class LoanProductDataValidator {
baseDataValidator.reset().parameter(GRACE_ON_INTEREST_CHARGED).value(graceOnInterestCharged).zeroOrPositiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME, element)) {
final Integer graceOnArrearsAgeing = this.fromApiJsonHelper
.extractIntegerWithLocaleNamed(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME, element);
baseDataValidator.reset().parameter(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME).value(graceOnArrearsAgeing)
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME, element)) {
final Integer graceOnArrearsAging = this.fromApiJsonHelper
.extractIntegerWithLocaleNamed(LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME, element);
baseDataValidator.reset().parameter(LoanProductConstants.GRACE_ON_ARREARS_AGING_PARAMETER_NAME).value(graceOnArrearsAging)
.integerZeroOrGreater();
}
@@ -250,7 +250,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
+ "lp.annual_nominal_interest_rate as annualInterestRate, lp.interest_method_enum as interestMethod, lp.interest_calculated_in_period_enum as interestCalculationInPeriodMethod,lp.allow_partial_period_interest_calcualtion as allowPartialPeriodInterestCalculation, "
+ "lp.repay_every as repaidEvery, lp.repayment_period_frequency_enum as repaymentPeriodFrequency, lp.number_of_repayments as numberOfRepayments, lp.min_number_of_repayments as minNumberOfRepayments, lp.max_number_of_repayments as maxNumberOfRepayments, "
+ "lp.fixed_length as fixedLength, " + "lp.enable_accrual_activity_posting as enableAccrualActivityPosting, "
+ "lp.grace_on_principal_periods as graceOnPrincipalPayment, lp.recurring_moratorium_principal_periods as recurringMoratoriumOnPrincipalPeriods, lp.grace_on_interest_periods as graceOnInterestPayment, lp.grace_interest_free_periods as graceOnInterestCharged,lp.grace_on_arrears_ageing as graceOnArrearsAgeing,lp.overdue_days_for_npa as overdueDaysForNPA, "
+ "lp.grace_on_principal_periods as graceOnPrincipalPayment, lp.recurring_moratorium_principal_periods as recurringMoratoriumOnPrincipalPeriods, lp.grace_on_interest_periods as graceOnInterestPayment, lp.grace_interest_free_periods as graceOnInterestCharged,lp.grace_on_arrears_aging as graceOnArrearsAging,lp.overdue_days_for_npa as overdueDaysForNPA, "
+ "lp.min_days_between_disbursal_and_first_repayment As minimumDaysBetweenDisbursalAndFirstRepayment, "
+ "lp.amortization_method_enum as amortizationMethod, lp.arrearstolerance_amount as tolerance, "
+ "lp.accounting_type as accountingType, lp.include_in_borrower_cycle as includeInBorrowerCycle,lp.use_borrower_cycle as useBorrowerCycle, lp.start_date as startDate, lp.close_date as closeDate, "
@@ -284,7 +284,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
+ "curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, curr.display_symbol as currencyDisplaySymbol, lp.external_id as externalId, "
+ "lca.id as lcaId, lca.amortization_method_enum as amortizationBoolean, lca.interest_method_enum as interestMethodConfigBoolean, "
+ "lca.loan_transaction_strategy_code as transactionProcessingStrategyBoolean,lca.interest_calculated_in_period_enum as interestCalcPeriodBoolean, lca.arrearstolerance_amount as arrearsToleranceBoolean, "
+ "lca.repay_every as repaymentFrequencyBoolean, lca.moratorium as graceOnPrincipalAndInterestBoolean, lca.grace_on_arrears_ageing as graceOnArrearsAgingBoolean, "
+ "lca.repay_every as repaymentFrequencyBoolean, lca.moratorium as graceOnPrincipalAndInterestBoolean, lca.grace_on_arrears_aging as graceOnArrearsAgingBoolean, "
+ "lp.is_linked_to_floating_interest_rates as isLinkedToFloatingInterestRates, "
+ "lfr.floating_rates_id as floatingRateId, " + "fr.name as floatingRateName, "
+ "lfr.interest_rate_differential as interestRateDifferential, "
@@ -352,7 +352,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
"recurringMoratoriumOnPrincipalPeriods");
final Integer graceOnInterestPayment = JdbcSupport.getIntegerDefaultToNullIfZero(rs, "graceOnInterestPayment");
final Integer graceOnInterestCharged = JdbcSupport.getIntegerDefaultToNullIfZero(rs, "graceOnInterestCharged");
final Integer graceOnArrearsAgeing = JdbcSupport.getIntegerDefaultToNullIfZero(rs, "graceOnArrearsAgeing");
final Integer graceOnArrearsAging = JdbcSupport.getIntegerDefaultToNullIfZero(rs, "graceOnArrearsAging");
final Integer overdueDaysForNPA = JdbcSupport.getIntegerDefaultToNullIfZero(rs, "overdueDaysForNPA");
final Integer minimumDaysBetweenDisbursalAndFirstRepayment = JdbcSupport.getInteger(rs,
"minimumDaysBetweenDisbursalAndFirstRepayment");
@@ -518,12 +518,12 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
final boolean arrearsTolerance = rs.getBoolean("arrearsToleranceBoolean");
final boolean repaymentFrequency = rs.getBoolean("repaymentFrequencyBoolean");
final boolean graceOnPrincipalAndInterest = rs.getBoolean("graceOnPrincipalAndInterestBoolean");
final boolean graceOnArrearsAging = rs.getBoolean("graceOnArrearsAgingBoolean");
final boolean graceOnArrearsAgingValue = rs.getBoolean("graceOnArrearsAgingBoolean");
LoanProductConfigurableAttributes allowAttributeOverrides = null;
allowAttributeOverrides = new LoanProductConfigurableAttributes(amortization, interestMethod, transactionProcessingStrategy,
interestCalcPeriod, arrearsTolerance, repaymentFrequency, graceOnPrincipalAndInterest, graceOnArrearsAging);
interestCalcPeriod, arrearsTolerance, repaymentFrequency, graceOnPrincipalAndInterest, graceOnArrearsAgingValue);
final boolean holdGuaranteeFunds = rs.getBoolean("holdGuaranteeFunds");
LoanProductGuaranteeData loanProductGuaranteeData = null;
@@ -592,7 +592,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
principalVariationsForBorrowerCycle, interestRateVariationsForBorrowerCycle,
numberOfRepaymentVariationsForBorrowerCycle, multiDisburseLoan, maxTrancheCount, outstandingLoanBalance,
disallowExpectedDisbursements, allowApprovedDisbursedAmountsOverApplied, overAppliedCalculationType, overAppliedNumber,
allowFullTermForTranche, graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType,
allowFullTermForTranche, graceOnArrearsAging, overdueDaysForNPA, daysInMonthType, daysInYearType,
isInterestRecalculationEnabled, interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment,
holdGuaranteeFunds, loanProductGuaranteeData, principalThresholdForLastInstallment,
accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf,
@@ -198,7 +198,7 @@ public class SelfLoansApiResource {
+ "Additional Mandatory Fields if interest recalculation is enabled for product and Rest frequency not same as repayment period: recalculationRestFrequencyDate\n\n"
+ "Additional Mandatory Fields if interest recalculation with interest/fee compounding is enabled for product and compounding frequency not same as repayment period: recalculationCompoundingFrequencyDate\n\n"
+ "Additional Mandatory Field if Entity-Datatable Check is enabled for the entity of type loan: datatables\n\n"
+ "Optional Fields: graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, linkAccountId, allowPartialPeriodInterestCalculation, fixedEmiAmount, maxOutstandingLoanBalance, disbursementData, graceOnArrearsAgeing, createStandingInstructionAtDisbursement (requires linkedAccountId if set to true)\n\n"
+ "Optional Fields: graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, linkAccountId, allowPartialPeriodInterestCalculation, fixedEmiAmount, maxOutstandingLoanBalance, disbursementData, graceOnArrearsAging, createStandingInstructionAtDisbursement (requires linkedAccountId if set to true)\n\n"
+ "Showing request/response for 'Submit a new Loan Application'")
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = SelfLoansApiResourceSwagger.PostSelfLoansRequest.class)))
@ApiResponses({
@@ -84,8 +84,8 @@ import org.springframework.stereotype.Component;
+ "graceOnInterestPayment\n"
+ "Optional: Integer - represents the number of repayment periods that grace should apply to the interest component of a repayment period. Interest is still calculated but offset to later repayment periods.\n"
+ "graceOnInterestCharged\n" + "Optional: Integer - represents the number of repayment periods that should be interest-free.\n"
+ "graceOnArrearsAgeing\n"
+ "Optional: Integer - Used in Arrears calculation to only take into account loans that are more than graceOnArrearsAgeing days overdue.\n"
+ "graceOnArrearsAging\n"
+ "Optional: Integer - Used in Arrears calculation to only take into account loans that are more than graceOnArrearsAging days overdue.\n"
+ "overdueDaysForNPA\n"
+ "Optional: Integer - represents the maximum number of days a Loan may be overdue before being classified as a NPA (non performing asset)\n"
+ "accountMovesOutOfNPAOnlyOnArrearsCompletion\n"
@@ -2177,7 +2177,7 @@
<column defaultValueComputed="NULL" name="loan_product_counter" type="SMALLINT"/>
<column defaultValueComputed="NULL" name="fixed_emi_amount" type="DECIMAL(19, 6)"/>
<column defaultValueComputed="NULL" name="max_outstanding_loan_balance" type="DECIMAL(19, 6)"/>
<column defaultValueComputed="NULL" name="grace_on_arrears_ageing" type="SMALLINT"/>
<column defaultValueComputed="NULL" name="grace_on_arrears_aging" type="SMALLINT"/>
<column defaultValueBoolean="false" name="is_npa" type="boolean">
<constraints nullable="false"/>
</column>
@@ -3166,7 +3166,7 @@
</column>
<column defaultValueComputed="NULL" name="max_disbursals" type="INT"/>
<column defaultValueComputed="NULL" name="max_outstanding_loan_balance" type="DECIMAL(19, 6)"/>
<column defaultValueComputed="NULL" name="grace_on_arrears_ageing" type="SMALLINT"/>
<column defaultValueComputed="NULL" name="grace_on_arrears_aging" type="SMALLINT"/>
<column defaultValueComputed="NULL" name="overdue_days_for_npa" type="SMALLINT"/>
<column defaultValueNumeric="1" name="days_in_month_enum" type="SMALLINT">
<constraints nullable="false"/>
@@ -3240,7 +3240,7 @@
<column defaultValueBoolean="true" name="moratorium" type="boolean">
<constraints nullable="false"/>
</column>
<column defaultValueBoolean="true" name="grace_on_arrears_ageing" type="boolean">
<column defaultValueBoolean="true" name="grace_on_arrears_aging" type="boolean">
<constraints nullable="false"/>
</column>
</createTable>
@@ -554,14 +554,14 @@
</insert>
<insert tableName="job">
<column name="id" valueNumeric="2"/>
<column name="name" value="Update Loan Arrears Ageing"/>
<column name="display_name" value="Update Loan Arrears Ageing"/>
<column name="name" value="Update Loan Arrears Aging"/>
<column name="display_name" value="Update Loan Arrears Aging"/>
<column name="cron_expression" value="0 1 0 1/1 * ? *"/>
<column name="create_time" valueDate="${current_datetime}"/>
<column name="task_priority" valueNumeric="5"/>
<column name="group_name"/>
<column name="previous_run_start_time"/>
<column name="job_key" value="Update Loan Arrears AgeingJobDetail1 _ DEFAULT"/>
<column name="job_key" value="Update Loan Arrears AgingJobDetail1 _ DEFAULT"/>
<column name="initializing_errorlog"/>
<column name="is_active" valueBoolean="true"/>
<column name="currently_running" valueBoolean="false"/>
@@ -36,7 +36,7 @@
</update>
<update tableName="job">
<column name="short_name" value="LA_ARAG"/>
<where>name='Update Loan Arrears Ageing'</where>
<where>name='Update Loan Arrears Aging'</where>
</update>
<update tableName="job">
<column name="short_name" value="LA_PIAD"/>
@@ -376,7 +376,7 @@ CREATE TABLE IF NOT EXISTS `job` (
/*!40000 ALTER TABLE `job` DISABLE KEYS */;
INSERT INTO `job` (`id`, `name`, `display_name`, `cron_expression`, `create_time`, `task_priority`, `group_name`, `previous_run_start_time`, `next_run_time`, `job_key`, `initializing_errorlog`, `is_active`, `currently_running`, `updates_allowed`, `scheduler_group`, `is_misfired`) VALUES
(1, 'Update loan Summary', 'Update loan Summary', '0 0 22 1/1 * ? *', '2015-06-03 02:56:57', 5, NULL, NULL, '2017-02-24 22:00:00', 'Update loan SummaryJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(2, 'Update Loan Arrears Ageing', 'Update Loan Arrears Ageing', '0 1 0 1/1 * ? *', '2015-06-03 02:56:57', 5, NULL, NULL, '2017-02-25 00:01:00', 'Update Loan Arrears AgeingJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(2, 'Update Loan Arrears Aging', 'Update Loan Arrears Aging', '0 1 0 1/1 * ? *', '2015-06-03 02:56:57', 5, NULL, NULL, '2017-02-25 00:01:00', 'Update Loan Arrears AgingJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(3, 'Update Loan Paid In Advance', 'Update Loan Paid In Advance', '0 5 0 1/1 * ? *', '2015-06-03 02:56:57', 5, NULL, NULL, '2017-02-25 00:05:00', 'Update Loan Paid In AdvanceJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(4, 'Apply Annual Fee For Savings', 'Apply Annual Fee For Savings', '0 20 22 1/1 * ? *', '2015-06-03 02:56:57', 5, NULL, NULL, '2017-02-24 22:20:00', 'Apply Annual Fee For SavingsJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(5, 'Apply Holidays To Loans', 'Apply Holidays To Loans', '0 0 12 * * ?', '2015-06-03 02:56:57', 5, NULL, NULL, '2017-02-25 12:00:00', 'Apply Holidays To LoansJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
@@ -2246,7 +2246,7 @@ CREATE TABLE IF NOT EXISTS `m_loan` (
`loan_product_counter` SMALLINT DEFAULT NULL,
`fixed_emi_amount` decimal(19,6) DEFAULT NULL,
`max_outstanding_loan_balance` decimal(19,6) DEFAULT NULL,
`grace_on_arrears_ageing` SMALLINT DEFAULT NULL,
`grace_on_arrears_aging` SMALLINT DEFAULT NULL,
`is_npa` tinyint NOT NULL DEFAULT '0',
`total_recovered_derived` decimal(19,6) DEFAULT NULL,
`accrued_till` date DEFAULT NULL,
@@ -3951,7 +3951,7 @@ CREATE TABLE IF NOT EXISTS `m_product_loan` (
`allow_multiple_disbursals` tinyint NOT NULL DEFAULT '0',
`max_disbursals` INT DEFAULT NULL,
`max_outstanding_loan_balance` decimal(19,6) DEFAULT NULL,
`grace_on_arrears_ageing` SMALLINT DEFAULT NULL,
`grace_on_arrears_aging` SMALLINT DEFAULT NULL,
`overdue_days_for_npa` SMALLINT DEFAULT NULL,
`days_in_month_enum` SMALLINT NOT NULL DEFAULT '1',
`days_in_year_enum` SMALLINT NOT NULL DEFAULT '1',
@@ -4005,7 +4005,7 @@ CREATE TABLE IF NOT EXISTS `m_product_loan_configurable_attributes` (
`arrearstolerance_amount` TINYINT NOT NULL DEFAULT '1',
`repay_every` TINYINT NOT NULL DEFAULT '1',
`moratorium` TINYINT NOT NULL DEFAULT '1',
`grace_on_arrears_ageing` TINYINT NOT NULL DEFAULT '1',
`grace_on_arrears_aging` TINYINT NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
KEY `fk_m_product_loan_configurable_attributes_0001` (`loan_product_id`),
CONSTRAINT `fk_m_product_loan_configurable_attributes_0001` FOREIGN KEY (`loan_product_id`) REFERENCES `m_product_loan` (`id`)
@@ -453,7 +453,7 @@ CREATE TABLE IF NOT EXISTS `job` (
/*!40000 ALTER TABLE `job` DISABLE KEYS */;
INSERT INTO `job` (`id`, `name`, `display_name`, `cron_expression`, `create_time`, `task_priority`, `group_name`, `previous_run_start_time`, `next_run_time`, `job_key`, `initializing_errorlog`, `is_active`, `currently_running`, `updates_allowed`, `scheduler_group`, `is_misfired`) VALUES
(1, 'Update loan Summary', 'Update loan Summary', '0 0 22 1/1 * ? *', '2014-03-07 18:29:14', 5, NULL, '2014-06-11 09:30:00', '2017-02-24 22:00:00', 'Update loan SummaryJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(2, 'Update Loan Arrears Ageing', 'Update Loan Arrears Ageing', '0 1 0 1/1 * ? *', '2014-03-07 18:29:14', 5, NULL, NULL, '2017-02-25 00:01:00', 'Update Loan Arrears AgeingJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(2, 'Update Loan Arrears Aging', 'Update Loan Arrears Aging', '0 1 0 1/1 * ? *', '2014-03-07 18:29:14', 5, NULL, NULL, '2017-02-25 00:01:00', 'Update Loan Arrears AgingJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(3, 'Update Loan Paid In Advance', 'Update Loan Paid In Advance', '0 5 0 1/1 * ? *', '2014-03-07 18:29:14', 5, NULL, NULL, '2017-02-25 00:05:00', 'Update Loan Paid In AdvanceJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(4, 'Apply Annual Fee For Savings', 'Apply Annual Fee For Savings', '0 20 22 1/1 * ? *', '2014-03-07 18:29:14', 5, NULL, '2014-06-11 09:50:00', '2017-02-24 22:20:00', 'Apply Annual Fee For SavingsJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(5, 'Apply Holidays To Loans', 'Apply Holidays To Loans', '0 0 12 * * ?', '2014-03-07 18:29:14', 5, NULL, '2014-03-24 12:00:04', '2017-02-25 12:00:00', 'Apply Holidays To LoansJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
@@ -2386,7 +2386,7 @@ CREATE TABLE IF NOT EXISTS `m_loan` (
`loan_product_counter` SMALLINT DEFAULT NULL,
`fixed_emi_amount` decimal(19,6) DEFAULT NULL,
`max_outstanding_loan_balance` decimal(19,6) DEFAULT NULL,
`grace_on_arrears_ageing` SMALLINT DEFAULT NULL,
`grace_on_arrears_aging` SMALLINT DEFAULT NULL,
`is_npa` tinyint NOT NULL DEFAULT '0',
`total_recovered_derived` decimal(19,6) DEFAULT NULL,
`accrued_till` date DEFAULT NULL,
@@ -2434,7 +2434,7 @@ CREATE TABLE IF NOT EXISTS `m_loan` (
-- Dumping data for table mifostenant-reference.m_loan: ~1 rows (approximately)
/*!40000 ALTER TABLE `m_loan` DISABLE KEYS */;
INSERT INTO `m_loan` (`id`, `account_no`, `external_id`, `client_id`, `group_id`, `product_id`, `fund_id`, `loan_officer_id`, `loanpurpose_cv_id`, `loan_status_id`, `loan_type_enum`, `currency_code`, `currency_digits`, `currency_multiplesof`, `principal_amount_proposed`, `principal_amount`, `approved_principal`, `arrearstolerance_amount`, `is_floating_interest_rate`, `interest_rate_differential`, `nominal_interest_rate_per_period`, `interest_period_frequency_enum`, `annual_nominal_interest_rate`, `interest_method_enum`, `interest_calculated_in_period_enum`, `allow_partial_period_interest_calcualtion`, `term_frequency`, `term_period_frequency_enum`, `repay_every`, `repayment_period_frequency_enum`, `number_of_repayments`, `grace_on_principal_periods`, `recurring_moratorium_principal_periods`, `grace_on_interest_periods`, `grace_interest_free_periods`, `amortization_method_enum`, `submittedon_date`, `submittedon_userid`, `approvedon_date`, `approvedon_userid`, `expected_disbursedon_date`, `expected_firstrepaymenton_date`, `interest_calculated_from_date`, `disbursedon_date`, `disbursedon_userid`, `expected_maturedon_date`, `maturedon_date`, `closedon_date`, `closedon_userid`, `total_charges_due_at_disbursement_derived`, `principal_disbursed_derived`, `principal_repaid_derived`, `principal_writtenoff_derived`, `principal_outstanding_derived`, `interest_charged_derived`, `interest_repaid_derived`, `interest_waived_derived`, `interest_writtenoff_derived`, `interest_outstanding_derived`, `fee_charges_charged_derived`, `fee_charges_repaid_derived`, `fee_charges_waived_derived`, `fee_charges_writtenoff_derived`, `fee_charges_outstanding_derived`, `penalty_charges_charged_derived`, `penalty_charges_repaid_derived`, `penalty_charges_waived_derived`, `penalty_charges_writtenoff_derived`, `penalty_charges_outstanding_derived`, `total_expected_repayment_derived`, `total_repayment_derived`, `total_expected_costofloan_derived`, `total_costofloan_derived`, `total_waived_derived`, `total_writtenoff_derived`, `total_outstanding_derived`, `total_overpaid_derived`, `rejectedon_date`, `rejectedon_userid`, `rescheduledon_date`, `rescheduledon_userid`, `withdrawnon_date`, `withdrawnon_userid`, `writtenoffon_date`, `loan_transaction_strategy_id`, `sync_disbursement_with_meeting`, `loan_counter`, `loan_product_counter`, `fixed_emi_amount`, `max_outstanding_loan_balance`, `grace_on_arrears_ageing`, `is_npa`, `total_recovered_derived`, `accrued_till`, `interest_recalcualated_on`, `days_in_month_enum`, `days_in_year_enum`, `interest_recalculation_enabled`, `guarantee_amount_derived`, `create_standing_instruction_at_disbursement`, `version`, `writeoff_reason_cv_id`, `loan_sub_status_id`, `is_topup`) VALUES
INSERT INTO `m_loan` (`id`, `account_no`, `external_id`, `client_id`, `group_id`, `product_id`, `fund_id`, `loan_officer_id`, `loanpurpose_cv_id`, `loan_status_id`, `loan_type_enum`, `currency_code`, `currency_digits`, `currency_multiplesof`, `principal_amount_proposed`, `principal_amount`, `approved_principal`, `arrearstolerance_amount`, `is_floating_interest_rate`, `interest_rate_differential`, `nominal_interest_rate_per_period`, `interest_period_frequency_enum`, `annual_nominal_interest_rate`, `interest_method_enum`, `interest_calculated_in_period_enum`, `allow_partial_period_interest_calcualtion`, `term_frequency`, `term_period_frequency_enum`, `repay_every`, `repayment_period_frequency_enum`, `number_of_repayments`, `grace_on_principal_periods`, `recurring_moratorium_principal_periods`, `grace_on_interest_periods`, `grace_interest_free_periods`, `amortization_method_enum`, `submittedon_date`, `submittedon_userid`, `approvedon_date`, `approvedon_userid`, `expected_disbursedon_date`, `expected_firstrepaymenton_date`, `interest_calculated_from_date`, `disbursedon_date`, `disbursedon_userid`, `expected_maturedon_date`, `maturedon_date`, `closedon_date`, `closedon_userid`, `total_charges_due_at_disbursement_derived`, `principal_disbursed_derived`, `principal_repaid_derived`, `principal_writtenoff_derived`, `principal_outstanding_derived`, `interest_charged_derived`, `interest_repaid_derived`, `interest_waived_derived`, `interest_writtenoff_derived`, `interest_outstanding_derived`, `fee_charges_charged_derived`, `fee_charges_repaid_derived`, `fee_charges_waived_derived`, `fee_charges_writtenoff_derived`, `fee_charges_outstanding_derived`, `penalty_charges_charged_derived`, `penalty_charges_repaid_derived`, `penalty_charges_waived_derived`, `penalty_charges_writtenoff_derived`, `penalty_charges_outstanding_derived`, `total_expected_repayment_derived`, `total_repayment_derived`, `total_expected_costofloan_derived`, `total_costofloan_derived`, `total_waived_derived`, `total_writtenoff_derived`, `total_outstanding_derived`, `total_overpaid_derived`, `rejectedon_date`, `rejectedon_userid`, `rescheduledon_date`, `rescheduledon_userid`, `withdrawnon_date`, `withdrawnon_userid`, `writtenoffon_date`, `loan_transaction_strategy_id`, `sync_disbursement_with_meeting`, `loan_counter`, `loan_product_counter`, `fixed_emi_amount`, `max_outstanding_loan_balance`, `grace_on_arrears_aging`, `is_npa`, `total_recovered_derived`, `accrued_till`, `interest_recalcualated_on`, `days_in_month_enum`, `days_in_year_enum`, `interest_recalculation_enabled`, `guarantee_amount_derived`, `create_standing_instruction_at_disbursement`, `version`, `writeoff_reason_cv_id`, `loan_sub_status_id`, `is_topup`) VALUES
(1, '000000001', NULL, 8, NULL, 1, 1, NULL, NULL, 200, 1, 'USD', 2, 0, 10000.000000, 10000.000000, 10000.000000, NULL, b'0', 0.000000, 26.000000, 3, 26.000000, 1, 1, 0, 25, 1, 1, 1, 25, NULL, NULL, NULL, NULL, 1, '2014-06-02', 1, '2014-06-11', 1, '2014-06-16', NULL, NULL, NULL, NULL, '2014-12-08', '2014-12-08', NULL, NULL, 500.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, 1, 1, 0, NULL, NULL, 1, NULL, NULL, 0);
/*!40000 ALTER TABLE `m_loan` ENABLE KEYS */;
@@ -4196,7 +4196,7 @@ CREATE TABLE IF NOT EXISTS `m_product_loan` (
`allow_multiple_disbursals` tinyint NOT NULL DEFAULT '0',
`max_disbursals` INT DEFAULT NULL,
`max_outstanding_loan_balance` decimal(19,6) DEFAULT NULL,
`grace_on_arrears_ageing` SMALLINT DEFAULT NULL,
`grace_on_arrears_aging` SMALLINT DEFAULT NULL,
`overdue_days_for_npa` SMALLINT DEFAULT NULL,
`days_in_month_enum` SMALLINT NOT NULL DEFAULT '1',
`days_in_year_enum` SMALLINT NOT NULL DEFAULT '1',
@@ -4219,7 +4219,7 @@ CREATE TABLE IF NOT EXISTS `m_product_loan` (
-- Dumping data for table mifostenant-reference.m_product_loan: ~1 rows (approximately)
/*!40000 ALTER TABLE `m_product_loan` DISABLE KEYS */;
INSERT INTO `m_product_loan` (`id`, `short_name`, `currency_code`, `currency_digits`, `currency_multiplesof`, `principal_amount`, `min_principal_amount`, `max_principal_amount`, `arrearstolerance_amount`, `name`, `description`, `fund_id`, `is_linked_to_floating_interest_rates`, `allow_variabe_installments`, `nominal_interest_rate_per_period`, `min_nominal_interest_rate_per_period`, `max_nominal_interest_rate_per_period`, `interest_period_frequency_enum`, `annual_nominal_interest_rate`, `interest_method_enum`, `interest_calculated_in_period_enum`, `allow_partial_period_interest_calcualtion`, `repay_every`, `repayment_period_frequency_enum`, `number_of_repayments`, `min_number_of_repayments`, `max_number_of_repayments`, `grace_on_principal_periods`, `recurring_moratorium_principal_periods`, `grace_on_interest_periods`, `grace_interest_free_periods`, `amortization_method_enum`, `accounting_type`, `loan_transaction_strategy_id`, `external_id`, `include_in_borrower_cycle`, `use_borrower_cycle`, `start_date`, `close_date`, `allow_multiple_disbursals`, `max_disbursals`, `max_outstanding_loan_balance`, `grace_on_arrears_ageing`, `overdue_days_for_npa`, `days_in_month_enum`, `days_in_year_enum`, `interest_recalculation_enabled`, `min_days_between_disbursal_and_first_repayment`, `hold_guarantee_funds`, `principal_threshold_for_last_installment`, `account_moves_out_of_npa_only_on_arrears_completion`, `can_define_fixed_emi_amount`, `instalment_amount_in_multiples_of`, `can_use_for_topup`, `sync_expected_with_disbursement_date`) VALUES
INSERT INTO `m_product_loan` (`id`, `short_name`, `currency_code`, `currency_digits`, `currency_multiplesof`, `principal_amount`, `min_principal_amount`, `max_principal_amount`, `arrearstolerance_amount`, `name`, `description`, `fund_id`, `is_linked_to_floating_interest_rates`, `allow_variabe_installments`, `nominal_interest_rate_per_period`, `min_nominal_interest_rate_per_period`, `max_nominal_interest_rate_per_period`, `interest_period_frequency_enum`, `annual_nominal_interest_rate`, `interest_method_enum`, `interest_calculated_in_period_enum`, `allow_partial_period_interest_calcualtion`, `repay_every`, `repayment_period_frequency_enum`, `number_of_repayments`, `min_number_of_repayments`, `max_number_of_repayments`, `grace_on_principal_periods`, `recurring_moratorium_principal_periods`, `grace_on_interest_periods`, `grace_interest_free_periods`, `amortization_method_enum`, `accounting_type`, `loan_transaction_strategy_id`, `external_id`, `include_in_borrower_cycle`, `use_borrower_cycle`, `start_date`, `close_date`, `allow_multiple_disbursals`, `max_disbursals`, `max_outstanding_loan_balance`, `grace_on_arrears_aging`, `overdue_days_for_npa`, `days_in_month_enum`, `days_in_year_enum`, `interest_recalculation_enabled`, `min_days_between_disbursal_and_first_repayment`, `hold_guarantee_funds`, `principal_threshold_for_last_installment`, `account_moves_out_of_npa_only_on_arrears_completion`, `can_define_fixed_emi_amount`, `instalment_amount_in_multiples_of`, `can_use_for_topup`, `sync_expected_with_disbursement_date`) VALUES
(1, 'IGL', 'USD', 2, 0, 10000.000000, 10000.000000, 10000.000000, NULL, 'Income Generating Loan', NULL, 1, b'0', b'0', 26.000000, 26.000000, 26.000000, 3, 26.000000, 1, 1, 0, 1, 1, 25, 25, 25, NULL, NULL, NULL, NULL, 1, 2, 1, NULL, 0, 0, '2010-01-01', NULL, 0, NULL, NULL, NULL, NULL, 1, 1, 0, NULL, 0, 0.00, 0, 0, NULL, 0, 0);
/*!40000 ALTER TABLE `m_product_loan` ENABLE KEYS */;
@@ -4254,7 +4254,7 @@ CREATE TABLE IF NOT EXISTS `m_product_loan_configurable_attributes` (
`arrearstolerance_amount` TINYINT NOT NULL DEFAULT '1',
`repay_every` TINYINT NOT NULL DEFAULT '1',
`moratorium` TINYINT NOT NULL DEFAULT '1',
`grace_on_arrears_ageing` TINYINT NOT NULL DEFAULT '1',
`grace_on_arrears_aging` TINYINT NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
KEY `fk_m_product_loan_configurable_attributes_0001` (`loan_product_id`),
CONSTRAINT `fk_m_product_loan_configurable_attributes_0001` FOREIGN KEY (`loan_product_id`) REFERENCES `m_product_loan` (`id`)
@@ -4262,7 +4262,7 @@ CREATE TABLE IF NOT EXISTS `m_product_loan_configurable_attributes` (
-- Dumping data for table mifostenant-reference.m_product_loan_configurable_attributes: ~0 rows (approximately)
/*!40000 ALTER TABLE `m_product_loan_configurable_attributes` DISABLE KEYS */;
INSERT INTO `m_product_loan_configurable_attributes` (`id`, `loan_product_id`, `amortization_method_enum`, `interest_method_enum`, `loan_transaction_strategy_id`, `interest_calculated_in_period_enum`, `arrearstolerance_amount`, `repay_every`, `moratorium`, `grace_on_arrears_ageing`) VALUES
INSERT INTO `m_product_loan_configurable_attributes` (`id`, `loan_product_id`, `amortization_method_enum`, `interest_method_enum`, `loan_transaction_strategy_id`, `interest_calculated_in_period_enum`, `arrearstolerance_amount`, `repay_every`, `moratorium`, `grace_on_arrears_aging`) VALUES
(1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
/*!40000 ALTER TABLE `m_product_loan_configurable_attributes` ENABLE KEYS */;
@@ -10248,10 +10248,10 @@ GET https://DomainName/fineract-provider/api/v1/groups/{groupId}/glimaccounts
</td>
</tr>
<tr class=alt>
<td>graceOnArrearsAgeing</td>
<td>graceOnArrearsAging</td>
</tr>
<tr>
<td class=fielddesc>Optional: Integer - Used in Arrears calculation to only take into account loans that are more than graceOnArrearsAgeing days overdue.
<td class=fielddesc>Optional: Integer - Used in Arrears calculation to only take into account loans that are more than graceOnArrearsAging days overdue.
</td>
</tr>
<tr class=alt>
@@ -11630,7 +11630,7 @@ Request Body:
</tr>
<tr class=alt>
<td>graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, linkAccountId, allowPartialPeriodInterestCalculation,
fixedEmiAmount, maxOutstandingLoanBalance, disbursementData, graceOnArrearsAgeing, createStandingInstructionAtDisbursement (requires linkedAccountId if set to true), daysInYearType
fixedEmiAmount, maxOutstandingLoanBalance, disbursementData, graceOnArrearsAging, createStandingInstructionAtDisbursement (requires linkedAccountId if set to true), daysInYearType
</td>
</tr>
</table>
@@ -15780,10 +15780,10 @@ An enumeration that indicates the type of transaction processing strategy to be
</td>
</tr>
<tr class=alt>
<td>graceOnArrearsAgeing</td>
<td>graceOnArrearsAging</td>
</tr>
<tr>
<td class=fielddesc>Optional: Integer - Used in Arrears calculation to only take into account loans that are more than graceOnArrearsAgeing days overdue.
<td class=fielddesc>Optional: Integer - Used in Arrears calculation to only take into account loans that are more than graceOnArrearsAging days overdue.
</td>
</tr>
<tr class=alt>
@@ -17167,7 +17167,7 @@ GET https://DomainName/api/v1/loanproducts/{productId}
<td><div class="fineractHeading2">Optional Fields</div></td>
</tr>
<tr class=alt>
<td>inArrearsTolerance, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, graceOnArrearsAgeing, charges, paymentChannelToFundSourceMappings, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, includeInBorrowerCycle,
<td>inArrearsTolerance, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, graceOnArrearsAging, charges, paymentChannelToFundSourceMappings, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, includeInBorrowerCycle,
useBorrowerCycle,principalVariationsForBorrowerCycle,
numberOfRepaymentVariationsForBorrowerCycle,
interestRateVariationsForBorrowerCycle,
@@ -17300,7 +17300,7 @@ Request Body:
inArrearsTolerance : false,
repaymentEvery : true,
graceOnPrincipalAndInterestPayment : true,
graceOnArrearsAgeing : true},
graceOnArrearsAging : true},
"accountingRule":"2",
"name":"product 5",
@@ -20395,7 +20395,7 @@ GET https://DomainName/api/v1/jobs
},
{
"jobId": 2,
"displayName": "Update Loan Arrears Ageing",
"displayName": "Update Loan Arrears Aging",
"nextRunTime": "Jul 27, 2013 12:01:00 AM",
"cronExpression": "0 1 0 1/1 * ? *",
"active": true,
@@ -48400,7 +48400,7 @@ Request Body:
</tr>
<tr class=alt>
<td>graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, linkAccountId, allowPartialPeriodInterestCalculation,
fixedEmiAmount, maxOutstandingLoanBalance, disbursementData, graceOnArrearsAgeing, createStandingInstructionAtDisbursement (requires linkedAccountId if set to true)
fixedEmiAmount, maxOutstandingLoanBalance, disbursementData, graceOnArrearsAging, createStandingInstructionAtDisbursement (requires linkedAccountId if set to true)
</td>
</tr>
</table>
@@ -51708,10 +51708,10 @@ An enumeration that indicates the type of transaction processing strategy to be
</td>
</tr>
<tr class=alt>
<td>graceOnArrearsAgeing</td>
<td>graceOnArrearsAging</td>
</tr>
<tr>
<td class=fielddesc>Optional: Integer - Used in Arrears calculation to only take into account loans that are more than graceOnArrearsAgeing days overdue.
<td class=fielddesc>Optional: Integer - Used in Arrears calculation to only take into account loans that are more than graceOnArrearsAging days overdue.
</td>
</tr>
<tr class=alt>
@@ -51885,7 +51885,7 @@ GET https://DomainName/api/v1/self/loanproducts?clientId={clientId}
"accountMovesOutOfNPAOnlyOnArrearsCompletion":false,
"allowAttributeOverrides":{
"graceOnPrincipalAndInterestPayment":true,
"graceOnArrearsAgeing":true
"graceOnArrearsAging":true
},
"syncExpectedWithDisbursementDate":false
}
@@ -128,7 +128,7 @@ public class LoanDelinquencyDomainServiceTest {
fromDate, dueDate, principal, zeroAmount, zeroAmount, zeroAmount, false, new HashSet<>(), zeroAmount));
// when
when(loanProductRelatedDetail.getGraceOnArrearsAgeing()).thenReturn(0);
when(loanProductRelatedDetail.getGraceOnArrearsAging()).thenReturn(0);
when(loan.getLoanProductRelatedDetail()).thenReturn(loanProductRelatedDetail);
when(loan.getRepaymentScheduleInstallments()).thenReturn(repaymentScheduleInstallments);
when(loan.getCurrency()).thenReturn(currency);
@@ -154,7 +154,7 @@ public class LoanDelinquencyDomainServiceTest {
fromDate, dueDate, principal, zeroAmount, zeroAmount, zeroAmount, false, new HashSet<>(), zeroAmount));
// when
when(loanProductRelatedDetail.getGraceOnArrearsAgeing()).thenReturn(0);
when(loanProductRelatedDetail.getGraceOnArrearsAging()).thenReturn(0);
when(loan.getLoanProductRelatedDetail()).thenReturn(loanProductRelatedDetail);
when(loan.getRepaymentScheduleInstallments()).thenReturn(repaymentScheduleInstallments);
when(loanTransactionReadService.fetchLoanTransactionsByType(loan.getId(), null, LoanTransactionType.CHARGEBACK))
@@ -195,7 +195,7 @@ public class LoanDelinquencyDomainServiceTest {
List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments = Arrays.asList(installment);
// when
when(loanProductRelatedDetail.getGraceOnArrearsAgeing()).thenReturn(0);
when(loanProductRelatedDetail.getGraceOnArrearsAging()).thenReturn(0);
when(loan.getLoanProductRelatedDetail()).thenReturn(loanProductRelatedDetail);
when(loan.getRepaymentScheduleInstallments()).thenReturn(repaymentScheduleInstallments);
when(loan.getCurrency()).thenReturn(currency);
@@ -224,7 +224,7 @@ public class LoanDelinquencyDomainServiceTest {
List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments = Arrays.asList(installment);
// when
when(loanProductRelatedDetail.getGraceOnArrearsAgeing()).thenReturn(0);
when(loanProductRelatedDetail.getGraceOnArrearsAging()).thenReturn(0);
when(loan.getLoanProductRelatedDetail()).thenReturn(loanProductRelatedDetail);
when(loan.getRepaymentScheduleInstallments()).thenReturn(repaymentScheduleInstallments);
when(loanTransactionReadService.fetchLoanTransactionsByType(loan.getId(), null, LoanTransactionType.CHARGEBACK))
@@ -278,7 +278,7 @@ public class LoanDelinquencyDomainServiceTest {
List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments = Arrays.asList(installment);
// when
when(loanProductRelatedDetail.getGraceOnArrearsAgeing()).thenReturn(0);
when(loanProductRelatedDetail.getGraceOnArrearsAging()).thenReturn(0);
when(loan.getLoanProductRelatedDetail()).thenReturn(loanProductRelatedDetail);
when(loan.getRepaymentScheduleInstallments()).thenReturn(repaymentScheduleInstallments);
when(loan.isEnableInstallmentLevelDelinquency()).thenReturn(true);
@@ -329,7 +329,7 @@ public class LoanDelinquencyDomainServiceTest {
List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments = Arrays.asList(installmentOne, installmentTwo,
installmentThree);
when(loanProductRelatedDetail.getGraceOnArrearsAgeing()).thenReturn(0);
when(loanProductRelatedDetail.getGraceOnArrearsAging()).thenReturn(0);
when(loan.getLoanProductRelatedDetail()).thenReturn(loanProductRelatedDetail);
when(loan.getRepaymentScheduleInstallments()).thenReturn(repaymentScheduleInstallments);
when(loanTransactionReadService.fetchLoanTransactionsByType(loan.getId(), null, LoanTransactionType.CHARGEBACK))
@@ -385,7 +385,7 @@ public class LoanDelinquencyDomainServiceTest {
when(localLoan.getId()).thenReturn(42L);
when(localLoan.getLoanProductRelatedDetail()).thenReturn(localDetails);
when(localDetails.getGraceOnArrearsAgeing()).thenReturn(0);
when(localDetails.getGraceOnArrearsAging()).thenReturn(0);
when(localLoan.getRepaymentScheduleInstallments()).thenReturn(installments);
when(localLoan.getLastLoanRepaymentScheduleInstallment()).thenReturn(installmentThree);
when(localLoan.getCurrency()).thenReturn(currency);
+1 -1
View File
@@ -16,7 +16,7 @@
# specific language governing permissions and limitations
# under the License.
#
org.gradle.jvmargs=-Xmx12g --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-exports=java.naming/com.sun.jndi.ldap=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.security=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.management/javax.management=ALL-UNNAMED --add-opens=java.naming/javax.naming=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=null
org.gradle.jvmargs=-Xmx8g --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-exports=java.naming/com.sun.jndi.ldap=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.security=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.management/javax.management=ALL-UNNAMED --add-opens=java.naming/javax.naming=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=null
buildType=BUILD
org.gradle.caching=true
org.gradle.parallel=true
@@ -498,7 +498,7 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true)//
.graceOnArrearsAging(true)//
).isEqualAmortization(false)//
.delinquencyBucketId(delinquencyBucketId.longValue())//
.enableDownPayment(false)//
@@ -596,7 +596,7 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true)//
.graceOnArrearsAging(true)//
).isEqualAmortization(false)//
.delinquencyBucketId(delinquencyBucketId)//
.enableDownPayment(false)//
@@ -698,7 +698,7 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true)//
.graceOnArrearsAging(true)//
).isEqualAmortization(false)//
.delinquencyBucketId(delinquencyBucketId.longValue())//
.enableDownPayment(false)//
@@ -750,7 +750,7 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
.daysInYearType(1)//
.daysInMonthType(1)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -767,7 +767,7 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))//
.graceOnArrearsAging(true))//
.allowPartialPeriodInterestCalculation(true)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0)//
@@ -887,7 +887,7 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
.repaymentFrequencyType(RepaymentFrequencyType.MONTHS.longValue())//
.interestType(interestType)//
.amortizationType(amortizationType)//
.graceOnArrearsAgeing(0);
.graceOnArrearsAging(0);
}
private RequestSpecification createRequestSpecification(String authKey) {
@@ -1381,7 +1381,7 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
.maxOutstandingLoanBalance(BigDecimal.valueOf(amount)) //
.principal(BigDecimal.valueOf(amount)) //
.loanType("individual") //
.graceOnArrearsAgeing(0);
.graceOnArrearsAging(0);
if (customizer != null) {
customizer.accept(postLoansRequest);
}
@@ -3979,7 +3979,7 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest {
}
@Test
public void testLoanScheduleWithInterestRecalculation_WITH_CURRENT_REPAYMENT_BASED_ARREARS_AGEING() {
public void testLoanScheduleWithInterestRecalculation_WITH_CURRENT_REPAYMENT_BASED_ARREARS_AGING() {
DateFormat dateFormat = new SimpleDateFormat(DATETIME_PATTERN, Locale.US);
dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
@@ -4060,7 +4060,7 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest {
}
@Test
public void testLoanScheduleWithInterestRecalculation_WITH_ORIGINAL_REPAYMENT_BASED_ARREARS_AGEING() {
public void testLoanScheduleWithInterestRecalculation_WITH_ORIGINAL_REPAYMENT_BASED_ARREARS_AGING() {
DateFormat dateFormat = new SimpleDateFormat(DATETIME_PATTERN, Locale.US);
dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
@@ -7169,7 +7169,7 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest {
String loanDetails = LOAN_TRANSACTION_HELPER.getLoanDetails(REQUEST_SPEC, RESPONSE_SPEC, loanID);
List<String> comparisonAttributes = Arrays.asList("amortizationType", "interestType", "transactionProcessingStrategyCode",
"interestCalculationPeriodType", "repaymentFrequencyType", "graceOnPrincipalPayment", "graceOnInterestPayment",
"inArrearsTolerance", "graceOnArrearsAgeing");
"inArrearsTolerance", "graceOnArrearsAging");
for (String comparisonAttribute : comparisonAttributes) {
Object val1 = JsonPath.from(loanProductDetails).get(comparisonAttribute);
@@ -7186,7 +7186,7 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest {
loanProductConfiguration.addProperty("inArrearsTolerance", bool);
loanProductConfiguration.addProperty("repaymentEvery", bool);
loanProductConfiguration.addProperty("graceOnPrincipalAndInterestPayment", bool);
loanProductConfiguration.addProperty("graceOnArrearsAgeing", bool);
loanProductConfiguration.addProperty("graceOnArrearsAging", bool);
return loanProductConfiguration;
}
@@ -8306,7 +8306,7 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest {
.daysInYearType(1)//
.daysInMonthType(1)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -8323,7 +8323,7 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))//
.graceOnArrearsAging(true))//
.allowPartialPeriodInterestCalculation(true)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0)//
@@ -342,7 +342,7 @@ public class DelinquencyActionIntegrationTests extends BaseLoanIntegrationTest {
req.submittedOnDate("01 November 2023");
req.setLoanTermFrequency(45);
req.setRepaymentEvery(15);
req.setGraceOnArrearsAgeing(0);
req.setGraceOnArrearsAging(0);
});
// Partial Loan amount Disbursement
@@ -448,7 +448,7 @@ public class DelinquencyActionIntegrationTests extends BaseLoanIntegrationTest {
product.setDelinquencyBucketId(delinquencyBucketId.longValue());
product.setMultiDisburseLoan(multiDisburseEnabled);
product.setEnableDownPayment(true);
product.setGraceOnArrearsAgeing(graceOnArrearsAging);
product.setGraceOnArrearsAging(graceOnArrearsAging);
product.setDisbursedAmountPercentageForDownPayment(DOWN_PAYMENT_PERCENTAGE);
product.setEnableAutoRepaymentForDownPayment(autoDownPaymentEnabled);
@@ -481,7 +481,7 @@ public class DelinquencyActionIntegrationTests extends BaseLoanIntegrationTest {
product.setDelinquencyBucketId(delinquencyBucketId.longValue());
product.setMultiDisburseLoan(multiDisburseEnabled);
product.setEnableDownPayment(false);
product.setGraceOnArrearsAgeing(graceOnArrearsAging);
product.setGraceOnArrearsAging(graceOnArrearsAging);
product.setEnableInstallmentLevelDelinquency(installmentLevelDelinquencyEnabled);
PostLoanProductsResponse loanProductResponse = loanProductHelper.createLoanProduct(product);
@@ -498,7 +498,7 @@ public class DelinquencyActionIntegrationTests extends BaseLoanIntegrationTest {
Long loanId = applyAndApproveLoan(clientId, loanProductId, "01 January 2022", 1000.0, 2, req -> {
req.setLoanTermFrequency(30);
req.setRepaymentEvery(15);
req.setGraceOnArrearsAgeing(0);
req.setGraceOnArrearsAging(0);
});
disburseLoan(loanId, BigDecimal.valueOf(1000.00), "01 January 2022");
loanIdHolder[0] = loanId;
@@ -548,7 +548,7 @@ public class DelinquencyActionIntegrationTests extends BaseLoanIntegrationTest {
Long loanId = applyAndApproveLoan(clientId, loanProductId, "01 January 2022", 1000.0, 3, req -> {
req.setLoanTermFrequency(45);
req.setRepaymentEvery(15);
req.setGraceOnArrearsAgeing(0);
req.setGraceOnArrearsAging(0);
});
disburseLoan(loanId, BigDecimal.valueOf(100.00), "01 January 2022");
loanIdHolder[0] = loanId;
@@ -595,7 +595,7 @@ public class DelinquencyActionIntegrationTests extends BaseLoanIntegrationTest {
Long loanId = applyAndApproveLoan(clientId, loanProductId, "10 January 2022", 1000.0, 3, req -> {
req.setLoanTermFrequency(30);
req.setRepaymentEvery(10);
req.setGraceOnArrearsAgeing(0);
req.setGraceOnArrearsAging(0);
});
disburseLoan(loanId, BigDecimal.valueOf(100.00), "10 January 2022");
loanIdHolder[0] = loanId;
@@ -642,7 +642,7 @@ public class DelinquencyActionIntegrationTests extends BaseLoanIntegrationTest {
Long loanId = applyAndApproveLoan(clientId, loanProductId, "01 January 2022", 1000.0, 1, req -> {
req.setLoanTermFrequency(30);
req.setRepaymentEvery(30);
req.setGraceOnArrearsAgeing(0);
req.setGraceOnArrearsAging(0);
});
disburseLoan(loanId, BigDecimal.valueOf(100.00), "01 January 2022");
loanIdHolder[0] = loanId;
@@ -708,7 +708,7 @@ public class DelinquencyActionIntegrationTests extends BaseLoanIntegrationTest {
Long loanId = applyAndApproveLoan(clientId, loanProductId, "01 January 2022", 1000.0, 2, req -> {
req.setLoanTermFrequency(20);
req.setRepaymentEvery(10);
req.setGraceOnArrearsAgeing(0);
req.setGraceOnArrearsAging(0);
});
disburseLoan(loanId, BigDecimal.valueOf(100.00), "01 January 2022");
loanIdHolder[0] = loanId;
@@ -743,7 +743,7 @@ public class DelinquencyActionIntegrationTests extends BaseLoanIntegrationTest {
Long loanId = applyAndApproveLoan(clientId, loanProductId, "01 January 2022", 1000.0, 4, req -> {
req.setLoanTermFrequency(60);
req.setRepaymentEvery(15);
req.setGraceOnArrearsAgeing(0);
req.setGraceOnArrearsAging(0);
});
disburseLoan(loanId, BigDecimal.valueOf(1000.00), "01 January 2022");
loanIdHolder[0] = loanId;
@@ -778,7 +778,7 @@ public class DelinquencyActionIntegrationTests extends BaseLoanIntegrationTest {
Long loanId = applyAndApproveLoan(clientId, loanProductId, "28 May 2025", 1000.0, 7, req -> {
req.setLoanTermFrequency(210);
req.setRepaymentEvery(30);
req.setGraceOnArrearsAgeing(3);
req.setGraceOnArrearsAging(3);
});
disburseLoan(loanId, BigDecimal.valueOf(1000.00), "28 May 2025");
loanIdHolder[0] = loanId;
@@ -987,7 +987,7 @@ public class DelinquencyBucketsIntegrationTest extends BaseLoanIntegrationTest {
}
@Test
public void testLoanClassificationUsingAgeingArrears() {
public void testLoanClassificationUsingAgingArrears() {
try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true));
@@ -50,7 +50,7 @@ import org.apache.fineract.integrationtests.common.products.DelinquencyBucketsHe
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class LoanAccountArrearsAgeingCOBBusinessStepTest extends BaseLoanIntegrationTest {
public class LoanAccountArrearsAgingCOBBusinessStepTest extends BaseLoanIntegrationTest {
private ResponseSpecification responseSpec;
private RequestSpecification requestSpec;
@@ -69,7 +69,7 @@ public class LoanAccountArrearsAgeingCOBBusinessStepTest extends BaseLoanIntegra
}
@Test
public void loanArrearsAgeingCOBBusinessStepTest() {
public void loanArrearsAgingCOBBusinessStepTest() {
// Set Business Date
try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
@@ -105,7 +105,7 @@ public class LoanAccountArrearsAgeingCOBBusinessStepTest extends BaseLoanIntegra
String loan2ExternalIdStr = UUID.randomUUID().toString();
final Integer loanId_2 = createLoanAccount(loanOperationDate, clientId, loanProductId, loan2ExternalIdStr);
// Run Loan cob with verfying business step for Update Arrears ageing details
// Run Loan cob with verfying business step for Update Arrears aging details
final SchedulerJobHelper schedulerJobHelper = new SchedulerJobHelper(requestSpec);
// COB Step Validation
@@ -733,7 +733,7 @@ public class LoanAccountChargeOffWithAdvancedPaymentAllocationTest extends BaseL
.daysInYearType(1)//
.daysInMonthType(1)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -750,7 +750,7 @@ public class LoanAccountChargeOffWithAdvancedPaymentAllocationTest extends BaseL
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))//
.graceOnArrearsAging(true))//
.allowPartialPeriodInterestCalculation(true)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0)//
@@ -425,7 +425,7 @@ public class LoanAccountChargeReveseReplayWithAdvancedPaymentAllocationTest exte
.daysInYearType(1)//
.daysInMonthType(1)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -442,7 +442,7 @@ public class LoanAccountChargeReveseReplayWithAdvancedPaymentAllocationTest exte
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))//
.graceOnArrearsAging(true))//
.allowPartialPeriodInterestCalculation(true)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0)//
@@ -927,7 +927,7 @@ public class LoanChargeOffAccountingTest extends BaseLoanIntegrationTest {
.daysInYearType(1)//
.daysInMonthType(1)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -944,7 +944,7 @@ public class LoanChargeOffAccountingTest extends BaseLoanIntegrationTest {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))//
.graceOnArrearsAging(true))//
.allowPartialPeriodInterestCalculation(true)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0)//
@@ -60,7 +60,7 @@ public class LoanDelinquencyDetailsNextPaymentDateConfigurationTest extends Base
req.submittedOnDate("01 November 2023");
req.setLoanTermFrequency(45);
req.setRepaymentEvery(15);
req.setGraceOnArrearsAgeing(0);
req.setGraceOnArrearsAging(0);
});
// Loan amount Disbursement
@@ -146,7 +146,7 @@ public class LoanDelinquencyDetailsNextPaymentDateConfigurationTest extends Base
req.submittedOnDate("01 November 2023");
req.setLoanTermFrequency(45);
req.setRepaymentEvery(15);
req.setGraceOnArrearsAgeing(0);
req.setGraceOnArrearsAging(0);
});
// Loan amount Disbursement
@@ -268,7 +268,7 @@ public class LoanDelinquencyDetailsNextPaymentDateConfigurationTest extends Base
product.setDelinquencyBucketId(delinquencyBucketId.longValue());
product.setMultiDisburseLoan(multiDisburseEnabled);
product.setEnableDownPayment(true);
product.setGraceOnArrearsAgeing(graceOnArrearsAging);
product.setGraceOnArrearsAging(graceOnArrearsAging);
product.setDisbursedAmountPercentageForDownPayment(DOWN_PAYMENT_PERCENTAGE);
product.setEnableAutoRepaymentForDownPayment(autoDownPaymentEnabled);
@@ -1022,7 +1022,7 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
runAt("1 February 2023", () -> {
Long loanId = loanIdRef.get();
schedulerJobHelper.executeAndAwaitJob("Update Loan Arrears Ageing");
schedulerJobHelper.executeAndAwaitJob("Update Loan Arrears Aging");
schedulerJobHelper.executeAndAwaitJob("Recalculate Interest For Loans");
GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
@@ -1036,7 +1036,7 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
runAt("2 February 2023", () -> {
Long loanId = loanIdRef.get();
schedulerJobHelper.executeAndAwaitJob("Update Loan Arrears Ageing");
schedulerJobHelper.executeAndAwaitJob("Update Loan Arrears Aging");
schedulerJobHelper.executeAndAwaitJob("Recalculate Interest For Loans");
GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
@@ -1050,7 +1050,7 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
runAt("20 February 2023", () -> {
Long loanId = loanIdRef.get();
schedulerJobHelper.executeAndAwaitJob("Update Loan Arrears Ageing");
schedulerJobHelper.executeAndAwaitJob("Update Loan Arrears Aging");
schedulerJobHelper.executeAndAwaitJob("Recalculate Interest For Loans");
GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
@@ -1064,7 +1064,7 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
runAt("2 March 2023", () -> {
Long loanId = loanIdRef.get();
schedulerJobHelper.executeAndAwaitJob("Update Loan Arrears Ageing");
schedulerJobHelper.executeAndAwaitJob("Update Loan Arrears Aging");
schedulerJobHelper.executeAndAwaitJob("Recalculate Interest For Loans");
GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
@@ -1114,7 +1114,7 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
runAt("2 February 2023", () -> {
Long loanId = loanIdRef.get();
schedulerJobHelper.executeAndAwaitJob("Update Loan Arrears Ageing");
schedulerJobHelper.executeAndAwaitJob("Update Loan Arrears Aging");
schedulerJobHelper.executeAndAwaitJob("Recalculate Interest For Loans");
GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
@@ -1206,7 +1206,7 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
runAt("8 February 2023", () -> {
Long loanId = loanIdRef.get();
schedulerJobHelper.executeAndAwaitJob("Update Loan Arrears Ageing");
schedulerJobHelper.executeAndAwaitJob("Update Loan Arrears Aging");
schedulerJobHelper.executeAndAwaitJob("Recalculate Interest For Loans");
GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
@@ -1194,7 +1194,7 @@ public class LoanPostChargeOffScenariosTest extends BaseLoanIntegrationTest {
.daysInYearType(1)//
.daysInMonthType(1)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -1211,7 +1211,7 @@ public class LoanPostChargeOffScenariosTest extends BaseLoanIntegrationTest {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))//
.graceOnArrearsAging(true))//
.allowPartialPeriodInterestCalculation(true)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0)//
@@ -164,7 +164,7 @@ public class LoanProductChargeOffReasonMappingsTest extends BaseLoanIntegrationT
.daysInYearType(1)//
.daysInMonthType(1)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -180,7 +180,7 @@ public class LoanProductChargeOffReasonMappingsTest extends BaseLoanIntegrationT
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))
.graceOnArrearsAging(true))
.outstandingLoanBalance(10000.0)//
.charges(charges)//
.accountingRule(3)//
@@ -1485,7 +1485,7 @@ public class LoanTransactionAccrualActivityPostingTest extends BaseLoanIntegrati
.daysInYearType(1)//
.daysInMonthType(1)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -1501,7 +1501,7 @@ public class LoanTransactionAccrualActivityPostingTest extends BaseLoanIntegrati
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))
.graceOnArrearsAging(true))
.outstandingLoanBalance(10000.0)//
.charges(charges)//
.accountingRule(3)//
@@ -194,7 +194,7 @@ public class RepaymentReverseExternalIdTest extends BaseLoanIntegrationTest {
.daysInYearType(1)//
.daysInMonthType(1)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -210,7 +210,7 @@ public class RepaymentReverseExternalIdTest extends BaseLoanIntegrationTest {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))
.graceOnArrearsAging(true))
.outstandingLoanBalance(10000.0)//
.charges(charges)//
.accountingRule(3)//
@@ -659,7 +659,7 @@ public class SchedulerJobsTestResults extends IntegrationTest {
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
String JobName = "Update Loan Arrears Ageing";
String JobName = "Update Loan Arrears Aging";
schedulerJobHelper.executeAndAwaitJob(JobName);
HashMap loanSummaryData = loanTransactionHelper.getLoanSummary(requestSpec, responseSpec, loanID);
@@ -275,7 +275,7 @@ public class UndoRepaymentWithDownPaymentIntegrationTest extends BaseLoanIntegra
.daysInYearType(1)//
.daysInMonthType(1)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -293,7 +293,7 @@ public class UndoRepaymentWithDownPaymentIntegrationTest extends BaseLoanIntegra
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))//
.graceOnArrearsAging(true))//
.allowPartialPeriodInterestCalculation(true)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0)//
@@ -78,7 +78,7 @@ public interface LoanProductTemplates {
.daysInYearType(DaysInYearType.ACTUAL)//
.daysInMonthType(DaysInMonthType.ACTUAL)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.graceOnArrearsAging(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
@@ -95,7 +95,7 @@ public interface LoanProductTemplates {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))//
.graceOnArrearsAging(true))//
.allowPartialPeriodInterestCalculation(true)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0)//
@@ -225,7 +225,7 @@ public interface LoanProductTemplates {
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))//
.graceOnArrearsAging(true))//
.isEqualAmortization(false)//
.enableDownPayment(false)//
.enableInstallmentLevelDelinquency(false)//
@@ -68,7 +68,7 @@ public class LoanPenaltyBackdatedTransactionTest extends BaseLoanIntegrationTest
// Create Loan Product
PostLoanProductsRequest product = createOnePeriod30DaysLongNoInterestPeriodicAccrualProduct() //
.graceOnArrearsAgeing(0).numberOfRepayments(numberOfRepayments) //
.graceOnArrearsAging(0).numberOfRepayments(numberOfRepayments) //
.repaymentEvery(repaymentEvery) //
.installmentAmountInMultiplesOf(null) //
.repaymentFrequencyType(RepaymentFrequencyType.DAYS.longValue()) //
@@ -181,7 +181,7 @@ public class LoanPenaltyBackdatedTransactionTest extends BaseLoanIntegrationTest
// Create Loan Product
PostLoanProductsRequest product = createOnePeriod30DaysLongNoInterestPeriodicAccrualProduct() //
.graceOnArrearsAgeing(0).numberOfRepayments(numberOfRepayments) //
.graceOnArrearsAging(0).numberOfRepayments(numberOfRepayments) //
.repaymentEvery(repaymentEvery) //
.installmentAmountInMultiplesOf(null) //
.repaymentFrequencyType(RepaymentFrequencyType.DAYS.longValue()) //
@@ -295,7 +295,7 @@ public class LoanPenaltyBackdatedTransactionTest extends BaseLoanIntegrationTest
// Create Loan Product
PostLoanProductsRequest product = createOnePeriod30DaysLongNoInterestPeriodicAccrualProduct() //
.graceOnArrearsAgeing(0).numberOfRepayments(numberOfRepayments) //
.graceOnArrearsAging(0).numberOfRepayments(numberOfRepayments) //
.repaymentEvery(repaymentEvery) //
.installmentAmountInMultiplesOf(null) //
.repaymentFrequencyType(RepaymentFrequencyType.DAYS.longValue()) //