Holiday rescheduling feature

This commit is contained in:
xurror
2021-09-21 21:16:27 +08:00
committed by Petri Tuomola
parent 3c5b16df44
commit 5c68e8b4a5
2 changed files with 58 additions and 9 deletions
@@ -125,10 +125,12 @@ import org.apache.fineract.portfolio.loanaccount.exception.MultiDisbursementData
import org.apache.fineract.portfolio.loanaccount.exception.UndoLastTrancheDisbursementException;
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanScheduleDTO;
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.AprCalculator;
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.DefaultScheduledDateGenerator;
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanApplicationTerms;
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleGenerator;
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel;
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModelPeriod;
import org.apache.fineract.portfolio.loanaccount.service.LoanUtilService;
import org.apache.fineract.portfolio.loanproduct.domain.AmortizationMethod;
import org.apache.fineract.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
import org.apache.fineract.portfolio.loanproduct.domain.InterestMethod;
@@ -4524,12 +4526,61 @@ public class Loan extends AbstractPersistableCustom {
// startDate
}
public void applyHolidayToRepaymentScheduleDates(final Holiday holiday) {
public void applyHolidayToRepaymentScheduleDates(final Holiday holiday, final LoanUtilService loanUtilService) {
final DefaultScheduledDateGenerator scheduledDateGenerator = new DefaultScheduledDateGenerator();
ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(this, holiday.getFromDateLocalDate());
final LoanApplicationTerms loanApplicationTerms = this.constructLoanApplicationTerms(scheduleGeneratorDTO);
// LocalDate rescheduleFromDate = holiday.getFromDateLocalDate();
LocalDate adjustedRescheduleToDate = null;
if (holiday.getReScheduleType().isResheduleToNextRepaymentDate()) {
final LocalDate rescheduleToDate = holiday.getToDateLocalDate();
for (final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : this.getRepaymentScheduleInstallments()) {
if (rescheduleToDate.isEqual(loanRepaymentScheduleInstallment.getDueDate())) {
adjustedRescheduleToDate = rescheduleToDate;
break;
} else {
// Account for a Bimonthly Loan Product
// if (loanApplicationTerms.getRepaymentPeriodFrequencyType().isSemiMonthly()) {
// if (rescheduleToDate.isAfter(loanRepaymentScheduleInstallment.getDueDate())
// && rescheduleToDate.isBefore(loanRepaymentScheduleInstallment.getDueDate().plusDays(15))) {
// adjustedRescheduleToDate = loanRepaymentScheduleInstallment.getDueDate();
// break;
// }
// } else {
// // Once Bimonthly product implemented, Replace the `Standard Monthly Loan Holiday check` below
// HERE
// if (rescheduleToDate.isAfter(loanRepaymentScheduleInstallment.getDueDate())
// && rescheduleToDate.isBefore(loanRepaymentScheduleInstallment.getDueDate().plusDays(30))) {
// adjustedRescheduleToDate = loanRepaymentScheduleInstallment.getDueDate();
// break;
// }
// }
// Standard Monthly Loan Holiday check
if (rescheduleToDate.isAfter(loanRepaymentScheduleInstallment.getDueDate())
&& rescheduleToDate.isBefore(loanRepaymentScheduleInstallment.getDueDate().plusDays(30))) {
adjustedRescheduleToDate = loanRepaymentScheduleInstallment.getDueDate();
break;
}
}
}
} else {
adjustedRescheduleToDate = holiday.getRepaymentsRescheduledToLocalDate();
}
// first repayment's from date is same as disbursement date.
LocalDate tmpFromDate = getDisbursementDate();
// Loop through all loanRepayments
List<LoanRepaymentScheduleInstallment> installments = getRepaymentScheduleInstallments();
for (final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : installments) {
if (adjustedRescheduleToDate == null) {
break;
}
final LocalDate oldDueDate = loanRepaymentScheduleInstallment.getDueDate();
// update from date if it's not same as previous installament's due
@@ -4537,17 +4588,15 @@ public class Loan extends AbstractPersistableCustom {
if (!loanRepaymentScheduleInstallment.getFromDate().isEqual(tmpFromDate)) {
loanRepaymentScheduleInstallment.updateFromDate(tmpFromDate);
}
if (oldDueDate.isAfter(holiday.getToDateLocalDate())) {
break;
}
if (oldDueDate.equals(holiday.getFromDateLocalDate()) || oldDueDate.equals(holiday.getToDateLocalDate())
|| (oldDueDate.isAfter(holiday.getFromDateLocalDate()) && oldDueDate.isBefore(holiday.getToDateLocalDate()))) {
if (oldDueDate.equals(holiday.getFromDateLocalDate()) || oldDueDate.isAfter(holiday.getFromDateLocalDate())) {
// FIXME: AA do we need to apply non-working days.
// Assuming holiday's repayment reschedule to date cannot be
// created on a non-working day.
final LocalDate newRepaymentDate = holiday.getRepaymentsRescheduledToLocalDate();
loanRepaymentScheduleInstallment.updateDueDate(newRepaymentDate);
adjustedRescheduleToDate = scheduledDateGenerator.generateNextRepaymentDate(adjustedRescheduleToDate, loanApplicationTerms,
false);
loanRepaymentScheduleInstallment.updateDueDate(adjustedRescheduleToDate);
}
tmpFromDate = loanRepaymentScheduleInstallment.getDueDate();
}
@@ -2615,7 +2615,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
for (final Loan loan : loans) {
// apply holiday
loan.applyHolidayToRepaymentScheduleDates(holiday);
loan.applyHolidayToRepaymentScheduleDates(holiday, this.loanUtilService);
}
this.loanRepositoryWrapper.save(loans);
holiday.processed();