Merge pull request #513 from mifoscontributer/mifosx-554
MIFOSX-554 Adjust repaymentdate for frequent meeting changes
This commit is contained in:
+28
-17
@@ -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){
|
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);
|
final Recur recur = CalendarHelper.getICalRecur(recurringRule);
|
||||||
if (recur == null) { return null; }
|
if (recur == null) { return null; }
|
||||||
|
|
||||||
if(isValidRecurringDate(recur, seedDate, oldRepaymentDate)){
|
if(isValidRecurringDate(recur, seedDate, oldRepaymentDate)){
|
||||||
return oldRepaymentDate;
|
return oldRepaymentDate;
|
||||||
}
|
}
|
||||||
/* Recurring dates should follow loanRepaymentInterval.
|
return getNextRepaymentMeetingDate(recurringRule, seedDate, oldRepaymentDate, loanRepaymentInterval, frequency, workingDays);
|
||||||
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.
|
public static LocalDate getNextRepaymentMeetingDate(final String recurringRule, final LocalDate seedDate, final LocalDate repaymentDate, final Integer loanRepaymentInterval, final String frequency, final WorkingDays workingDays){
|
||||||
//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);
|
final Recur recur = CalendarHelper.getICalRecur(recurringRule);
|
||||||
LocalDate nextRepaymentDate = getNextRecurringDate(recur, seedDate, newRepaymentDate);
|
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);
|
||||||
|
|
||||||
newRepaymentDate = WorkingDaysUtil.getOffSetDateIfNonWorkingDay(newRepaymentDate, nextRepaymentDate, workingDays);
|
/*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);
|
||||||
|
}
|
||||||
|
|
||||||
return newRepaymentDate;
|
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) {
|
public static boolean isFrequencySame(final String oldRRule, final String newRRule) {
|
||||||
|
|||||||
+41
-8
@@ -2395,20 +2395,30 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
|
|
||||||
public void updateLoanRepaymentScheduleDates(final LocalDate meetingStartDate, final String recuringRule,
|
public void updateLoanRepaymentScheduleDates(final LocalDate meetingStartDate, final String recuringRule,
|
||||||
final boolean isHolidayEnabled, final List<Holiday> holidays, final WorkingDays workingDays) {
|
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;
|
LocalDate newRepaymentDate = null;
|
||||||
for (LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : this.repaymentScheduleInstallments) {
|
for (LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : this.repaymentScheduleInstallments) {
|
||||||
final LocalDate oldDueDate = loanRepaymentScheduleInstallment.getDueDate();
|
final LocalDate oldDueDate = loanRepaymentScheduleInstallment.getDueDate();
|
||||||
// FIXME: AA this won't update repayment dates before current date.
|
// FIXME: AA this won't update repayment dates before current date.
|
||||||
if (oldDueDate.isAfter(meetingStartDate) && oldDueDate.isAfter(DateUtils.getLocalDateOfTenant())) {
|
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,
|
||||||
newRepaymentDate = CalendarHelper.getNewRepaymentMeetingDate(recuringRule, meetingStartDate, oldDueDate, loanRepaymentInterval, frequency, workingDays);
|
loanRepaymentInterval, frequency, workingDays);
|
||||||
if(isHolidayEnabled){
|
|
||||||
|
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);
|
newRepaymentDate = HolidayUtil.getRepaymentRescheduleDateToIfHoliday(newRepaymentDate, holidays);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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) {
|
public void applyHolidayToRepaymentScheduleDates(final Holiday holiday) {
|
||||||
// first repayment's from date is same as disbursement date.
|
// first repayment's from date is same as disbursement date.
|
||||||
LocalDate tmpFromDate = this.getDisbursementDate();
|
LocalDate tmpFromDate = this.getDisbursementDate();
|
||||||
|
|||||||
Reference in New Issue
Block a user