[ 
https://issues.apache.org/jira/browse/FINERACT-2990?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Sonigra Bhavya Hemendrabhai updated FINERACT-2990:
--------------------------------------------------
    Description: 
h3. Summary

HeavensFamilyLoanRepaymentScheduleTransactionProcessor.handleTransactionThatIsPaymentInAdvanceOfInstallment(),
 an early/advance repayment calculates the principal paid on an installment, 
but an accidental duplicate call to payPrincipalComponent() immediately 
overwrites principalPortion with 0.

As a result, the transaction is saved without any 
LoanTransactionToRepaymentScheduleMapping entries, corrupting the link between 
the repayment transaction and the installment schedule.
h3. Root Cause

In HeavensFamilyLoanRepaymentScheduleTransactionProcessor.java:

1. Lines 129–130:
{code:java}
if (currentInstallment.isPrincipalNotCompleted(currency)) {
    principalPortion = 
currentInstallment.payPrincipalComponent(transactionDate, 
transactionAmountRemaining);
    ...
    transactionAmountRemaining = 
transactionAmountRemaining.minus(principalPortion);
}
{code}
principalPortion is calculated (e.g. $100), and transactionAmountRemaining is 
decremented (e.g. to $0).

2. Lines 142–144:
{code:java}
// 1. pay of principal with over payment.
principalPortion = currentInstallment.payPrincipalComponent(transactionDate, 
transactionAmountRemaining);
transactionAmountRemaining = transactionAmountRemaining.minus(principalPortion);
{code}
Because transactionAmountRemaining is 0 (and the installment principal was 
already paid), currentInstallment.payPrincipalComponent(...) returns 0. This 
overwrites principalPortion from $100 to $0.

3. Lines 157–160:
{code:java}
if 
(principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero())
 {
    
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(...));
}
{code}
Because principalPortion was clobbered to 0, this condition evaluates to false, 
and no LoanTransactionToRepaymentScheduleMapping is created.

Additionally, line 137 calls loanTransaction.updateComponents(...) inside the 
if block, and line 156 calls loanTransaction.updateComponents(...) again 
unconditionally at the end of the method.
h3. Expected Behavior
 * principalPortion should not be overwritten.
 * LoanTransactionToRepaymentScheduleMapping should be created linking the 
advance repayment transaction to the paid installment with the proper principal 
amount.
 * loanTransaction.updateComponents(...) should only be called once at the end 
of the method.

h3. Proposed Fix

1. Remove lines 142–144 (the duplicate principal payoff lines).
2. Remove line 137 so updateComponents is called only once at the end of the 
method (line 156), mirroring the fix in FINERACT-2861.
3. Add a unit test in 
HeavensFamilyLoanRepaymentScheduleTransactionProcessorTest verifying that an 
in-advance repayment populates repayment.getPrincipalPortion() and creates the 
schedule mapping.

  was:
h3. Summary

In 
HeavensFamilyLoanRepaymentScheduleTransactionProcessor.handleTransactionThatIsPaymentInAdvanceOfInstallment(),
 an early/advance repayment calculates the principal paid on an installment, 
but an accidental duplicate call to payPrincipalComponent() immediately 
overwrites principalPortion with 0. 

As a result, the transaction is saved without any 
LoanTransactionToRepaymentScheduleMapping entries, corrupting the link between 
the repayment transaction and the installment schedule.


h3. Root Cause

In HeavensFamilyLoanRepaymentScheduleTransactionProcessor.java:

1. Lines 129–130:
{code:java}
if (currentInstallment.isPrincipalNotCompleted(currency)) {
    principalPortion = 
currentInstallment.payPrincipalComponent(transactionDate, 
transactionAmountRemaining);
    ...
    transactionAmountRemaining = 
transactionAmountRemaining.minus(principalPortion);
}
{code}
principalPortion is calculated (e.g. $100), and transactionAmountRemaining is 
decremented (e.g. to $0).

2. Lines 142–144:
{code:java}
// 1. pay of principal with over payment.
principalPortion = currentInstallment.payPrincipalComponent(transactionDate, 
transactionAmountRemaining);
transactionAmountRemaining = transactionAmountRemaining.minus(principalPortion);
{code}
Because transactionAmountRemaining is 0 (and the installment principal was 
already paid), currentInstallment.payPrincipalComponent(...) returns 0. This 
overwrites principalPortion from $100 to $0.

3. Lines 157–160:
{code:java}
if 
(principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero())
 {
    
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(...));
}
{code}
Because principalPortion was clobbered to 0, this condition evaluates to false, 
and no LoanTransactionToRepaymentScheduleMapping is created.

Additionally, line 137 calls loanTransaction.updateComponents(...) inside the 
if block, and line 156 calls loanTransaction.updateComponents(...) again 
unconditionally at the end of the method.


h3. Expected Behavior

* principalPortion should not be overwritten.
* LoanTransactionToRepaymentScheduleMapping should be created linking the 
advance repayment transaction to the paid installment with the proper principal 
amount.
* loanTransaction.updateComponents(...) should only be called once at the end 
of the method.


h3. Proposed Fix

1. Remove lines 142–144 (the duplicate principal payoff lines).
2. Remove line 137 so updateComponents is called only once at the end of the 
method (line 156), mirroring the fix in FINERACT-2861.
3. Add a unit test in 
HeavensFamilyLoanRepaymentScheduleTransactionProcessorTest verifying that an 
in-advance repayment populates repayment.getPrincipalPortion() and creates the 
schedule mapping.



> HeavensFamily: Advance repayment clobbers principalPortion and skips schedule 
> mapping creation
> ----------------------------------------------------------------------------------------------
>
>                 Key: FINERACT-2990
>                 URL: https://issues.apache.org/jira/browse/FINERACT-2990
>             Project: Apache Fineract
>          Issue Type: Bug
>          Components: Loan
>    Affects Versions: 1.16.0
>            Reporter: Sonigra Bhavya Hemendrabhai
>            Assignee: Sonigra Bhavya Hemendrabhai
>            Priority: Major
>              Labels: loan, repayment
>
> h3. Summary
> HeavensFamilyLoanRepaymentScheduleTransactionProcessor.handleTransactionThatIsPaymentInAdvanceOfInstallment(),
>  an early/advance repayment calculates the principal paid on an installment, 
> but an accidental duplicate call to payPrincipalComponent() immediately 
> overwrites principalPortion with 0.
> As a result, the transaction is saved without any 
> LoanTransactionToRepaymentScheduleMapping entries, corrupting the link 
> between the repayment transaction and the installment schedule.
> h3. Root Cause
> In HeavensFamilyLoanRepaymentScheduleTransactionProcessor.java:
> 1. Lines 129–130:
> {code:java}
> if (currentInstallment.isPrincipalNotCompleted(currency)) {
>     principalPortion = 
> currentInstallment.payPrincipalComponent(transactionDate, 
> transactionAmountRemaining);
>     ...
>     transactionAmountRemaining = 
> transactionAmountRemaining.minus(principalPortion);
> }
> {code}
> principalPortion is calculated (e.g. $100), and transactionAmountRemaining is 
> decremented (e.g. to $0).
> 2. Lines 142–144:
> {code:java}
> // 1. pay of principal with over payment.
> principalPortion = currentInstallment.payPrincipalComponent(transactionDate, 
> transactionAmountRemaining);
> transactionAmountRemaining = 
> transactionAmountRemaining.minus(principalPortion);
> {code}
> Because transactionAmountRemaining is 0 (and the installment principal was 
> already paid), currentInstallment.payPrincipalComponent(...) returns 0. This 
> overwrites principalPortion from $100 to $0.
> 3. Lines 157–160:
> {code:java}
> if 
> (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero())
>  {
>     
> transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(...));
> }
> {code}
> Because principalPortion was clobbered to 0, this condition evaluates to 
> false, and no LoanTransactionToRepaymentScheduleMapping is created.
> Additionally, line 137 calls loanTransaction.updateComponents(...) inside the 
> if block, and line 156 calls loanTransaction.updateComponents(...) again 
> unconditionally at the end of the method.
> h3. Expected Behavior
>  * principalPortion should not be overwritten.
>  * LoanTransactionToRepaymentScheduleMapping should be created linking the 
> advance repayment transaction to the paid installment with the proper 
> principal amount.
>  * loanTransaction.updateComponents(...) should only be called once at the 
> end of the method.
> h3. Proposed Fix
> 1. Remove lines 142–144 (the duplicate principal payoff lines).
> 2. Remove line 137 so updateComponents is called only once at the end of the 
> method (line 156), mirroring the fix in FINERACT-2861.
> 3. Add a unit test in 
> HeavensFamilyLoanRepaymentScheduleTransactionProcessorTest verifying that an 
> in-advance repayment populates repayment.getPrincipalPortion() and creates 
> the schedule mapping.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to