airajena commented on code in PR #5523:
URL: https://github.com/apache/fineract/pull/5523#discussion_r2881788290


##########
fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java:
##########
@@ -484,6 +495,65 @@ public CommandProcessingResult approve(JsonCommand 
jsonCommand) {
         }
     }
 
+    private LoanScheduleDTO generateRescheduledLoanSchedule(final 
ScheduleGeneratorDTO scheduleGeneratorDTO, final Loan loan,
+            final LocalDate rescheduleFromDate, final MathContext mathContext,
+            final LoanRepaymentScheduleTransactionProcessor 
loanRepaymentScheduleTransactionProcessor) {
+        final LoanApplicationTerms loanApplicationTerms = 
loanTermVariationsMapper.constructLoanApplicationTerms(scheduleGeneratorDTO,
+                loan);
+        final BigDecimal annualNominalInterestRate = null;
+        final List<LoanTermVariationsData> loanTermVariations = new 
ArrayList<>();
+        
loanTermVariationsMapper.constructLoanTermVariations(scheduleGeneratorDTO.getFloatingRateDTO(),
 annualNominalInterestRate,
+                loanTermVariations, loan);
+        
loanApplicationTerms.getLoanTermVariations().setExceptionData(loanTermVariations);
+
+        final LoanScheduleGenerator loanScheduleGenerator = 
this.loanScheduleFactory.create(loanApplicationTerms.getLoanScheduleType(),
+                loanApplicationTerms.getInterestMethod());
+        return loanScheduleGenerator.rescheduleNextInstallments(mathContext, 
loanApplicationTerms, loan,
+                loanApplicationTerms.getHolidayDetailDTO(), 
loanRepaymentScheduleTransactionProcessor, rescheduleFromDate);
+    }
+
+    private void addAutoExtendRepaymentPeriodVariation(final 
LoanRescheduleRequest loanRescheduleRequest, final Loan loan,
+            final LocalDate rescheduleFromDate) {
+        final LoanTermVariations loanTermVariation = new 
LoanTermVariations(LoanTermVariationType.EXTEND_REPAYMENT_PERIOD.getValue(),
+                rescheduleFromDate, BigDecimal.ONE, null, false, loan, 
loan.getStatus().getValue(), true, null);
+        loan.getLoanTermVariations().add(loanTermVariation);
+        loanRescheduleRequest.getLoanRescheduleRequestToTermVariationMappings()
+                
.add(LoanRescheduleRequestToTermVariationMapping.createNew(loanRescheduleRequest,
 loanTermVariation));
+    }
+
+    private boolean isLastInstallmentAmountTooLarge(final LoanScheduleDTO 
loanScheduleDTO, final MonetaryCurrency currency,
+            final LocalDate rescheduleFromDate) {
+        final List<LoanRepaymentScheduleInstallment> installments = 
loanScheduleDTO.getInstallments();
+        if (installments == null || installments.size() < 2) {
+            return false;
+        }
+
+        final List<LoanRepaymentScheduleInstallment> rescheduledInstallments = 
new ArrayList<>();
+        for (LoanRepaymentScheduleInstallment installment : installments) {
+            if (installment.isDownPayment() || 
DateUtils.isBefore(installment.getDueDate(), rescheduleFromDate)) {
+                continue;
+            }
+            rescheduledInstallments.add(installment);
+        }
+
+        if (rescheduledInstallments.size() < 2) {
+            return false;
+        }
+
+        final LoanRepaymentScheduleInstallment lastInstallment = 
rescheduledInstallments.get(rescheduledInstallments.size() - 1);
+        BigDecimal maxPriorDueAmount = BigDecimal.ZERO;
+        for (int i = 0; i < rescheduledInstallments.size() - 1; i++) {
+            final BigDecimal dueAmount = 
rescheduledInstallments.get(i).getDue(currency).getAmount();
+            if (dueAmount.compareTo(maxPriorDueAmount) > 0) {
+                maxPriorDueAmount = dueAmount;
+            }
+        }
+
+        final BigDecimal lastInstallmentDueAmount = 
lastInstallment.getDue(currency).getAmount();
+        final BigDecimal minimumMaterialDifference = 
BigDecimal.ONE.movePointLeft(currency.getDigitsAfterDecimal());
+        return 
lastInstallmentDueAmount.subtract(maxPriorDueAmount).compareTo(minimumMaterialDifference)
 > 0;

Review Comment:
   too large here means the last rescheduled installment becomes materially 
higher than the rest, not just different due to rounding.
   
   My current Logic in this method:
   We only inspect installments in the rescheduled range (exclude down payment 
+ due dates before rescheduleFromDate). We take the max due amount among all 
rescheduled installments except the last. We compare last due vs that max prior 
due. We treat it as “too large” only if the last due is greater by more than 
one minor currency unit. So for a 2-decimal currency, the threshold is > 0.01 
(strictly greater), which intentionally ignores rounding noise and only flags a 
real ballooning last installment.



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