FINERACT-2326: Fix payment allocation when current period is closed

This commit is contained in:
mark.vituska
2025-07-28 14:23:54 +02:00
committed by Adam Saghy
parent 70373eafef
commit 68b35024f6
5 changed files with 104 additions and 60 deletions
@@ -2949,12 +2949,12 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
| 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 10.0 | 0.0 | 10.0 | 7.01 |
| 3 | 31 | 01 April 2024 | | 50.53 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.91 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 17.19 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 6 | 30 | 01 July 2024 | | 0.0 | 17.19 | 0.2 | 0.0 | 0.0 | 17.39 | 0.0 | 0.0 | 0.0 | 17.39 |
| 4 | 30 | 01 May 2024 | | 33.81 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 17.0 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 6 | 30 | 01 July 2024 | | 0.0 | 17.0 | 0.1 | 0.0 | 0.0 | 17.1 | 0.0 | 0.0 | 0.0 | 17.1 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 2.44 | 0.0 | 0.0 | 102.44 | 27.01 | 0.0 | 10.0 | 75.43 |
| 100.0 | 2.15 | 0.0 | 0.0 | 102.15 | 27.01 | 0.0 | 10.0 | 75.14 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
@@ -2969,12 +2969,12 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
| 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 10.0 | 0.0 | 10.0 | 7.01 |
| 3 | 31 | 01 April 2024 | | 50.53 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.95 | 16.58 | 0.43 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 17.27 | 16.68 | 0.33 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 6 | 30 | 01 July 2024 | | 0.0 | 17.27 | 0.24 | 0.0 | 0.0 | 17.51 | 0.0 | 0.0 | 0.0 | 17.51 |
| 4 | 30 | 01 May 2024 | | 33.81 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 17.0 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 6 | 30 | 01 July 2024 | | 0.0 | 17.0 | 0.1 | 0.0 | 0.0 | 17.1 | 0.0 | 0.0 | 0.0 | 17.1 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 2.56 | 0.0 | 0.0 | 102.56 | 27.01 | 0.0 | 10.0 | 75.55 |
| 100.0 | 2.15 | 0.0 | 0.0 | 102.15 | 27.01 | 0.0 | 10.0 | 75.14 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
@@ -7890,10 +7890,10 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
| 3 | 31 | 01 April 2025 | | 4661.9 | 1112.7 | 576.13 | 0.0 | 0.0 | 1688.83 | 0.0 | 0.0 | 0.0 | 1688.83 |
| 4 | 30 | 01 May 2025 | | 3549.2 | 1112.7 | 576.13 | 0.0 | 0.0 | 1688.83 | 0.0 | 0.0 | 0.0 | 1688.83 |
| 5 | 31 | 01 June 2025 | | 2436.5 | 1112.7 | 576.13 | 0.0 | 0.0 | 1688.83 | 0.0 | 0.0 | 0.0 | 1688.83 |
| 6 | 30 | 01 July 2025 | | 0.0 | 2436.5 | 896.66 | 0.0 | 0.0 | 3333.16 | 0.0 | 0.0 | 0.0 | 3333.16 |
| 6 | 30 | 01 July 2025 | | 0.0 | 2436.5 | 576.13 | 0.0 | 0.0 | 3012.63 | 0.0 | 0.0 | 0.0 | 3012.63 |
And Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 8000.0 | 3777.31 | 0.0 | 0.0 | 11777.31 | 0.05 | 0.0 | 0.04 | 11777.26 |
| 8000.0 | 3456.78 | 0.0 | 0.0 | 11456.78 | 0.05 | 0.0 | 0.04 | 11456.73 |
@TestRailId:C3657
Scenario: Verify tranche interest bearing progressive loan that expects two tranches with repayment and undo last disbursement - UC1
@@ -9631,4 +9631,4 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
| Type | Account code | Account name | Debit | Credit |
| ASSET | 112601 | Loans Receivable | | 906.25 |
| ASSET | 112603 | Interest/Fee Receivable | | 16.87 |
| LIABILITY | 145023 | Suspense/Clearing account | 923.12 | |
| LIABILITY | 145023 | Suspense/Clearing account | 923.12 | |
@@ -6005,18 +6005,18 @@ Feature: Charge-off
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | 01 March 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 17.01 | 0.0 |
| 2 | 29 | 01 March 2024 | 01 March 2024 | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 3 | 30 | 31 March 2024 | | 0.0 | 67.05 | 0.18 | 0.0 | 0.0 | 67.23 | 35.98 | 35.98 | 0.0 | 31.25 |
| 2 | 29 | 01 March 2024 | 01 March 2024 | 67.14 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 3 | 30 | 31 March 2024 | | 0.0 | 67.14 | 0.0 | 0.0 | 0.0 | 67.14 | 35.98 | 35.98 | 0.0 | 31.16 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 1.25 | 0.0 | 0.0 | 101.25 | 70.0 | 35.98 | 17.01 | 31.25 |
| 100.0 | 1.16 | 0.0 | 0.0 | 101.16 | 70.0 | 35.98 | 17.01 | 31.16 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
| 01 March 2024 | Repayment | 70.0 | 68.93 | 1.07 | 0.0 | 0.0 | 31.07 | false | false |
| 01 March 2024 | Repayment | 70.0 | 68.84 | 1.16 | 0.0 | 0.0 | 31.16 | false | false |
| 31 March 2024 | Accrual | 1.72 | 0.0 | 1.72 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Accrual Adjustment | 0.47 | 0.0 | 0.47 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Charge-off | 31.25 | 31.07 | 0.18 | 0.0 | 0.0 | 0.0 | false | true |
| 31 March 2024 | Accrual Adjustment | 0.56 | 0.0 | 0.56 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Charge-off | 31.16 | 31.16 | 0.0 | 0.0 | 0.0 | 0.0 | false | true |
And Global configuration "is-principal-compounding-disabled-for-overdue-loans" is disabled
@TestRailId:C3499 @AdvancedPaymentAllocation
@@ -1035,18 +1035,18 @@ Feature: Contract Termination
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | 01 March 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 17.01 | 0.0 |
| 2 | 29 | 01 March 2024 | 01 March 2024 | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 3 | 30 | 31 March 2024 | | 0.0 | 67.05 | 0.18 | 0.0 | 0.0 | 67.23 | 35.98 | 35.98 | 0.0 | 31.25 |
| 2 | 29 | 01 March 2024 | 01 March 2024 | 67.14 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 3 | 30 | 31 March 2024 | | 0.0 | 67.14 | 0.0 | 0.0 | 0.0 | 67.14 | 35.98 | 35.98 | 0.0 | 31.16 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 1.25 | 0.0 | 0.0 | 101.25 | 70.0 | 35.98 | 17.01 | 31.25 |
| 100.0 | 1.16 | 0.0 | 0.0 | 101.16 | 70.0 | 35.98 | 17.01 | 31.16 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
| 01 March 2024 | Repayment | 70.0 | 68.93 | 1.07 | 0.0 | 0.0 | 31.07 | false | false |
| 01 March 2024 | Repayment | 70.0 | 68.84 | 1.16 | 0.0 | 0.0 | 31.16 | false | false |
| 31 March 2024 | Accrual | 1.72 | 0.0 | 1.72 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Accrual Adjustment | 0.47 | 0.0 | 0.47 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Contract Termination | 31.25 | 31.07 | 0.18 | 0.0 | 0.0 | 0.0 | false | true |
| 31 March 2024 | Accrual Adjustment | 0.56 | 0.0 | 0.56 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Contract Termination | 31.16 | 31.16 | 0.0 | 0.0 | 0.0 | 0.0 | false | true |
And Global configuration "is-principal-compounding-disabled-for-overdue-loans" is disabled
@TestRailId:C3738
@@ -639,21 +639,21 @@ Feature: Loan interest pause on repayment schedule
And Customer makes "PAYOUT_REFUND" transaction with "AUTOPAY" payment type on "22 April 2025" with 400 EUR transaction amount and self-generated Idempotency key
When Admin sets the business date to "23 April 2025"
And Admin runs inline COB job for Loan
And Admin makes Credit Balance Refund transaction on "23 April 2025" with 165.25 EUR transaction amount
And Admin makes Credit Balance Refund transaction on "23 April 2025" with 164.19 EUR transaction amount
When Admin sets the business date to "01 May 2025"
And Admin runs inline COB job for Loan
Then Loan Repayment schedule has 6 periods, with the following data for periods:
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 01 April 2025 | | 1000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 30 | 01 May 2025 | 21 April 2025 | 829.71 | 170.29 | 9.75 | 0.0 | 25.0 | 205.04 | 205.04 | 205.04 | 0.0 | 0.0 |
| 2 | 31 | 01 June 2025 | 21 April 2025 | 649.67 | 180.04 | 0.0 | 0.0 | 0.0 | 180.04 | 180.04 | 180.04 | 0.0 | 0.0 |
| 3 | 30 | 01 July 2025 | 21 April 2025 | 469.63 | 180.04 | 0.0 | 0.0 | 0.0 | 180.04 | 180.04 | 180.04 | 0.0 | 0.0 |
| 4 | 31 | 01 August 2025 | 21 April 2025 | 289.59 | 180.04 | 0.0 | 0.0 | 0.0 | 180.04 | 180.04 | 180.04 | 0.0 | 0.0 |
| 5 | 31 | 01 September 2025 | 22 April 2025 | 109.55 | 180.04 | 0.0 | 0.0 | 0.0 | 180.04 | 180.04 | 180.04 | 0.0 | 0.0 |
| 6 | 30 | 01 October 2025 | 22 April 2025 | 0.0 | 109.55 | 0.0 | 0.0 | 0.0 | 109.55 | 109.55 | 109.55 | 0.0 | 0.0 |
| 1 | 30 | 01 May 2025 | 22 April 2025 | 828.65 | 171.35 | 9.75 | 0.0 | 25.0 | 206.1 | 206.1 | 206.1 | 0.0 | 0.0 |
| 2 | 31 | 01 June 2025 | 21 April 2025 | 648.61 | 180.04 | 0.0 | 0.0 | 0.0 | 180.04 | 180.04 | 180.04 | 0.0 | 0.0 |
| 3 | 30 | 01 July 2025 | 21 April 2025 | 468.57 | 180.04 | 0.0 | 0.0 | 0.0 | 180.04 | 180.04 | 180.04 | 0.0 | 0.0 |
| 4 | 31 | 01 August 2025 | 21 April 2025 | 288.53 | 180.04 | 0.0 | 0.0 | 0.0 | 180.04 | 180.04 | 180.04 | 0.0 | 0.0 |
| 5 | 31 | 01 September 2025 | 22 April 2025 | 108.49 | 180.04 | 0.0 | 0.0 | 0.0 | 180.04 | 180.04 | 180.04 | 0.0 | 0.0 |
| 6 | 30 | 01 October 2025 | 22 April 2025 | 0.0 | 108.49 | 1.06 | 0.0 | 0.0 | 109.55 | 109.55 | 109.55 | 0.0 | 0.0 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 1000.0 | 9.75 | 0.0 | 25.0 | 1034.75 | 1034.75 | 1034.75 | 0.0 | 0.0 |
| 1000.0 | 10.81 | 0.0 | 25.0 | 1035.81 | 1035.81 | 1035.81 | 0.0 | 0.0 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 April 2025 | Disbursement | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | false | false |
@@ -672,8 +672,9 @@ Feature: Loan interest pause on repayment schedule
| 14 April 2025 | Accrual | 0.75 | 0.0 | 0.75 | 0.0 | 0.0 | 0.0 | false | false |
| 20 April 2025 | Accrual | 25.0 | 0.0 | 0.0 | 0.0 | 25.0 | 0.0 | false | false |
| 21 April 2025 | Repayment | 800.0 | 765.25 | 9.75 | 0.0 | 25.0 | 234.75 | false | false |
| 22 April 2025 | Payout Refund | 400.0 | 234.75 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
| 23 April 2025 | Credit Balance Refund | 165.25 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
| 22 April 2025 | Payout Refund | 400.0 | 234.75 | 1.06 | 0.0 | 0.0 | 0.0 | false | false |
| 22 April 2025 | Accrual | 1.06 | 0.0 | 1.06 | 0.0 | 0.0 | 0.0 | false | false |
| 23 April 2025 | Credit Balance Refund | 164.19 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
Then Loan status will be "CLOSED_OBLIGATIONS_MET"
@TestRailId:C3627
@@ -1570,10 +1570,8 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
} else {
lastOverdueBalanceChange = currentDate;
}
if (DateUtils.isBefore(ctx.getModel().lastOverdueBalanceChange(), toDate)) {
emiCalculator.addBalanceCorrection(ctx.getModel(), lastOverdueBalanceChange, aggregatedOverDuePrincipal.negated());
ctx.getModel().lastOverdueBalanceChange(lastOverdueBalanceChange);
}
emiCalculator.addBalanceCorrection(ctx.getModel(), lastOverdueBalanceChange, aggregatedOverDuePrincipal.negated());
ctx.getModel().lastOverdueBalanceChange(lastOverdueBalanceChange);
}
}
@@ -1599,10 +1597,32 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
if (loanTransaction.isRepaymentLikeType() || loanTransaction.isInterestWaiver() || loanTransaction.isRecoveryRepayment()) {
loanTransaction.resetDerivedComponents();
}
calculateUnrecognizedInterestForClosedPeriodByInterestRecalculationStrategy(loanTransaction, transactionCtx);
Money transactionAmountUnprocessed = loanTransaction.getAmount(transactionCtx.getCurrency());
processTransaction(loanTransaction, transactionCtx, transactionAmountUnprocessed);
}
private void calculateUnrecognizedInterestForClosedPeriodByInterestRecalculationStrategy(LoanTransaction loanTransaction,
TransactionCtx transactionCtx) {
if (transactionCtx instanceof ProgressiveTransactionCtx progressiveTransactionCtx && progressiveTransactionCtx.isPrepayAttempt()
&& loanTransaction.isRepaymentLikeType() && loanTransaction.getLoan().getLoanInterestRecalculationDetails()
.getPreCloseInterestCalculationStrategy().calculateTillRestFrequencyEnabled()) {
Optional<RepaymentPeriod> oCurrentRepaymentPeriod = progressiveTransactionCtx.getModel().repaymentPeriods().stream()
.filter(rm -> DateUtils.isDateInRangeFromInclusiveToExclusive(rm.getFromDate(), rm.getDueDate(),
loanTransaction.getTransactionDate()))
.findFirst();
if (oCurrentRepaymentPeriod.isPresent() && oCurrentRepaymentPeriod.get().isFullyPaid()) {
RepaymentPeriod currentRepaymentPeriod = oCurrentRepaymentPeriod.get();
OutstandingDetails outstandingAmountsTillDate = emiCalculator
.getOutstandingAmountsTillDate(progressiveTransactionCtx.getModel(), currentRepaymentPeriod.getDueDate());
if (outstandingAmountsTillDate.getOutstandingInterest().isGreaterThanZero()) {
currentRepaymentPeriod.setFutureUnrecognizedInterest(outstandingAmountsTillDate.getOutstandingInterest());
}
}
}
}
private LoanTransactionToRepaymentScheduleMapping getTransactionMapping(
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings, LoanTransaction loanTransaction,
LoanRepaymentScheduleInstallment currentInstallment, MonetaryCurrency currency) {
@@ -1751,26 +1771,28 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
final LoanRepaymentScheduleInstallment currentInstallment = loan.getRelatedRepaymentScheduleInstallment(transactionDate);
if (!installments.isEmpty() && transactionDate.isBefore(loan.getMaturityDate())) {
if (transactionCtx instanceof ProgressiveTransactionCtx progressiveTransactionCtx
&& loanTransaction.getLoan().isInterestBearingAndInterestRecalculationEnabled()) {
final BigDecimal interestOutstanding = currentInstallment.getInterestOutstanding(loan.getCurrency()).getAmount();
final BigDecimal newInterest = emiCalculator.getPeriodInterestTillDate(progressiveTransactionCtx.getModel(),
currentInstallment.getDueDate(), transactionDate, true).getAmount();
if (interestOutstanding.compareTo(BigDecimal.ZERO) > 0 || newInterest.compareTo(BigDecimal.ZERO) > 0) {
currentInstallment.updateInterestCharged(newInterest);
}
} else {
final BigDecimal totalInterest = currentInstallment.getInterestOutstanding(transactionCtx.getCurrency()).getAmount();
if (totalInterest.compareTo(BigDecimal.ZERO) > 0) {
final long totalDaysInPeriod = ChronoUnit.DAYS.between(currentInstallment.getFromDate(),
currentInstallment.getDueDate());
final long daysTillChargeOff = ChronoUnit.DAYS.between(currentInstallment.getFromDate(), transactionDate);
if (currentInstallment.isNotFullyPaidOff()) {
if (transactionCtx instanceof ProgressiveTransactionCtx progressiveTransactionCtx
&& loanTransaction.getLoan().isInterestBearingAndInterestRecalculationEnabled()) {
final BigDecimal interestOutstanding = currentInstallment.getInterestOutstanding(loan.getCurrency()).getAmount();
final BigDecimal newInterest = emiCalculator.getPeriodInterestTillDate(progressiveTransactionCtx.getModel(),
currentInstallment.getDueDate(), transactionDate, true).getAmount();
if (interestOutstanding.compareTo(BigDecimal.ZERO) > 0 || newInterest.compareTo(BigDecimal.ZERO) > 0) {
currentInstallment.updateInterestCharged(newInterest);
}
} else {
final BigDecimal totalInterest = currentInstallment.getInterestOutstanding(transactionCtx.getCurrency()).getAmount();
if (totalInterest.compareTo(BigDecimal.ZERO) > 0) {
final long totalDaysInPeriod = ChronoUnit.DAYS.between(currentInstallment.getFromDate(),
currentInstallment.getDueDate());
final long daysTillChargeOff = ChronoUnit.DAYS.between(currentInstallment.getFromDate(), transactionDate);
final MathContext mc = MoneyHelper.getMathContext();
final Money interestTillChargeOff = Money.of(transactionCtx.getCurrency(), totalInterest
.divide(BigDecimal.valueOf(totalDaysInPeriod), mc).multiply(BigDecimal.valueOf(daysTillChargeOff), mc), mc);
final MathContext mc = MoneyHelper.getMathContext();
final Money interestTillChargeOff = Money.of(transactionCtx.getCurrency(), totalInterest
.divide(BigDecimal.valueOf(totalDaysInPeriod), mc).multiply(BigDecimal.valueOf(daysTillChargeOff), mc), mc);
currentInstallment.updateInterestCharged(interestTillChargeOff.getAmount());
currentInstallment.updateInterestCharged(interestTillChargeOff.getAmount());
}
}
}
@@ -1790,6 +1812,21 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
currentInstallment.updatePrincipal(MathUtil.nullToZero(currentInstallment.getPrincipal()).add(futurePrincipal));
if (currentInstallment.isObligationsMet()) {
final BigDecimal futureOutstandingPrincipal = futureInstallments.stream()
.map(installment -> installment.getPrincipalOutstanding(transactionCtx.getCurrency()).getAmount())
.filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
final BigDecimal futureTotalPaidInAdvance = futureInstallments.stream()
.map(LoanRepaymentScheduleInstallment::getTotalPaidInAdvance).filter(Objects::nonNull)
.reduce(ZERO, BigDecimal::add);
currentInstallment
.setPrincipalCompleted(MathUtil.nullToZero(currentInstallment.getPrincipal()).subtract(futureOutstandingPrincipal));
currentInstallment.setTotalPaidInAdvance(
MathUtil.nullToZero(currentInstallment.getTotalPaidInAdvance()).add(futureTotalPaidInAdvance));
}
final List<LoanRepaymentScheduleInstallment> installmentsUpToTransactionDate = installments.stream()
.filter(installment -> transactionDate.isAfter(installment.getFromDate()))
.collect(Collectors.toCollection(ArrayList::new));
@@ -1817,7 +1854,8 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
}
}
transactionCtx.getInstallments().stream().filter(installment -> installment.getFromDate().isBefore(transactionDate))
transactionCtx.getInstallments().stream()
.filter(installment -> installment.getFromDate().isBefore(transactionDate) && installment.isNotFullyPaidOff())
.filter(installment -> transactionsToBeReprocessed.stream()
.anyMatch(transaction -> transaction.getLoanTransactionToRepaymentScheduleMappings().stream().anyMatch(
mapping -> mapping.getInstallment().getInstallmentNumber().equals(installment.getInstallmentNumber()))))
@@ -1835,8 +1873,8 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
newTransaction.updateLoan(loan);
loan.getLoanTransactions().add(newTransaction);
}
loanBalanceService.updateLoanSummaryDerivedFields(loan);
}
loanBalanceService.updateLoanSummaryDerivedFields(loan);
}
}
@@ -2870,9 +2908,14 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
.filter(repaymentPeriod -> previousInstallmentsMapping.stream()
.anyMatch(installment -> installment.getFromDate().equals(repaymentPeriod.getFromDate())))
.forEach(RepaymentPeriod::resetDerivedComponents);
emiCalculator.addBalanceCorrection(transactionCtx.getModel(), processTransaction.getTransactionDate(),
processTransaction.getPrincipalPortion(transactionCtx.getCurrency()));
processSingleTransaction(processTransaction, transactionCtx);
LoanRepaymentScheduleInstallment installment = processTransaction.getLoan()
.getRelatedRepaymentScheduleInstallment(processTransaction.getTransactionDate());
if (installment == null || installment.isNotFullyPaidOff()) {
emiCalculator.addBalanceCorrection(transactionCtx.getModel(), processTransaction.getTransactionDate(),
processTransaction.getPrincipalPortion(transactionCtx.getCurrency()));
processSingleTransaction(processTransaction, transactionCtx);
}
}
}