mariiaKraievska commented on code in PR #5053:
URL: https://github.com/apache/fineract/pull/5053#discussion_r2465469919
##########
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;
+ }
Review Comment:
Done
##########
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();
Review Comment:
Done
##########
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:
Done
--
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]