This is an automated email from the ASF dual-hosted git repository.
adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/develop by this push:
new 7642530393 FINERACT-2081: Fix Accrual activity - reverse and replayed
couple of times after backdated repayment
7642530393 is described below
commit 764253039316f80898e59440119c95730befaab6
Author: Rustam Zeinalov <[email protected]>
AuthorDate: Wed Feb 12 19:57:15 2025 +0100
FINERACT-2081: Fix Accrual activity - reverse and replayed couple of times
after backdated repayment
---
.gitignore | 3 +
.../fineract/test/support/TestContextKey.java | 2 +-
.../resources/features/LoanAccrualActivity.feature | 12 +--
.../domain/LoanRepaymentScheduleInstallment.java | 5 ++
.../loanaccount/domain/LoanTransaction.java | 4 +
...tLoanRepaymentScheduleTransactionProcessor.java | 11 ++-
.../LoanTransactionAccrualActivityPostingTest.java | 95 +++++++++++++++++-----
7 files changed, 105 insertions(+), 27 deletions(-)
diff --git a/.gitignore b/.gitignore
index 5a6fc20cfe..97b125798f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,3 +30,6 @@ fineract-provider/src/main/generated/
**/out/
gradleExp/
+
+.run/
+.java-version
\ No newline at end of file
diff --git
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/support/TestContextKey.java
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/support/TestContextKey.java
index 96bbae8ec2..de56fc8ab0 100644
---
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/support/TestContextKey.java
+++
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/support/TestContextKey.java
@@ -120,8 +120,8 @@ public abstract class TestContextKey {
public static final String
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_RECALCULATION_DAILY
=
"loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmiActualActualInterestRecalculationDaily";
public static final String
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ACCELERATE_MATURITY_CHARGE_OFF_BEHAVIOUR
=
"loanProductCreateResponseLP2AdvancedPaymentInterestDailyInterestRecalculationAccelerateMaturityChargeOffBehaviour";
public static final String
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_ACCRUAL_ACTIVITY
=
"loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030AccrualActivity";
- public static final String
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_ACCELERATE_MATURITY_CHARGE_OFF_BEHAVIOUR
=
"loanProductCreateResponseLP2AdvancedPaymentAccelerateMaturityChargeOffBehaviour";
public static final String
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_RECOGNITION_DISBURSEMENT_DAILY_EMI_360_30_ACCRUAL_ACTIVITY
=
"loanProductCreateResponseLP2AdvancedPaymentInterestRecognitionDisbursementDailyEmi36030AccrualActivity";
+ public static final String
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_ACCELERATE_MATURITY_CHARGE_OFF_BEHAVIOUR
=
"loanProductCreateResponseLP2AdvancedPaymentAccelerateMaturityChargeOffBehaviour";
public static final String
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_RECOGNITION_DISBURSEMENT_DAILY_EMI_ACTUAL_ACTUAL_ACCRUAL_ACTIVITY
=
"loanProductCreateResponseLP2AdvancedPaymentInterestRecognitionDisbursementDailyEmiActualActualAccrualActivity";
public static final String
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALC_EMI_360_30_CHARGEBACK_INTEREST_PENALTY_FEE_PRINCIPAL
=
"loanProductCreateResponseLP2AdvancedPaymentInterestDailyInterestRecalcEmi36030ChargebackInterestPenaltyFeePrincipal";
public static final String
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALC_EMI_360_30_CHARGEBACK_INTEREST_FEE_PRINCIPAL
=
"loanProductCreateResponseLP2AdvancedPaymentInterestDailyInterestRecalcEmi36030ChargebackInterestFeePrincipal";
diff --git
a/fineract-e2e-tests-runner/src/test/resources/features/LoanAccrualActivity.feature
b/fineract-e2e-tests-runner/src/test/resources/features/LoanAccrualActivity.feature
index 2e8f17d92a..ddd8056f6f 100644
---
a/fineract-e2e-tests-runner/src/test/resources/features/LoanAccrualActivity.feature
+++
b/fineract-e2e-tests-runner/src/test/resources/features/LoanAccrualActivity.feature
@@ -4584,7 +4584,7 @@ Feature: LoanAccrualActivity
| 1 | 29 | 29 February 2024 | | 1671.5 | 328.5
| 11.67 | 0.0 | 0.0 | 340.17 | 0.0 | 0.0 | 0.0 |
340.17 |
| 2 | 31 | 31 March 2024 | | 1341.14 | 330.36
| 9.81 | 0.0 | 0.0 | 340.17 | 0.0 | 0.0 | 0.0 | 340.17
|
| 3 | 30 | 30 April 2024 | | 1008.79 | 332.35
| 7.82 | 0.0 | 0.0 | 340.17 | 0.0 | 0.0 | 0.0 |
340.17 |
- | 4 | 31 | 31 May 2024 | | 674.5 | 334.29
| 5.88 | 0.0 | 0.0 | 340.17 | 0.0 | 0.0 | 0.0 |
340.17 |
+ | 4 | 31 | 31 May 2024 | | 674.5 |
334.29 | 5.88 | 0.0 | 0.0 | 340.17 | 0.0 | 0.0 | 0.0 |
340.17 |
| 5 | 30 | 30 June 2024 | | 338.26 | 336.24
| 3.93 | 0.0 | 0.0 | 340.17 | 0.0 | 0.0 | 0.0 |
340.17 |
| 6 | 31 | 31 July 2024 | | 0.0 | 338.26
| 1.97 | 0.0 | 0.0 | 340.23 | 0.0 | 0.0 | 0.0 |
340.23 |
Then Loan Repayment schedule has the following data in Total row:
@@ -4629,11 +4629,11 @@ Feature: LoanAccrualActivity
| Nr | Days | Date | Paid date | Balance of loan |
Principal due | Interest | Fees | Penalties | Due | Paid | In advance |
Late | Outstanding |
| | | 31 January 2024 | | 2000.0 |
| | 0.0 | | 0.0 | 0.0 | |
| |
| 1 | 29 | 29 February 2024 | 15 February 2024 | 1665.86 |
334.14 | 6.03 | 0.0 | 0.0 | 340.17 | 340.17 | 340.17 |
0.0 | 0.0 |
- | 2 | 31 | 31 March 2024 | | 1340.11 |
325.75 | 14.42 | 0.0 | 0.0 | 340.17 | 0.0 | 0.0 |
0.0 | 340.17 |
+ | 2 | 31 | 31 March 2024 | | 1340.11 |
325.75 | 14.42 | 0.0 | 0.0 | 340.17 | 0.0 | 0.0 |
0.0 | 340.17 |
| 3 | 30 | 30 April 2024 | | 1007.76 |
332.35 | 7.82 | 0.0 | 0.0 | 340.17 | 0.0 | 0.0 |
0.0 | 340.17 |
- | 4 | 31 | 31 May 2024 | | 673.47 |
334.29 | 5.88 | 0.0 | 0.0 | 340.17 | 0.0 | 0.0 |
0.0 | 340.17 |
+ | 4 | 31 | 31 May 2024 | | 673.47
| 334.29 | 5.88 | 0.0 | 0.0 | 340.17 | 0.0 | 0.0 |
0.0 | 340.17 |
| 5 | 30 | 30 June 2024 | | 337.23 |
336.24 | 3.93 | 0.0 | 0.0 | 340.17 | 0.0 | 0.0 |
0.0 | 340.17 |
- | 6 | 31 | 31 July 2024 | | 0.0 |
337.23 | 1.97 | 0.0 | 0.0 | 339.2 | 0.0 | 0.0 |
0.0 | 339.2 |
+ | 6 | 31 | 31 July 2024 | | 0.0 |
337.23 | 1.97 | 0.0 | 0.0 | 339.2 | 0.0 | 0.0 |
0.0 | 339.2 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In
advance | Late | Outstanding |
| 2000.0 | 40.05 | 0.0 | 0.0 | 2040.05 | 340.17 |
340.17 | 0.0 | 1699.88 |
@@ -4680,7 +4680,7 @@ Feature: LoanAccrualActivity
| 1 | 29 | 29 February 2024 | 15 February 2024 | 1665.86 |
334.14 | 6.03 | 0.0 | 0.0 | 340.17 | 340.17 | 340.17 |
0.0 | 0.0 |
| 2 | 31 | 31 March 2024 | | 1340.11 |
325.75 | 14.42 | 0.0 | 0.0 | 340.17 | 0.0 | 0.0 |
0.0 | 340.17 |
| 3 | 30 | 30 April 2024 | | 1007.82 |
332.29 | 7.88 | 0.0 | 0.0 | 340.17 | 0.0 | 0.0 |
0.0 | 340.17 |
- | 4 | 31 | 31 May 2024 | | 673.53 |
334.29 | 5.88 | 0.0 | 0.0 | 340.17 | 0.0 | 0.0 |
0.0 | 340.17 |
+ | 4 | 31 | 31 May 2024 | | 673.53 |
334.29 | 5.88 | 0.0 | 0.0 | 340.17 | 0.0 | 0.0 |
0.0 | 340.17 |
| 5 | 30 | 30 June 2024 | | 337.29 |
336.24 | 3.93 | 0.0 | 0.0 | 340.17 | 0.0 | 0.0 |
0.0 | 340.17 |
| 6 | 31 | 31 July 2024 | | 0.0 |
337.29 | 1.97 | 0.0 | 0.0 | 339.26 | 0.0 | 0.0 |
0.0 | 339.26 |
Then Loan Repayment schedule has the following data in Total row:
@@ -4721,7 +4721,7 @@ Feature: LoanAccrualActivity
| 28 February 2024 | Accrual | 0.41 | 0.0 | 0.41
| 0.0 | 0.0 | 0.0 | false | false |
| 29 February 2024 | Accrual | 0.38 | 0.0 | 0.38
| 0.0 | 0.0 | 0.0 | false | false |
| 29 February 2024 | Accrual Activity | 6.03 | 0.0 | 6.03
| 0.0 | 0.0 | 0.0 | false | true |
- | 01 March 2024 | Accrual Adjustment | 0.69 | 0.0 | 0.69
| 0.0 | 0.0 | 0.0 | false | false |
+ | 01 March 2024 | Accrual Adjustment | 0.69 | 0.0 | 0.69
| 0.0 | 0.0 | 0.0 | false | false |
| 02 March 2024 | Accrual | 0.31 | 0.0 | 0.31
| 0.0 | 0.0 | 0.0 | false | false |
| 03 March 2024 | Accrual | 0.31 | 0.0 | 0.31
| 0.0 | 0.0 | 0.0 | false | false |
| 04 March 2024 | Accrual | 0.32 | 0.0 | 0.32
| 0.0 | 0.0 | 0.0 | false | false |
diff --git
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java
index 87641b5423..307e1355d2 100644
---
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java
+++
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java
@@ -1058,4 +1058,9 @@ public class LoanRepaymentScheduleInstallment extends
AbstractAuditableWithUTCDa
public enum PaymentAction {
PAY, UNPAY
}
+
+ public boolean isTransactionDateWithinPeriod(LocalDate referenceDate) {
+ return DateUtils.isAfter(referenceDate, getFromDate()) &&
!DateUtils.isAfter(referenceDate, getDueDate());
+ }
+
}
diff --git
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java
index a9f7270bcf..b8de878758 100644
---
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java
+++
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java
@@ -1035,4 +1035,8 @@ public class LoanTransaction extends
AbstractAuditableWithUTCDateTimeCustom<Long
// TODO missing hashCode(), equals(Object obj), but probably OK as long as
// this is never stored in a Collection.
+
+ public void updateTransactionDate(final LocalDate transactionDate) {
+ this.dateOf = transactionDate;
+ }
}
diff --git
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/AbstractLoanRepaymentScheduleTransactionProcessor.java
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/AbstractLoanRepaymentScheduleTransactionProcessor.java
index c6c0da1869..722328cd25 100644
---
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/AbstractLoanRepaymentScheduleTransactionProcessor.java
+++
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/AbstractLoanRepaymentScheduleTransactionProcessor.java
@@ -239,7 +239,16 @@ public abstract class
AbstractLoanRepaymentScheduleTransactionProcessor implemen
Money interestPortion =
currentInstallment.getInterestCharged(currency);
Money feeChargesPortion =
currentInstallment.getFeeChargesCharged(currency);
Money penaltyChargesPortion =
currentInstallment.getPenaltyChargesCharged(currency);
- loanTransaction.updateComponentsAndTotal(principalPortion,
interestPortion, feeChargesPortion, penaltyChargesPortion);
+ if
(interestPortion.plus(feeChargesPortion).plus(penaltyChargesPortion).isZero()) {
+ loanTransaction.reverse();
+ } else {
+ loanTransaction.updateComponentsAndTotal(principalPortion,
interestPortion, feeChargesPortion, penaltyChargesPortion);
+ final Loan loan = loanTransaction.getLoan();
+ if ((loan.isClosedObligationsMet() || loan.isOverPaid()) &&
currentInstallment.isObligationsMet()
+ &&
currentInstallment.isTransactionDateWithinPeriod(currentInstallment.getObligationsMetOnDate()))
{
+
loanTransaction.updateTransactionDate(currentInstallment.getObligationsMetOnDate());
+ }
+ }
}
}
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionAccrualActivityPostingTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionAccrualActivityPostingTest.java
index c8d754f9da..b042ec8ff5 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionAccrualActivityPostingTest.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionAccrualActivityPostingTest.java
@@ -417,7 +417,6 @@ public class LoanTransactionAccrualActivityPostingTest
extends BaseLoanIntegrati
transaction(6.48, "Accrual Activity", "17 November 2024"),
//
transaction(4.75, "Accrual Activity", "17 December 2024"),
//
transaction(18.31, "Accrual Activity", "17 January
2025")); //
-
});
}
@@ -719,7 +718,7 @@ public class LoanTransactionAccrualActivityPostingTest
extends BaseLoanIntegrati
Long localLoanProductId =
createLoanProductAccountingAccrualPeriodicAdvancedPaymentAllocation();
loanId.set(applyForLoanApplicationAdvancedPaymentAllocation(client.getClientId(),
localLoanProductId, BigDecimal.valueOf(40000),
- disbursementDay));
+ disbursementDay, BigDecimal.ZERO));
loanTransactionHelper.approveLoan(loanId.get(), new
PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000))
.dateFormat(DATETIME_PATTERN).approvedOnDate(disbursementDay).locale("en"));
@@ -798,7 +797,7 @@ public class LoanTransactionAccrualActivityPostingTest
extends BaseLoanIntegrati
Long localLoanProductId =
createLoanProductAccountingAccrualPeriodicAdvancedPaymentAllocation();
loanId.set(applyForLoanApplicationAdvancedPaymentAllocation(client.getClientId(),
localLoanProductId, BigDecimal.valueOf(40000),
- disbursementDay));
+ disbursementDay, BigDecimal.ZERO));
loanTransactionHelper.approveLoan(loanId.get(), new
PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000))
.dateFormat(DATETIME_PATTERN).approvedOnDate(disbursementDay).locale("en"));
@@ -850,7 +849,7 @@ public class LoanTransactionAccrualActivityPostingTest
extends BaseLoanIntegrati
runAt(creationBusinessDay, () -> {
Long localLoanProductId =
createLoanProductAccountingAccrualPeriodicAdvancedPaymentAllocation();
loanId.set(applyForLoanApplicationAdvancedPaymentAllocation(client.getClientId(),
localLoanProductId, BigDecimal.valueOf(40000),
- disbursementDay));
+ disbursementDay, BigDecimal.ZERO));
loanTransactionHelper.approveLoan(loanId.get(), new
PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000))
.dateFormat(DATETIME_PATTERN).approvedOnDate(disbursementDay).locale("en"));
@@ -955,7 +954,7 @@ public class LoanTransactionAccrualActivityPostingTest
extends BaseLoanIntegrati
Long localLoanProductId =
createLoanProductAccountingAccrualPeriodicAdvancedPaymentAllocation(true);
loanId.set(applyForLoanApplicationAdvancedPaymentAllocation(client.getClientId(),
localLoanProductId, BigDecimal.valueOf(40000),
- disbursementDay, disbursementDay2));
+ disbursementDay, disbursementDay2, BigDecimal.ZERO));
loanTransactionHelper.approveLoan(loanId.get(), new
PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000))
.dateFormat(DATETIME_PATTERN).approvedOnDate(disbursementDay).locale("en"));
@@ -1014,7 +1013,7 @@ public class LoanTransactionAccrualActivityPostingTest
extends BaseLoanIntegrati
Long localLoanProductId =
createLoanProductAccountingAccrualPeriodicAdvancedPaymentAllocation(true);
loanId.set(applyForLoanApplicationAdvancedPaymentAllocation(client.getClientId(),
localLoanProductId, BigDecimal.valueOf(40000),
- disbursementDay, disbursementDay2));
+ disbursementDay, disbursementDay2, BigDecimal.ZERO));
loanTransactionHelper.approveLoan(loanId.get(), new
PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000))
.dateFormat(DATETIME_PATTERN).approvedOnDate(disbursementDay).locale("en"));
@@ -1119,7 +1118,7 @@ public class LoanTransactionAccrualActivityPostingTest
extends BaseLoanIntegrati
runAt(creationBusinessDay, () -> {
Long localLoanProductId =
createLoanProductAccountingAccrualPeriodicAdvancedPaymentAllocation(true);
loanId.set(applyForLoanApplicationAdvancedPaymentAllocation(client.getClientId(),
localLoanProductId, BigDecimal.valueOf(1000),
- disbursementDay, disbursementDay2));
+ disbursementDay, disbursementDay2, BigDecimal.ZERO));
loanTransactionHelper.approveLoan(loanId.get(), new
PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000))
.dateFormat(DATETIME_PATTERN).approvedOnDate(disbursementDay).locale("en"));
@@ -1391,6 +1390,41 @@ public class LoanTransactionAccrualActivityPostingTest
extends BaseLoanIntegrati
});
}
+ @Test
+ public void testReverseAndReplayedCoupleOfTimesAfterBackdatedRepayment() {
+ final String disbursementDay = "01 January 2025";
+ AtomicReference<Long> loanId = new AtomicReference<>();
+ runAt(disbursementDay, () -> {
+ Long localLoanProductId =
createLoanProductAccountingAccrualPeriodicAdvancedPaymentAllocationInterestRecalculation(true);
+
loanId.set(applyForLoanApplicationAdvancedPaymentAllocation(client.getClientId(),
localLoanProductId, BigDecimal.valueOf(800),
+ disbursementDay, disbursementDay,
BigDecimal.valueOf(0.3)));
+
+ loanTransactionHelper.approveLoan(loanId.get(), new
PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(800))
+
.dateFormat(DATETIME_PATTERN).approvedOnDate(disbursementDay).locale("en"));
+
+ loanTransactionHelper.disburseLoan(loanId.get(), new
PostLoansLoanIdRequest().actualDisbursementDate(disbursementDay)
+
.dateFormat(DATETIME_PATTERN).transactionAmount(BigDecimal.valueOf(800.0)).locale("en"));
+ });
+
+ runAt("02 February 2025", () -> {
+ inlineLoanCOBHelper.executeInlineCOB(List.of(loanId.get()));
+ verifyTransactions(loanId.get(),
+ transaction(10.60, "Accrual Activity", "01 February 2025",
0.0, 0.0, 10.60, 0.0, 0.0, 0.0, 0.0, false), //
+ transaction(10.60, "Accrual", "01 February 2025", 0.0,
0.0, 10.60, 0.0, 0.0, 0.0, 0.0, false), //
+ transaction(800.0, "Disbursement", disbursementDay, 800.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false));
+
+ loanTransactionHelper.makeLoanRepayment("31 January 2025", 900.0F,
loanId.get().intValue());
+
+ verifyTransactions(loanId.get(),
+ transaction(0.34, "Accrual Adjustment", "02 February
2025", 0.0, 0.0, 0.34, 0.0, 0.0, 0.0, 0.0, false), //
+ transaction(10.60, "Accrual", "01 February 2025", 0.0,
0.0, 10.60, 0.0, 0.0, 0.0, 0.0, false), //
+ transaction(10.26, "Accrual Activity", "31 January 2025",
0.0, 0.0, 10.26, 0.0, 0.0, 0.0, 0.0, false), //
+ transaction(900.0, "Repayment", "31 January 2025", 0.0,
800, 10.26, 0.0, 0.0, 0.0, 89.74, false), //
+ transaction(800.0, "Disbursement", disbursementDay, 800.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false));
+
+ });
+ }
+
private PostLoanProductsRequest
loanProductsRequestInterestDecliningBalanceDailyRecalculationCompoundingNoneAccrualActivity()
{
String name = Utils.uniqueRandomStringGenerator("LOAN_PRODUCT_", 6);
String shortName = Utils.uniqueRandomStringGenerator("", 4);
@@ -1439,6 +1473,7 @@ public class LoanTransactionAccrualActivityPostingTest
extends BaseLoanIntegrati
.minInterestRatePerPeriod(0.0)//
.interestRatePerPeriod(12.0)//
.maxInterestRatePerPeriod(30.0)//
+ .interestRateFrequencyType(2)// Month
.interestRateFrequencyType(3)//
.repaymentEvery(30)//
.repaymentFrequencyType(0L)//
@@ -1631,19 +1666,28 @@ public class LoanTransactionAccrualActivityPostingTest
extends BaseLoanIntegrati
}
private Long
createLoanProductAccountingAccrualPeriodicAdvancedPaymentAllocation(boolean
isMultiDisburse) {
+ Long resourceId = loanTransactionHelper
+
.createLoanProduct(loanProductAccountingAccrualAdvanvedPaymentAllocationAccrualActivity(isMultiDisburse)).getResourceId();
+ LOG.info("Test Progressive Loan Product Id {} isMultiDisburse {}
http://localhost:4200/#/products/loan-products/{1}/general",
+ resourceId, isMultiDisburse);
+ return resourceId;
+ }
+
+ private PostLoanProductsRequest
loanProductAccountingAccrualAdvanvedPaymentAllocationAccrualActivity(boolean
isMultiDisburse) {
String name = Utils.uniqueRandomStringGenerator("LOAN_PRODUCT_", 6);
String shortName = Utils.uniqueRandomStringGenerator("", 4);
AdvancedPaymentData defaultAllocation =
createDefaultPaymentAllocation();
- Long resourceId = loanTransactionHelper.createLoanProduct(new
PostLoanProductsRequest().name(name).shortName(shortName)
-
.multiDisburseLoan(isMultiDisburse).maxTrancheCount(isMultiDisburse ? 2 :
1).interestType(isMultiDisburse ? 0 : 1)
+ return new
PostLoanProductsRequest().name(name).shortName(shortName).multiDisburseLoan(isMultiDisburse)
+ .maxTrancheCount(isMultiDisburse ? 2 :
1).interestType(isMultiDisburse ? 0 : 1)
.interestCalculationPeriodType(isMultiDisburse ? 0 :
1).disallowExpectedDisbursements(isMultiDisburse)
.description("Test loan
description").currencyCode("USD").digitsAfterDecimal(2).daysInYearType(1).daysInMonthType(1)
.recalculationRestFrequencyType(1).rescheduleStrategyMethod(1).loanScheduleType(LoanScheduleType.PROGRESSIVE.name())
-
.recalculationRestFrequencyInterval(0).isInterestRecalculationEnabled(false).locale("en_GB").numberOfRepayments(4)
-
.repaymentFrequencyType(2L).repaymentEvery(1).minPrincipal(100.0).principal(1000.0).maxPrincipal(10000000.0)
-
.amortizationType(1).interestRatePerPeriod(0.0).interestRateFrequencyType(1).dateFormat("dd
MMMM yyyy")
+
.recalculationRestFrequencyInterval(0).locale("en_GB").numberOfRepayments(4).repaymentFrequencyType(2L).repaymentEvery(1)
+
.minPrincipal(100.0).principal(1000.0).maxPrincipal(10000000.0).amortizationType(1).interestRatePerPeriod(0.0)
+ .interestRateFrequencyType(1).dateFormat("dd MMMM yyyy")
.transactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION_STRATEGY).paymentAllocation(List.of(defaultAllocation))
-
.accountingRule(3).enableAccrualActivityPosting(true).fundSourceAccountId(fundSource.getAccountID().longValue())//
+
.accountingRule(3).isInterestRecalculationEnabled(false).enableAccrualActivityPosting(true)
+ .fundSourceAccountId(fundSource.getAccountID().longValue())//
.loanPortfolioAccountId(loansReceivableAccount.getAccountID().longValue())//
.transfersInSuspenseAccountId(suspenseAccount.getAccountID().longValue())//
.interestOnLoanAccountId(interestIncomeAccount.getAccountID().longValue())//
@@ -1663,18 +1707,30 @@ public class LoanTransactionAccrualActivityPostingTest
extends BaseLoanIntegrati
.incomeFromChargeOffFeesAccountId(feeChargeOffAccount.getAccountID().longValue())//
.chargeOffExpenseAccountId(chargeOffExpenseAccount.getAccountID().longValue())//
.chargeOffFraudExpenseAccountId(chargeOffFraudExpenseAccount.getAccountID().longValue())//
-
.incomeFromChargeOffPenaltyAccountId(penaltyChargeOffAccount.getAccountID().longValue())//
- ).getResourceId();
+
.incomeFromChargeOffPenaltyAccountId(penaltyChargeOffAccount.getAccountID().longValue());//
+ }
+
+ private Long
createLoanProductAccountingAccrualPeriodicAdvancedPaymentAllocationInterestRecalculation(boolean
isMultiDisburse) {
+ Long resourceId = loanTransactionHelper
+
.createLoanProduct(loanProductAccountingAccrualAdvanvedPaymentAllocationAccrualActivity(isMultiDisburse)
//
+ .interestRatePerPeriod(10.0) //
+ .isInterestRecalculationEnabled(true)//
+ .preClosureInterestCalculationStrategy(1) //
TILL_PRE_CLOSE_DATE
+ .rescheduleStrategyMethod(4) //
ADJUST_LAST_UNPAID_PERIOD
+ .interestRecalculationCompoundingMethod(0) // NONE
+ .recalculationRestFrequencyType(2) // DAILY
+ .recalculationRestFrequencyInterval(1)//
+ ).getResourceId();
LOG.info("Test Progressive Loan Product Id {} isMultiDisburse {}
http://localhost:4200/#/products/loan-products/{1}/general",
resourceId, isMultiDisburse);
return resourceId;
}
private static Long applyForLoanApplicationAdvancedPaymentAllocation(final
Long clientID, final Long loanProductID,
- BigDecimal principal, String applicationDisbursementDate) {
+ BigDecimal principal, String applicationDisbursementDate,
BigDecimal interestRatePerPeriod) {
final PostLoansRequest loanRequest = new PostLoansRequest() //
.loanTermFrequency(4).locale("en_GB").loanTermFrequencyType(2).numberOfRepayments(4).repaymentFrequencyType(2)
-
.repaymentEvery(1).principal(principal).amortizationType(1).interestType(0).interestRatePerPeriod(BigDecimal.ZERO)
+
.repaymentEvery(1).principal(principal).amortizationType(1).interestType(0).interestRatePerPeriod(interestRatePerPeriod)
.interestCalculationPeriodType(1).dateFormat("dd MMMM yyyy")
.transactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION_STRATEGY).loanType("individual")
.expectedDisbursementDate(applicationDisbursementDate).submittedOnDate(applicationDisbursementDate).clientId(clientID)
@@ -1686,10 +1742,11 @@ public class LoanTransactionAccrualActivityPostingTest
extends BaseLoanIntegrati
}
private static Long applyForLoanApplicationAdvancedPaymentAllocation(final
Long clientID, final Long loanProductID,
- BigDecimal principal, String applicationDisbursementDate, String
applicationDisbursementDate2) {
+ BigDecimal principal, String applicationDisbursementDate, String
applicationDisbursementDate2,
+ BigDecimal interestRatePerPeriod) {
final PostLoansRequest loanRequest = new PostLoansRequest() //
.loanTermFrequency(4).locale("en_GB").loanTermFrequencyType(2).numberOfRepayments(4).repaymentFrequencyType(2)
-
.repaymentEvery(1).principal(principal).amortizationType(1).interestType(0).interestRatePerPeriod(BigDecimal.ZERO)
+
.repaymentEvery(1).principal(principal).amortizationType(1).interestType(0).interestRatePerPeriod(interestRatePerPeriod)
.interestCalculationPeriodType(0).dateFormat("dd MMMM yyyy")
.transactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION_STRATEGY).loanType("individual")
.submittedOnDate(applicationDisbursementDate).clientId(clientID).expectedDisbursementDate(applicationDisbursementDate2)