adamsaghy commented on code in PR #6109:
URL: https://github.com/apache/fineract/pull/6109#discussion_r3550559243


##########
fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/service/WorkingCapitalLoanBreachScheduleServiceImpl.java:
##########
@@ -306,32 +304,51 @@ public void recalculatePeriodsForPauses(final 
WorkingCapitalLoan loan) {
     }
 
     @Override
-    public void reEvaluateAfterEnable(final WorkingCapitalLoan loan, final 
LocalDate enableDate) {
-        final Optional<WorkingCapitalBreach> breachOpt = getBreachConfig(loan);
-        if (breachOpt.isEmpty()) {
+    public void reprocessDelinquencySchedule(final WorkingCapitalLoan loan) {
+        final LocalDate businessDate = DateUtils.getBusinessLocalDate();
+        generateNextPeriodIfNeeded(loan, businessDate);
+        List<WorkingCapitalLoanBreachSchedule> breachPeriods = 
resetAllPeriodsForReprocessing(loan.getId());
+
+        final List<TransactionDateAndAmountHolder> 
transactionDateAndAmountHolderList = transactionRepository
+                .fetchTransactionDateAndAmount(loan.getId(), 
LoanTransactionType.getRepaymentLikeTransactionTypes());
+        if (transactionDateAndAmountHolderList.isEmpty()) {
+            breachPeriods.forEach(period -> {
+                recomputeBreach(period, businessDate);
+            });
             return;
         }
-        generateNextPeriodIfNeeded(loan, enableDate);
-        final List<WorkingCapitalLoanBreachSchedule> periods = 
repository.findByLoanIdOrderByPeriodNumberAsc(loan.getId());
-        final Optional<LocalDate> lastResetDate = 
activeBreachResetResolver.findLatestActiveResetDate(loan.getId());
-        periods.stream().filter(period -> isNotNullifiedByActiveReset(period, 
lastResetDate)).forEach(period -> {
-            rebuildPaidAmountFromTransactions(period, lastResetDate);
-            recomputeBreach(period, enableDate);
+
+        List<TransactionDateAndAmountHolder> 
remappedTransactionDateAndAmountHolderList = new ArrayList<>();
+        breachPeriods.forEach(period -> {
+            BigDecimal sumAmount = 
transactionDateAndAmountHolderList.stream().parallel()
+                    .filter(holder -> 
DateUtils.isDateInRangeInclusive(holder.transactionDate(), 
period.getFromDate(), period.getToDate()))
+                    
.map(TransactionDateAndAmountHolder::transactionAmount).reduce(BigDecimal.ZERO, 
BigDecimal::add);
+            remappedTransactionDateAndAmountHolderList.add(new 
TransactionDateAndAmountHolder(period.getToDate(), sumAmount));
         });
-        repository.saveAll(periods);
-        log.debug("Re-evaluated breach schedule for WC loan {} after enable as 
of {}", loan.getId(), enableDate);
+
+        
remappedTransactionDateAndAmountHolderList.forEach(transactionDateAndAmountHolder
 -> {
+            applyRepayment(loan.getId(), 
transactionDateAndAmountHolder.transactionDate(),
+                    transactionDateAndAmountHolder.transactionAmount());
+        });
+
+        evaluateExpiredPeriods(loan, breachPeriods);
     }
 
-    private boolean isNotNullifiedByActiveReset(final 
WorkingCapitalLoanBreachSchedule period, final Optional<LocalDate> 
lastResetDate) {
-        return lastResetDate.map(resetDate -> 
!period.getToDate().isBefore(resetDate)).orElse(true);
+    private List<WorkingCapitalLoanBreachSchedule> 
resetAllPeriodsForReprocessing(final Long loanId) {
+        final List<WorkingCapitalLoanBreachSchedule> periods = 
repository.findByLoanIdOrderByPeriodNumberAsc(loanId);
+        for (final WorkingCapitalLoanBreachSchedule period : periods) {
+            period.setPaidAmount(BigDecimal.ZERO);
+            period.setOutstandingAmount(period.getMinPaymentAmount());
+            period.setBreach(null);
+        }
+        return periods;
     }
 
-    private void rebuildPaidAmountFromTransactions(final 
WorkingCapitalLoanBreachSchedule period, final Optional<LocalDate> 
lastResetDate) {
-        final LocalDate fromDate = lastResetDate.filter(resetDate -> 
resetDate.isAfter(period.getFromDate())).orElse(period.getFromDate());
-        final BigDecimal paidAmount = 
transactionRepository.sumBreachRelevantPaid(period.getLoan().getId(),
-                LoanTransactionType.getRepaymentLikeTransactionTypes(), 
fromDate, period.getToDate());
-        period.setPaidAmount(paidAmount);
-        
period.setOutstandingAmount(period.getMinPaymentAmount().subtract(paidAmount).max(BigDecimal.ZERO));
+    private void evaluateExpiredPeriods(WorkingCapitalLoan loan, 
List<WorkingCapitalLoanBreachSchedule> breachPeriods) {
+        breachPeriods.stream().filter(period -> period.getBreach() == 
null).toList().forEach(period -> {
+            boolean criteriaMet = 
period.getPaidAmount().compareTo(period.getMinPaymentAmount()) >= 0;
+            period.setBreach(criteriaMet);

Review Comment:
   Nice catch.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to