Skip to content

FINERACT-2455: Add WC near-breach evaluation business step#5849

Open
oleksii-novikov-onix wants to merge 2 commits into
apache:developfrom
openMF:FINERACT-2455/wc-near-breach-evaluation-business-step
Open

FINERACT-2455: Add WC near-breach evaluation business step#5849
oleksii-novikov-onix wants to merge 2 commits into
apache:developfrom
openMF:FINERACT-2455/wc-near-breach-evaluation-business-step

Conversation

@oleksii-novikov-onix
Copy link
Copy Markdown
Contributor

Description

Describe the changes made and why they were made. (Ignore if these details are present on the associated Apache Fineract JIRA ticket.)

Checklist

Please make sure these boxes are checked before submitting your pull request - thanks!

  • Write the commit message as per our guidelines
  • Acknowledge that we will not review PRs that are not passing the build ("green") - it is your responsibility to get a proposed PR to pass the build, not primarily the project's maintainers.
  • Create/update unit or integration tests for verifying the changes made.
  • Follow our coding conventions.
  • Add required Swagger annotation and update API documentation at fineract-provider/src/main/resources/static/legacy-docs/apiLive.htm with details of any API changes
  • This PR must not be a "code dump". Large changes can be made in a branch, with assistance. Ask for help on the developer mailing list.

Your assigned reviewer(s) will follow our guidelines for code reviews.

Copy link
Copy Markdown
Contributor

@galovics galovics left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not convinced CREDIT_BALANCE_REFUND should be in REDUCING_TRANSACTION_TYPES here.

A CREDIT_BALANCE_REFUND is the bank returning an overpayment to the borrower - money leaving the loan, not an inbound payment. Summing it in paidInWindow would make the borrower appear to have paid more than they actually did, and could suppress a near-breach trigger that should have fired. None of the e2e scenarios exercise this path, so a bug here would go undetected.

Wouldn't it make more sense to only count REPAYMENT and GOODWILL_CREDIT? (And worth a double-check on GOODWILL_CREDIT too - that's a bank-side write-off, not a borrower payment, though at least it goes the right direction.)

https://github.com/apache/fineract/blob/FINERACT-2455/wc-near-breach-evaluation-business-step/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/service/WorkingCapitalLoanNearBreachEvaluationServiceImpl.java#L782-L783

@oleksii-novikov-onix oleksii-novikov-onix force-pushed the FINERACT-2455/wc-near-breach-evaluation-business-step branch from a743639 to 9ca4f57 Compare May 18, 2026 06:07
@oleksii-novikov-onix
Copy link
Copy Markdown
Contributor Author

@galovics Thanks, I removed CREDIT_BALANCE_REFUND

@oleksii-novikov-onix oleksii-novikov-onix force-pushed the FINERACT-2455/wc-near-breach-evaluation-business-step branch from 9ca4f57 to 55cc88c Compare May 18, 2026 12:13
@ruzeynalov ruzeynalov force-pushed the FINERACT-2455/wc-near-breach-evaluation-business-step branch from 55cc88c to ff9bfb2 Compare May 18, 2026 12:23
@oleksii-novikov-onix oleksii-novikov-onix marked this pull request as ready for review May 18, 2026 14:48
@oleksii-novikov-onix oleksii-novikov-onix force-pushed the FINERACT-2455/wc-near-breach-evaluation-business-step branch from ff9bfb2 to 0546770 Compare May 19, 2026 10:06
Comment on lines +85 to +86
final BigDecimal requiredCumulative = thresholdFraction.multiply(BigDecimal.valueOf(index + 1L), MoneyHelper.getMathContext())
.multiply(period.getMinPaymentAmount(), MoneyHelper.getMathContext());
Copy link
Copy Markdown
Contributor

@adamsaghy adamsaghy May 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can extract this calculation into a method for better readability + please use Money object for appropriate rounding and number of digist after decimal point.

anyPassed = true;
final BigDecimal requiredCumulative = thresholdFraction.multiply(BigDecimal.valueOf(index + 1L), MoneyHelper.getMathContext())
.multiply(period.getMinPaymentAmount(), MoneyHelper.getMathContext());
final BigDecimal paidCumulative = transactionRepository.sumPaymentsInWindow(loanId, period.getFromDate(), evalDate,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use Money object for appropriate rounding and number of digist after decimal point.

Comment on lines +41 to +46
final boolean isDisbursed = input.getDisbursementDetails().stream()
.map(WorkingCapitalLoanDisbursementDetails::getActualDisbursementDate).anyMatch(Objects::nonNull);
if (!isDisbursed) {
log.debug("Skipping near breach evaluation for WC loan {} - not yet disbursed", input.getId());
return input;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the WorkingCapitalLoan.loanStatus instead.

private final WorkingCapitalLoanNearBreachEvaluationService nearBreachEvaluationService;

@Override
public WorkingCapitalLoan execute(final WorkingCapitalLoan input) {
Copy link
Copy Markdown
Contributor

@adamsaghy adamsaghy May 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rename input field to something more relevant, like: "loan".

}

final LocalDate businessDate = DateUtils.getBusinessLocalDate();
nearBreachEvaluationService.evaluateNearBreach(input, businessDate.plusDays(1L));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why to increase the date by 1? COB date is the date on we evaluate the near-breach, am i missing something?

AND t.reversed = false
AND t.transactionType IN :reducingTypes
""")
BigDecimal sumPaymentsInWindow(@Param("loanId") Long loanId, @Param("fromDate") LocalDate fromDate, @Param("toDate") LocalDate toDate,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We dont need this. Paid amount is available on the breach schedule already.

@Override
public void evaluateBreachAndNearBreach(final WorkingCapitalLoan loan, final LocalDate businessDate) {
public void evaluateBreach(final WorkingCapitalLoan loan, final LocalDate businessDate) {
final List<WorkingCapitalLoanBreachSchedule> allPeriods = repository.findByLoanIdOrderByPeriodNumberAsc(loan.getId());
Copy link
Copy Markdown
Contributor

@adamsaghy adamsaghy May 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont think we need all periods. Fetch only the (one) relevant by business date, please

@ruzeynalov ruzeynalov force-pushed the FINERACT-2455/wc-near-breach-evaluation-business-step branch from 0546770 to eef3043 Compare May 19, 2026 12:38
@oleksii-novikov-onix oleksii-novikov-onix force-pushed the FINERACT-2455/wc-near-breach-evaluation-business-step branch from eef3043 to 406aa0e Compare May 19, 2026 14:58
@oleksii-novikov-onix oleksii-novikov-onix force-pushed the FINERACT-2455/wc-near-breach-evaluation-business-step branch from 406aa0e to 2801210 Compare May 19, 2026 18:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants