chinmaya samantara created FINERACT-2971:
--------------------------------------------

             Summary: Foreclosure of a progressive loan always fails with HTTP 
500 (NullPointerException on ScheduleGeneratorDTO)
                 Key: FINERACT-2971
                 URL: https://issues.apache.org/jira/browse/FINERACT-2971
             Project: Apache Fineract
          Issue Type: Bug
            Reporter: chinmaya samantara
            Assignee: chinmaya samantara


Foreclosing a loan that uses the progressive schedule (advanced payment 
allocation) always fails. The API answers with a bare HTTP 500, nothing is 
logged, and the loan stays Active. The same request on a cumulative loan closes 
it as expected. The foreclosure template still works, so the UI shows the 
payoff amount and then fails on submit.

*Steps to reproduce* (develop 0df2ef786f, PostgreSQL)

1. Loan product with loanScheduleType PROGRESSIVE and 
transactionProcessingStrategyCode advanced-payment-allocation-strategy (no 
interest recalculation), 6 monthly installments, 2% per month.
2. Loan of 1200 disbursed on 01 March 2026.
3. Foreclose it:
{code}
POST /fineract-provider/api/v1/loans/{loanId}/transactions?command=foreclosure
{ "transactionDate": "01 August 2026", "dateFormat": "dd MMMM yyyy", "locale": 
"en" }
{code}

Actual result: HTTP 500 with Spring's default body (timestamp, status, error, 
path) and no log entry. The loan stays Active.
Expected result: a repayment for the foreclosure amount is created and the loan 
is Closed (obligations met), like for a cumulative loan.

{{GET /loans/{loanId}/transactions/template?command=foreclosure}} works for the 
same loan (amount 1281.19). The same POST on a cumulative product closes the 
loan.

Sending the request through the batch API shows the exception:
{code}
POST /fineract-provider/api/v1/batches?enclosingTransaction=false
-> statusCode 500, body: {"Exception":"Cannot invoke 
\"org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO.getCalendar()\"
 because \"scheduleGeneratorDTO\" is null"}
{code}

*Cause*

LoanAccountDomainServiceJpa.foreCloseLoan() passes a hard-coded null:
{code:java}
final ScheduleGeneratorDTO scheduleGeneratorDTO = null;
...
handleForeClosureTransactions(loan, payment, scheduleGeneratorDTO);
{code}
handleForeClosureTransactions() hands it to 
loanDownPaymentHandlerService.handleRepaymentOrRecoveryOrWaiverTransaction(). 
For progressive loans the schedule is rebuilt through LoanMapper -> 
LoanTermVariationsMapper.constructLoanApplicationTerms(scheduleGeneratorDTO, 
loan), whose first lines call scheduleGeneratorDTO.getCalendar() 
(LoanTermVariationsMapper.java:74), so it throws a NullPointerException.

*Suggested fix*

Build the DTO in foreCloseLoan() (for example with 
loanUtilService.buildScheduleGeneratorDTO(loan, null)) instead of passing null, 
and add a test that forecloses a progressive loan.




--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to