[MIFOSX-2652] Correcting repayment schedule for the loans with variable installments enabled

This commit is contained in:
Vishwa
2016-05-13 12:37:53 +05:30
parent b4a43e6e98
commit 0b81e80233
3 changed files with 93 additions and 16 deletions
@@ -120,4 +120,9 @@ public class LoanTermVariationsDataWrapper {
return data; return data;
} }
public boolean hasExceptionVariation(final LocalDate date, ListIterator<LoanTermVariationsData> exceptionDataListIterator) {
ListIterator<LoanTermVariationsData> iterator = exceptionDataListIterator;
return hasNext(date, iterator);
}
} }
@@ -26,6 +26,7 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.ListIterator;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
@@ -957,6 +958,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
boolean skipPeriod = false; boolean skipPeriod = false;
boolean recalculateAmounts = false; boolean recalculateAmounts = false;
LocalDate modifiedScheduledDueDate = scheduledDueDate; LocalDate modifiedScheduledDueDate = scheduledDueDate;
ArrayList<LoanTermVariationsData> variationsData = null;
// due date changes should be applied only for that dueDate // due date changes should be applied only for that dueDate
if (loanApplicationTerms.getLoanTermVariations().hasDueDateVariation(scheduledDueDate)) { if (loanApplicationTerms.getLoanTermVariations().hasDueDateVariation(scheduledDueDate)) {
@@ -1019,7 +1021,48 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
} }
} }
LoanTermVariationParams termVariationParams = new LoanTermVariationParams(skipPeriod, recalculateAmounts, modifiedScheduledDueDate); LoanTermVariationParams termVariationParams = new LoanTermVariationParams(skipPeriod, recalculateAmounts, modifiedScheduledDueDate,
variationsData);
return termVariationParams;
}
/**
* @param loanApplicationTerms
* @param scheduledDueDate
* @param exceptionDataListIterator
* @return
*/
private LoanTermVariationParams applyExceptionLoanTermVariations(final LoanApplicationTerms loanApplicationTerms,
final LocalDate scheduledDueDate, final ListIterator<LoanTermVariationsData> exceptionDataListIterator) {
boolean skipPeriod = false;
boolean recalculateAmounts = false;
LocalDate modifiedScheduledDueDate = scheduledDueDate;
ArrayList<LoanTermVariationsData> variationsData = new ArrayList<>();
while (loanApplicationTerms.getLoanTermVariations().hasExceptionVariation(modifiedScheduledDueDate, exceptionDataListIterator)) {
LoanTermVariationsData loanTermVariationsData = exceptionDataListIterator.next();
if (loanTermVariationsData.isProcessed()) {
continue;
}
switch (loanTermVariationsData.getTermVariationType()) {
case INSERT_INSTALLMENT:
modifiedScheduledDueDate = loanTermVariationsData.getTermApplicableFrom();
variationsData.add(loanTermVariationsData) ;
break;
case DELETE_INSTALLMENT:
if (loanTermVariationsData.getTermApplicableFrom().isEqual(modifiedScheduledDueDate)) {
skipPeriod = true;
variationsData.add(loanTermVariationsData) ;
}
break;
default:
break;
}
}
LoanTermVariationParams termVariationParams = new LoanTermVariationParams(skipPeriod, recalculateAmounts, modifiedScheduledDueDate,
variationsData);
return termVariationParams; return termVariationParams;
} }
@@ -2276,6 +2319,10 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
} }
int loanTermInDays = 0; int loanTermInDays = 0;
List<LoanTermVariationsData> exceptionDataList = loanApplicationTerms.getLoanTermVariations().getExceptionData();
final ListIterator<LoanTermVariationsData> exceptionDataListIterator = exceptionDataList.listIterator();
LoanTermVariationParams loanTermVariationParams = null;
// Block process the installment and creates the period if it falls // Block process the installment and creates the period if it falls
// before reschedule from date // before reschedule from date
// This will create the recalculation details by applying the // This will create the recalculation details by applying the
@@ -2289,23 +2336,42 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
break; break;
} }
LocalDate previousRepaymentDate = actualRepaymentDate; LocalDate previousRepaymentDate = actualRepaymentDate;
actualRepaymentDate = this.scheduledDateGenerator.generateNextRepaymentDate(actualRepaymentDate, loanApplicationTerms, ArrayList<LoanTermVariationsData> dueDateVariationsDataList = new ArrayList<>();
isFirstRepayment, holidayDetailDTO);
isFirstRepayment = false; // check for date changes
lastInstallmentDate = this.scheduledDateGenerator.adjustRepaymentDate(actualRepaymentDate, loanApplicationTerms,
holidayDetailDTO);
if (!lastInstallmentDate.isBefore(rescheduleFrom)) {
actualRepaymentDate = previousRepaymentDate;
break;
}
periodNumber++;
// check for date changes
while (loanApplicationTerms.getLoanTermVariations().hasDueDateVariation(lastInstallmentDate)) { while (loanApplicationTerms.getLoanTermVariations().hasDueDateVariation(lastInstallmentDate)) {
LoanTermVariationsData variation = loanApplicationTerms.getLoanTermVariations().nextDueDateVariation(); LoanTermVariationsData variation = loanApplicationTerms.getLoanTermVariations().nextDueDateVariation();
if (!variation.isSpecificToInstallment()) { if (!variation.isSpecificToInstallment()) {
actualRepaymentDate = variation.getDateValue(); actualRepaymentDate = variation.getDateValue();
} }
variation.setProcessed(true); dueDateVariationsDataList.add(variation);
}
do {
actualRepaymentDate = this.scheduledDateGenerator.generateNextRepaymentDate(actualRepaymentDate,
loanApplicationTerms, isFirstRepayment, holidayDetailDTO);
isFirstRepayment = false;
lastInstallmentDate = this.scheduledDateGenerator.adjustRepaymentDate(actualRepaymentDate, loanApplicationTerms,
holidayDetailDTO);
loanTermVariationParams = applyExceptionLoanTermVariations(loanApplicationTerms, lastInstallmentDate,
exceptionDataListIterator);
} while (loanTermVariationParams != null && loanTermVariationParams.isSkipPeriod());
if (!lastInstallmentDate.isBefore(rescheduleFrom)) {
actualRepaymentDate = previousRepaymentDate;
break;
}
periodNumber++;
for (LoanTermVariationsData dueDateVariation : dueDateVariationsDataList) {
dueDateVariation.setProcessed(true);
}
if (loanTermVariationParams != null && loanTermVariationParams.isSkipPeriod()) {
ArrayList<LoanTermVariationsData> variationsDataList = loanTermVariationParams.getVariationsDataList();
for (LoanTermVariationsData variationsData : variationsDataList) {
variationsData.setProcessed(true);
}
} }
} }
@@ -2690,11 +2756,14 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
private final boolean skipPeriod; private final boolean skipPeriod;
private final boolean recalculateAmounts; private final boolean recalculateAmounts;
private final LocalDate scheduledDueDate; private final LocalDate scheduledDueDate;
private final ArrayList<LoanTermVariationsData> variationsData;
public LoanTermVariationParams(final boolean skipPeriod, final boolean recalculateAmounts, final LocalDate scheduledDueDate) { public LoanTermVariationParams(final boolean skipPeriod, final boolean recalculateAmounts, final LocalDate scheduledDueDate,
final ArrayList<LoanTermVariationsData> variationsData) {
this.skipPeriod = skipPeriod; this.skipPeriod = skipPeriod;
this.recalculateAmounts = recalculateAmounts; this.recalculateAmounts = recalculateAmounts;
this.scheduledDueDate = scheduledDueDate; this.scheduledDueDate = scheduledDueDate;
this.variationsData = variationsData;
} }
public boolean isSkipPeriod() { public boolean isSkipPeriod() {
@@ -2709,6 +2778,10 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
return this.scheduledDueDate; return this.scheduledDueDate;
} }
public ArrayList<LoanTermVariationsData> getVariationsDataList() {
return this.variationsData;
}
} }
private final class ScheduleCurrentPeriodParams { private final class ScheduleCurrentPeriodParams {
@@ -762,8 +762,7 @@ public final class LoanApplicationCommandFromApiJsonHelper {
repaymentsStartingFromDateParameterName, element); repaymentsStartingFromDateParameterName, element);
baseDataValidator.reset().parameter(repaymentsStartingFromDateParameterName).value(repaymentsStartingFromDate).ignoreIfNull(); baseDataValidator.reset().parameter(repaymentsStartingFromDateParameterName).value(repaymentsStartingFromDate).ignoreIfNull();
if (!existingLoanApplication.getLoanTermVariations().isEmpty()) { if (!existingLoanApplication.getLoanTermVariations().isEmpty()) {
baseDataValidator.reset().parameter(repaymentsStartingFromDateParameterName).value(repaymentsStartingFromDate) baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("cannot.modify.application.due.to.variable.installments");
.failWithCode("invalid.due.to.variable.installments");
} }
} }