budaidev commented on code in PR #5032:
URL: https://github.com/apache/fineract/pull/5032#discussion_r2344231265


##########
fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java:
##########
@@ -2856,21 +2857,49 @@ private void handleReAge(LoanTransaction 
loanTransaction, TransactionCtx ctx) {
             adjustCalculatedPrincipal = outstandingPrincipalBalance.get()
                     
.minus(calculatedPrincipal.multipliedBy(loanTransaction.getLoanReAgeParameter().getNumberOfInstallments()));
         }
-        LoanRepaymentScheduleInstallment lastNormalInstallment = 
installments.stream().filter(i -> !i.isDownPayment())
-                .reduce((first, second) -> second).orElseThrow();
-        LoanRepaymentScheduleInstallment reAgedInstallment = 
LoanRepaymentScheduleInstallment.newReAgedInstallment(
-                lastNormalInstallment.getLoan(), 
lastNormalInstallment.getInstallmentNumber() + 1, 
lastNormalInstallment.getDueDate(),
-                loanTransaction.getLoanReAgeParameter().getStartDate(), 
calculatedPrincipal.getAmount());
-        installments.add(reAgedInstallment);
+        final LoanRepaymentScheduleInstallment lastNormalInstallment = 
installments.stream() //
+                .filter(i -> !i.isDownPayment() && 
i.getDueDate().isBefore(loanTransaction.getTransactionDate())) //
+                .reduce((first, second) -> second) //
+                .orElseThrow();
+
+        final LocalDate startDate = 
loanTransaction.getLoanReAgeParameter().getStartDate();
+        final Optional<LoanRepaymentScheduleInstallment> additionalInstallment 
= findAdditionalForFrequency(installments, startDate,
+                loanTransaction.getLoanReAgeParameter());
+
+        LoanRepaymentScheduleInstallment reAgedInstallment;
+        if (additionalInstallment.isPresent()) {
+            reAgedInstallment = 
convertAdditionalToReAged(additionalInstallment.get(), 
lastNormalInstallment.getDueDate(), startDate,
+                    calculatedPrincipal.getAmount());
+        } else {
+            final Optional<LoanRepaymentScheduleInstallment> 
existingAdditional = findPrincipalOnlyAdditional(installments, currency);
+            if (existingAdditional.isPresent()) {
+                reAgedInstallment = 
convertAdditionalToReAged(existingAdditional.get(), 
lastNormalInstallment.getDueDate(), startDate,
+                        calculatedPrincipal.getAmount());
+            } else {
+                reAgedInstallment = 
LoanRepaymentScheduleInstallment.newReAgedInstallment(lastNormalInstallment.getLoan(),
+                        lastNormalInstallment.getInstallmentNumber() + 1, 
lastNormalInstallment.getDueDate(), startDate,
+                        calculatedPrincipal.getAmount());
+                installments.add(reAgedInstallment);
+            }
+        }
         reAgedInstallment.updateObligationsMet(currency, 
loanTransaction.getTransactionDate());
 
         for (int i = 1; i < 
loanTransaction.getLoanReAgeParameter().getNumberOfInstallments(); i++) {
-            LocalDate calculatedDueDate = 
calculateReAgedInstallmentDueDate(loanTransaction.getLoanReAgeParameter(),
+            final LocalDate calculatedDueDate = 
calculateReAgedInstallmentDueDate(loanTransaction.getLoanReAgeParameter(),
                     reAgedInstallment.getDueDate());
-            reAgedInstallment = 
LoanRepaymentScheduleInstallment.newReAgedInstallment(reAgedInstallment.getLoan(),
-                    reAgedInstallment.getInstallmentNumber() + 1, 
reAgedInstallment.getDueDate(), calculatedDueDate,
-                    calculatedPrincipal.getAmount());
-            installments.add(reAgedInstallment);
+
+            final Optional<LoanRepaymentScheduleInstallment> 
additionalInstallment2 = findAdditionalForFrequency(installments,
+                    calculatedDueDate, 
loanTransaction.getLoanReAgeParameter());
+
+            if (additionalInstallment2.isPresent()) {

Review Comment:
   This logic is almost the same as the additionalInstallment one, consider to 
extract this logic



##########
fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java:
##########
@@ -2856,21 +2857,49 @@ private void handleReAge(LoanTransaction 
loanTransaction, TransactionCtx ctx) {
             adjustCalculatedPrincipal = outstandingPrincipalBalance.get()
                     
.minus(calculatedPrincipal.multipliedBy(loanTransaction.getLoanReAgeParameter().getNumberOfInstallments()));
         }
-        LoanRepaymentScheduleInstallment lastNormalInstallment = 
installments.stream().filter(i -> !i.isDownPayment())
-                .reduce((first, second) -> second).orElseThrow();
-        LoanRepaymentScheduleInstallment reAgedInstallment = 
LoanRepaymentScheduleInstallment.newReAgedInstallment(
-                lastNormalInstallment.getLoan(), 
lastNormalInstallment.getInstallmentNumber() + 1, 
lastNormalInstallment.getDueDate(),
-                loanTransaction.getLoanReAgeParameter().getStartDate(), 
calculatedPrincipal.getAmount());
-        installments.add(reAgedInstallment);
+        final LoanRepaymentScheduleInstallment lastNormalInstallment = 
installments.stream() //
+                .filter(i -> !i.isDownPayment() && 
i.getDueDate().isBefore(loanTransaction.getTransactionDate())) //
+                .reduce((first, second) -> second) //
+                .orElseThrow();
+
+        final LocalDate startDate = 
loanTransaction.getLoanReAgeParameter().getStartDate();
+        final Optional<LoanRepaymentScheduleInstallment> additionalInstallment 
= findAdditionalForFrequency(installments, startDate,
+                loanTransaction.getLoanReAgeParameter());
+
+        LoanRepaymentScheduleInstallment reAgedInstallment;
+        if (additionalInstallment.isPresent()) {
+            reAgedInstallment = 
convertAdditionalToReAged(additionalInstallment.get(), 
lastNormalInstallment.getDueDate(), startDate,
+                    calculatedPrincipal.getAmount());
+        } else {
+            final Optional<LoanRepaymentScheduleInstallment> 
existingAdditional = findPrincipalOnlyAdditional(installments, currency);
+            if (existingAdditional.isPresent()) {
+                reAgedInstallment = 
convertAdditionalToReAged(existingAdditional.get(), 
lastNormalInstallment.getDueDate(), startDate,
+                        calculatedPrincipal.getAmount());
+            } else {
+                reAgedInstallment = 
LoanRepaymentScheduleInstallment.newReAgedInstallment(lastNormalInstallment.getLoan(),
+                        lastNormalInstallment.getInstallmentNumber() + 1, 
lastNormalInstallment.getDueDate(), startDate,
+                        calculatedPrincipal.getAmount());
+                installments.add(reAgedInstallment);
+            }
+        }
         reAgedInstallment.updateObligationsMet(currency, 
loanTransaction.getTransactionDate());
 
         for (int i = 1; i < 
loanTransaction.getLoanReAgeParameter().getNumberOfInstallments(); i++) {
-            LocalDate calculatedDueDate = 
calculateReAgedInstallmentDueDate(loanTransaction.getLoanReAgeParameter(),
+            final LocalDate calculatedDueDate = 
calculateReAgedInstallmentDueDate(loanTransaction.getLoanReAgeParameter(),
                     reAgedInstallment.getDueDate());
-            reAgedInstallment = 
LoanRepaymentScheduleInstallment.newReAgedInstallment(reAgedInstallment.getLoan(),
-                    reAgedInstallment.getInstallmentNumber() + 1, 
reAgedInstallment.getDueDate(), calculatedDueDate,
-                    calculatedPrincipal.getAmount());
-            installments.add(reAgedInstallment);
+
+            final Optional<LoanRepaymentScheduleInstallment> 
additionalInstallment2 = findAdditionalForFrequency(installments,

Review Comment:
   Can we have a more descriptive name here? It is pretty hard to understand 
the logic



##########
fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java:
##########
@@ -2887,6 +2916,43 @@ private void 
reprocessInstallmentsOrder(List<LoanRepaymentScheduleInstallment> i
                 .forEachOrdered(i -> 
i.updateInstallmentNumber(counter.getAndIncrement()));
     }
 
+    private LoanRepaymentScheduleInstallment convertAdditionalToReAged(final 
LoanRepaymentScheduleInstallment installment,
+            final LocalDate fromDate, final LocalDate dueDate, final 
BigDecimal principalAmount) {
+        installment.setAdditional(false);
+        installment.setReAged(true);
+        installment.updateFromDate(fromDate);
+        installment.updateDueDate(dueDate);
+        installment.updatePrincipal(principalAmount);
+        return installment;
+    }
+
+    private Optional<LoanRepaymentScheduleInstallment> 
findAdditionalForFrequency(final List<LoanRepaymentScheduleInstallment> 
installments,
+            final LocalDate targetDueDate, final LoanReAgeParameter 
reAgeParameter) {
+        return 
installments.stream().filter(LoanRepaymentScheduleInstallment::isAdditional).filter(ai
 -> {
+            final LocalDate dueDate = ai.getDueDate();
+            return switch (reAgeParameter.getFrequencyType()) {
+                case DAYS -> dueDate.isEqual(targetDueDate);
+                case WEEKS -> {
+                    final int tw = 
targetDueDate.get(WeekFields.ISO.weekOfWeekBasedYear());

Review Comment:
   tw and ty variables can be outside of the loop since they won't change 
through the function call



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