Merge pull request #513 from mifoscontributer/mifosx-554

MIFOSX-554 Adjust repaymentdate for frequent meeting changes
This commit is contained in:
Vishwas Babu A J
2013-08-06 23:14:16 -07:00
2 changed files with 74 additions and 30 deletions
@@ -312,30 +312,41 @@ public class CalendarHelper {
public static LocalDate getNewRepaymentMeetingDate(final String recurringRule, final LocalDate seedDate, final LocalDate oldRepaymentDate, final Integer loanRepaymentInterval, final String frequency, final WorkingDays workingDays){
final Recur recur = CalendarHelper.getICalRecur(recurringRule);
if (recur == null) { return null; }
if(isValidRecurringDate(recur, seedDate, oldRepaymentDate)){
return oldRepaymentDate;
}
/* Recurring dates should follow loanRepaymentInterval.
e.g. The weekly meeting will have interval of 1, if the loan product with fortnightly frequency will have interval of 2,
to generate right set of meeting dates reset interval same as loan repayment interval.
*/
recur.setInterval(loanRepaymentInterval);
/*Recurring dates should follow loanRepayment frequency.
//e.g. daily meeting frequency should support all loan products with any type of frequency.
to generate right set of meeting dates reset frequency same as loan repayment frequency.
*/
if(recur.getFrequency().equals(Recur.DAILY)){
recur.setFrequency(frequency);
}
LocalDate newRepaymentDate = getNextRecurringDate(recur, seedDate, oldRepaymentDate);
LocalDate nextRepaymentDate = getNextRecurringDate(recur, seedDate, newRepaymentDate);
newRepaymentDate = WorkingDaysUtil.getOffSetDateIfNonWorkingDay(newRepaymentDate, nextRepaymentDate, workingDays);
return newRepaymentDate;
return getNextRepaymentMeetingDate(recurringRule, seedDate, oldRepaymentDate, loanRepaymentInterval, frequency, workingDays);
}
public static LocalDate getNextRepaymentMeetingDate(final String recurringRule, final LocalDate seedDate, final LocalDate repaymentDate, final Integer loanRepaymentInterval, final String frequency, final WorkingDays workingDays){
final Recur recur = CalendarHelper.getICalRecur(recurringRule);
if (recur == null) { return null; }
LocalDate tmpDate = repaymentDate;
if(isValidRecurringDate(recur, seedDate, repaymentDate)){
tmpDate = repaymentDate.plusDays(1);
}
/* Recurring dates should follow loanRepaymentInterval.
*
e.g. The weekly meeting will have interval of 1, if the loan product with fortnightly frequency will have interval of 2,
to generate right set of meeting dates reset interval same as loan repayment interval.
*/
recur.setInterval(loanRepaymentInterval);
/*Recurring dates should follow loanRepayment frequency.
//e.g. daily meeting frequency should support all loan products with any type of frequency.
to generate right set of meeting dates reset frequency same as loan repayment frequency.
*/
if(recur.getFrequency().equals(Recur.DAILY)){
recur.setFrequency(frequency);
}
LocalDate newRepaymentDate = getNextRecurringDate(recur, seedDate, tmpDate);
LocalDate nextRepaymentDate = getNextRecurringDate(recur, seedDate, newRepaymentDate);
newRepaymentDate = WorkingDaysUtil.getOffSetDateIfNonWorkingDay(newRepaymentDate, nextRepaymentDate, workingDays);
return newRepaymentDate;
}
public static boolean isFrequencySame(final String oldRRule, final String newRRule) {
@@ -2395,23 +2395,33 @@ public class Loan extends AbstractPersistable<Long> {
public void updateLoanRepaymentScheduleDates(final LocalDate meetingStartDate, final String recuringRule,
final boolean isHolidayEnabled, final List<Holiday> holidays, final WorkingDays workingDays) {
//update repayment dates of repayment schedule installaments
LocalDate tmpFromDate = this.getDisbursementDate();//first repayment's from date is same as disbursement date.
LocalDate tmpFromDate = this.getDisbursementDate();
final PeriodFrequencyType repaymentPeriodFrequencyType = this.loanRepaymentScheduleDetail.getRepaymentPeriodFrequencyType();
final Integer loanRepaymentInterval = this.loanRepaymentScheduleDetail.getRepayEvery();
final String frequency = CalendarHelper.getMeetingFrequencyFromPeriodFrequencyType(repaymentPeriodFrequencyType);
LocalDate newRepaymentDate = null;
for (LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : this.repaymentScheduleInstallments) {
final LocalDate oldDueDate = loanRepaymentScheduleInstallment.getDueDate();
// FIXME: AA this won't update repayment dates before current date.
if (oldDueDate.isAfter(meetingStartDate) && oldDueDate.isAfter(DateUtils.getLocalDateOfTenant())) {
final PeriodFrequencyType repaymentPeriodFrequencyType = this.loanRepaymentScheduleDetail.getRepaymentPeriodFrequencyType();
final String frequency = CalendarHelper.getMeetingFrequencyFromPeriodFrequencyType(repaymentPeriodFrequencyType);
final Integer loanRepaymentInterval = this.loanRepaymentScheduleDetail.getRepayEvery();
// reset repayment date with new meeting date
newRepaymentDate = CalendarHelper.getNewRepaymentMeetingDate(recuringRule, meetingStartDate, oldDueDate, loanRepaymentInterval, frequency, workingDays);
if(isHolidayEnabled){
newRepaymentDate = CalendarHelper.getNewRepaymentMeetingDate(recuringRule, meetingStartDate, oldDueDate,
loanRepaymentInterval, frequency, workingDays);
final LocalDate maxDateLimitForNewRepayment = getMaxDateLimitForNewRepayment(repaymentPeriodFrequencyType,
loanRepaymentInterval, tmpFromDate);
if (newRepaymentDate.isAfter(maxDateLimitForNewRepayment)) {
newRepaymentDate = CalendarHelper.getNextRepaymentMeetingDate(recuringRule, meetingStartDate, tmpFromDate,
loanRepaymentInterval, frequency, workingDays);
}
if (isHolidayEnabled) {
newRepaymentDate = HolidayUtil.getRepaymentRescheduleDateToIfHoliday(newRepaymentDate, holidays);
}
loanRepaymentScheduleInstallment.updateDueDate(newRepaymentDate);
// reset from date to get actual daysInPeriod
loanRepaymentScheduleInstallment.updateFromDate(tmpFromDate);
@@ -2423,6 +2433,29 @@ public class Loan extends AbstractPersistable<Long> {
}
}
private LocalDate getMaxDateLimitForNewRepayment(final PeriodFrequencyType periodFrequencyType, final Integer loanRepaymentInterval,
final LocalDate startDate) {
LocalDate dueRepaymentPeriodDate = startDate;
final Integer repaidEvery = 2*loanRepaymentInterval;
switch (periodFrequencyType) {
case DAYS:
dueRepaymentPeriodDate = startDate.plusDays(repaidEvery);
break;
case WEEKS:
dueRepaymentPeriodDate = startDate.plusWeeks(repaidEvery);
break;
case MONTHS:
dueRepaymentPeriodDate = startDate.plusMonths(repaidEvery);
break;
case YEARS:
dueRepaymentPeriodDate = startDate.plusYears(repaidEvery);
break;
case INVALID:
break;
}
return dueRepaymentPeriodDate.minusDays(1);//get 2n-1 range date from startDate
}
public void applyHolidayToRepaymentScheduleDates(final Holiday holiday) {
// first repayment's from date is same as disbursement date.
LocalDate tmpFromDate = this.getDisbursementDate();