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


##########
fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/calc/ProgressiveEMICalculator.java:
##########
@@ -559,6 +566,92 @@ private void 
calculateEMIValueAndRateFactorsForDecliningBalanceInterestMethod(fi
         }
     }
 
+    @Override
+    public void updateModelRepaymentPeriodsDuringReAge(final 
ProgressiveLoanInterestScheduleModel scheduleModel,
+            final LoanTransaction loanTransaction, final LoanApplicationTerms 
loanApplicationTerms, final MathContext mc) {
+        final LoanReAgeParameter loanReAgeParameter = 
loanTransaction.getLoanReAgeParameter();
+        final LocalDate reAgingStartDate = loanReAgeParameter.getStartDate();
+        final LocalDate transactionDate = loanTransaction.getTransactionDate();
+        final List<RepaymentPeriod> existingRepaymentPeriods = 
scheduleModel.repaymentPeriods();
+
+        final List<RepaymentPeriod> periodsBeforeReAging = 
existingRepaymentPeriods.stream()
+                .filter(rp -> rp.getFromDate().isBefore(reAgingStartDate) && 
!rp.isFullyPaid()).toList();
+
+        periodsBeforeReAging.forEach(rp -> {
+            final InterestPeriod lastInterestPeriod = 
rp.getInterestPeriods().getLast();
+            
lastInterestPeriod.addBalanceCorrectionAmount(rp.getOutstandingPrincipal().negated());
+            rp.setEmi(rp.getTotalPaidAmount());
+        });
+
+        final LocalDate periodStartDate = switch 
(loanReAgeParameter.getFrequencyType()) {
+            case DAYS -> 
reAgingStartDate.minusDays(loanReAgeParameter.getFrequencyNumber());
+            case WEEKS -> 
reAgingStartDate.minusWeeks(loanReAgeParameter.getFrequencyNumber());
+            case MONTHS -> 
reAgingStartDate.minusMonths(loanReAgeParameter.getFrequencyNumber());
+            case YEARS -> 
reAgingStartDate.minusYears(loanReAgeParameter.getFrequencyNumber());
+            case WHOLE_TERM -> throw new IllegalStateException("Unexpected 
RecalculationFrequencyType: WHOLE_TERM");
+            case INVALID -> throw new IllegalStateException("Unexpected 
RecalculationFrequencyType: INVALID");
+        };
+
+        LocalDate disbursementDate = transactionDate;
+        if (!reAgingStartDate.isAfter(transactionDate)) {
+            disbursementDate = periodStartDate;
+        }
+
+        // generate list of proposed schedule due dates
+        final List<LoanScheduleModelRepaymentPeriod> expectedRepaymentPeriods 
= scheduledDateGenerator.generateRepaymentPeriods(mc,
+                periodStartDate, loanApplicationTerms, null);
+        final ProgressiveLoanInterestScheduleModel 
temporaryReAgedScheduleModel = generatePeriodInterestScheduleModel(
+                expectedRepaymentPeriods, 
loanApplicationTerms.toLoanProductRelatedDetailMinimumData(), null,
+                loanApplicationTerms.getInstallmentAmountInMultiplesOf(), mc);
+
+        addDisbursement(temporaryReAgedScheduleModel, 
EmiChangeOperation.disburse(disbursementDate, 
loanApplicationTerms.getPrincipal()));
+
+        final List<RepaymentPeriod> newPeriods = 
temporaryReAgedScheduleModel.repaymentPeriods();
+
+        if (newPeriods.isEmpty()) {
+            return;
+        }
+
+        final LocalDate reAgeDate = newPeriods.getFirst().getDueDate();
+        final Optional<RepaymentPeriod> firstExistingRepaymentPeriodOpt = 
existingRepaymentPeriods.stream()
+                .filter(period -> 
period.getDueDate().equals(reAgeDate)).findFirst();
+
+        for (final RepaymentPeriod newPeriod : newPeriods) {
+            final Optional<RepaymentPeriod> existingRepaymentPeriodOpt = 
existingRepaymentPeriods.stream().filter(
+                    period -> 
period.getFromDate().equals(newPeriod.getFromDate()) && 
period.getDueDate().equals(newPeriod.getDueDate()))
+                    .findFirst();
+            Optional<RepaymentPeriod> previousExistingRepaymentPeriodOpt = 
Optional.empty();
+            if (existingRepaymentPeriodOpt.isPresent() && 
firstExistingRepaymentPeriodOpt.isPresent()
+                    && 
existingRepaymentPeriodOpt.get().equals(firstExistingRepaymentPeriodOpt.get())) 
{
+                previousExistingRepaymentPeriodOpt = 
existingRepaymentPeriodOpt.get().getPrevious();
+            }
+
+            final Money newPrincipal = newPeriod.getDuePrincipal();
+            final Money newInterest = newPeriod.getDueInterest();
+
+            final RepaymentPeriod rp = RepaymentPeriod.create(
+                    
previousExistingRepaymentPeriodOpt.orElseGet(existingRepaymentPeriods::getLast),
 newPeriod.getFromDate(),
+                    newPeriod.getDueDate(), newPrincipal.add(newInterest), 
MoneyHelper.getMathContext(),
+                    loanTransaction.getLoan().getLoanProductRelatedDetail());
+            
rp.setTotalDisbursedAmount(scheduleModel.repaymentPeriods().getFirst().getTotalDisbursedAmount());
+
+            
existingRepaymentPeriodOpt.ifPresent(existingRepaymentPeriods::remove);
+            existingRepaymentPeriods.add(rp);
+            calculateRateFactorForRepaymentPeriod(rp, scheduleModel);
+        }
+
+        final RepaymentPeriod lastReAgedInstallment = newPeriods.getLast();
+        final List<RepaymentPeriod> reAgedRepaymentPeriods = 
existingRepaymentPeriods.stream()
+                .filter(repaymentPeriod -> 
(!repaymentPeriod.getFromDate().isBefore(reAgingStartDate)
+                        || 
repaymentPeriod.getDueDate().isEqual(reAgingStartDate))
+                        && 
!repaymentPeriod.getDueDate().isAfter(lastReAgedInstallment.getDueDate()))
+                .toList();
+
+        calculateOutstandingBalance(scheduleModel);
+        calculateLastUnpaidRepaymentPeriodEMI(scheduleModel, transactionDate);
+        checkAndAdjustEmiIfNeededOnRelatedRepaymentPeriods(scheduleModel, 
reAgedRepaymentPeriods);

Review Comment:
   Extract into a method and leave a short description what it does (like 
merging the newmodel and existing one together and after recalculate the 
balances).



-- 
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