Repository: incubator-fineract Updated Branches: refs/heads/develop e20ec293b -> 525e8becb
Reschedule repayment on holidays+extend term Project: http://git-wip-us.apache.org/repos/asf/incubator-fineract/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-fineract/commit/b478064a Tree: http://git-wip-us.apache.org/repos/asf/incubator-fineract/tree/b478064a Diff: http://git-wip-us.apache.org/repos/asf/incubator-fineract/diff/b478064a Branch: refs/heads/develop Commit: b478064ac0fe74a7130b9a0c2f07a5ccd30631a5 Parents: 8327b11 Author: Terence Denzil Monteiro <tere...@sanjosesolutions.in> Authored: Thu Aug 25 17:45:14 2016 +0530 Committer: Terence Denzil Monteiro <tere...@sanjosesolutions.in> Committed: Thu Aug 25 17:45:14 2016 +0530 ---------------------------------------------------------------------- .../api/WorkingDaysApiConstants.java | 6 +-- .../workingdays/data/WorkingDayValidator.java | 6 ++- .../workingdays/data/WorkingDaysData.java | 11 ++++-- .../workingdays/domain/WorkingDays.java | 15 ++++++- .../WorkingDaysReadPlatformServiceImpl.java | 8 ++-- .../domain/DefaultScheduledDateGenerator.java | 41 +++++++++++++++----- .../V320__add_holiday_payment_reschedule.sql | 20 ++++++++++ 7 files changed, 86 insertions(+), 21 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/b478064a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/api/WorkingDaysApiConstants.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/api/WorkingDaysApiConstants.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/api/WorkingDaysApiConstants.java index 5eebbe9..fda39bb 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/api/WorkingDaysApiConstants.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/api/WorkingDaysApiConstants.java @@ -36,14 +36,14 @@ public class WorkingDaysApiConstants { public static final String rescheduleRepaymentTemplate = "rescheduleRepaymentTemplate"; public static final String localeParamName = "locale"; public static final String extendTermForDailyRepayments = "extendTermForDailyRepayments"; - + public static final String extendTermForRepaymentsOnHolidays = "extendTermForRepaymentsOnHolidays"; public static final Set<String> WORKING_DAYS_CREATE_OR_UPDATE_REQUEST_DATA_PARAMETERS =new HashSet<>(Arrays.asList( - recurrence,repayment_rescheduling_enum,localeParamName,extendTermForDailyRepayments + recurrence,repayment_rescheduling_enum,localeParamName,extendTermForDailyRepayments,extendTermForRepaymentsOnHolidays )); public static final Set<String> WORKING_DAYS_RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList(idParamName, - recurrence,repayment_rescheduling_enum,extendTermForDailyRepayments + recurrence,repayment_rescheduling_enum,extendTermForDailyRepayments,extendTermForRepaymentsOnHolidays )); public static final Set<String> WORKING_DAYS_TEMPLATE_PARAMETERS = new HashSet<>(Arrays.asList(rescheduleRepaymentTemplate)); http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/b478064a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDayValidator.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDayValidator.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDayValidator.java index 271a5a6..466ca0f 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDayValidator.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDayValidator.java @@ -67,14 +67,16 @@ public class WorkingDayValidator { final Boolean extendTermForDailyRepayments = this.fromApiJsonHelper.extractBooleanNamed("extendTermForDailyRepayments", element); baseDataValidator.reset().parameter(WorkingDaysApiConstants.extendTermForDailyRepayments).value(extendTermForDailyRepayments).ignoreIfNull().validateForBooleanValue(); - + + final Boolean extendTermForRepaymentsOnHolidays = this.fromApiJsonHelper.extractBooleanNamed("extendTermForRepaymentsOnHolidays", element); + baseDataValidator.reset().parameter(WorkingDaysApiConstants.extendTermForRepaymentsOnHolidays).value(extendTermForRepaymentsOnHolidays).ignoreIfNull().validateForBooleanValue(); + throwExceptionIfValidationWarningsExist(dataValidationErrors); } private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) { if (!dataValidationErrors.isEmpty()) { - // throw new PlatformApiDataValidationException(dataValidationErrors); } } http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/b478064a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDaysData.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDaysData.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDaysData.java index affdc03..72fd6d0 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDaysData.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDaysData.java @@ -31,28 +31,33 @@ public class WorkingDaysData { @SuppressWarnings("unused") private final EnumOptionData repaymentRescheduleType; - + @SuppressWarnings("unused") private final Boolean extendTermForDailyRepayments; + @SuppressWarnings("unused") + private final Boolean extendTermForRepaymentsOnHolidays; + // template date @SuppressWarnings("unused") private final Collection<EnumOptionData> repaymentRescheduleOptions; - public WorkingDaysData(Long id, String recurrence, EnumOptionData repaymentRescheduleType, Boolean extendTermForDailyRepayments) { + public WorkingDaysData(Long id, String recurrence, EnumOptionData repaymentRescheduleType, Boolean extendTermForDailyRepayments, Boolean extendTermForRepaymentsOnHolidays) { this.id = id; this.recurrence = recurrence; this.repaymentRescheduleType = repaymentRescheduleType; this.repaymentRescheduleOptions = null; this.extendTermForDailyRepayments = extendTermForDailyRepayments; + this.extendTermForRepaymentsOnHolidays = extendTermForRepaymentsOnHolidays; } public WorkingDaysData(Long id, String recurrence, EnumOptionData repaymentRescheduleType, - Collection<EnumOptionData> repaymentRescheduleOptions, Boolean extendTermForDailyRepayments) { + Collection<EnumOptionData> repaymentRescheduleOptions, Boolean extendTermForDailyRepayments, Boolean extendTermForRepaymentsOnHolidays) { this.id = id; this.recurrence = recurrence; this.repaymentRescheduleType = repaymentRescheduleType; this.repaymentRescheduleOptions = repaymentRescheduleOptions; this.extendTermForDailyRepayments = extendTermForDailyRepayments; + this.extendTermForRepaymentsOnHolidays = extendTermForRepaymentsOnHolidays; } } http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/b478064a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/domain/WorkingDays.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/domain/WorkingDays.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/domain/WorkingDays.java index adeba4a..75852c7 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/domain/WorkingDays.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/domain/WorkingDays.java @@ -41,15 +41,19 @@ public class WorkingDays extends AbstractPersistable<Long> { @Column(name = "extend_term_daily_repayments", nullable = false) private Boolean extendTermForDailyRepayments; + + @Column(name = "extend_term_holiday_repayment", nullable = false) + private Boolean extendTermForRepaymentsOnHolidays; protected WorkingDays() { } - protected WorkingDays(final String recurrence, final Integer repaymentReschedulingType, final Boolean extendTermForDailyRepayments ) { + protected WorkingDays(final String recurrence, final Integer repaymentReschedulingType, final Boolean extendTermForDailyRepayments, final Boolean extendTermForRepaymentsOnHolidays) { this.recurrence = recurrence; this.repaymentReschedulingType = repaymentReschedulingType; this.extendTermForDailyRepayments = extendTermForDailyRepayments; + this.extendTermForRepaymentsOnHolidays = extendTermForRepaymentsOnHolidays; } /** @@ -74,6 +78,8 @@ public class WorkingDays extends AbstractPersistable<Long> { return this.extendTermForDailyRepayments; } + public Boolean getExtendTermForRepaymentsOnHolidays() { return this.extendTermForRepaymentsOnHolidays; } + public Map<String, Object> update(final JsonCommand command) { final Map<String, Object> actualChanges = new LinkedHashMap<>(7); @@ -96,6 +102,13 @@ public class WorkingDays extends AbstractPersistable<Long> { actualChanges.put(WorkingDaysApiConstants.extendTermForDailyRepayments, newValue); this.extendTermForDailyRepayments = newValue; } + + if (command.isChangeInBooleanParameterNamed(WorkingDaysApiConstants.extendTermForRepaymentsOnHolidays, this.extendTermForRepaymentsOnHolidays)) { + final Boolean newValue = command.booleanPrimitiveValueOfParameterNamed(WorkingDaysApiConstants.extendTermForRepaymentsOnHolidays); + actualChanges.put(WorkingDaysApiConstants.extendTermForRepaymentsOnHolidays, newValue); + this.extendTermForRepaymentsOnHolidays = newValue; + } + return actualChanges; } http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/b478064a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysReadPlatformServiceImpl.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysReadPlatformServiceImpl.java index 085e42e..8c4153c 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysReadPlatformServiceImpl.java @@ -53,7 +53,8 @@ public class WorkingDaysReadPlatformServiceImpl implements WorkingDaysReadPlatfo public WorkingDaysMapper() { final StringBuilder sqlBuilder = new StringBuilder(100); sqlBuilder.append("w.id as id,w.recurrence as recurrence,w.repayment_rescheduling_enum as status_enum,"); - sqlBuilder.append("w.extend_term_daily_repayments as extendTermForDailyRepayments "); + sqlBuilder.append("w.extend_term_daily_repayments as extendTermForDailyRepayments,"); + sqlBuilder.append("w.extend_term_holiday_repayment as extendTermForRepaymentsOnHolidays "); sqlBuilder.append("from m_working_days w"); this.schema = sqlBuilder.toString(); @@ -70,8 +71,9 @@ public class WorkingDaysReadPlatformServiceImpl implements WorkingDaysReadPlatfo final Integer statusEnum = JdbcSupport.getInteger(rs, "status_enum"); final EnumOptionData status = WorkingDaysEnumerations.workingDaysStatusType(statusEnum); final Boolean extendTermForDailyRepayments = rs.getBoolean("extendTermForDailyRepayments"); + final Boolean extendTermForRepaymentsOnHolidays = rs.getBoolean("extendTermForRepaymentsOnHolidays"); - return new WorkingDaysData(id, recurrence, status,extendTermForDailyRepayments); + return new WorkingDaysData(id, recurrence, status, extendTermForDailyRepayments, extendTermForRepaymentsOnHolidays); } } @@ -93,6 +95,6 @@ public class WorkingDaysReadPlatformServiceImpl implements WorkingDaysReadPlatfo WorkingDaysEnumerations.repaymentRescheduleType(RepaymentRescheduleType.MOVE_TO_NEXT_WORKING_DAY), WorkingDaysEnumerations.repaymentRescheduleType(RepaymentRescheduleType.MOVE_TO_NEXT_REPAYMENT_MEETING_DAY), WorkingDaysEnumerations.repaymentRescheduleType(RepaymentRescheduleType.MOVE_TO_PREVIOUS_WORKING_DAY)); - return new WorkingDaysData(null, null, null, repaymentRescheduleOptions, null); + return new WorkingDaysData(null, null, null, repaymentRescheduleOptions, null, null); } } http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/b478064a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/DefaultScheduledDateGenerator.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/DefaultScheduledDateGenerator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/DefaultScheduledDateGenerator.java index b57f215..93a58ce 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/DefaultScheduledDateGenerator.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/DefaultScheduledDateGenerator.java @@ -18,9 +18,10 @@ */ package org.apache.fineract.portfolio.loanaccount.loanschedule.domain; - +import org.apache.fineract.organisation.holiday.domain.Holiday; import org.apache.fineract.organisation.holiday.service.HolidayUtil; import org.apache.fineract.organisation.workingdays.domain.RepaymentRescheduleType; +import org.apache.fineract.organisation.workingdays.domain.WorkingDays; import org.apache.fineract.organisation.workingdays.service.WorkingDaysUtil; import org.apache.fineract.portfolio.calendar.data.CalendarHistoryDataWrapper; import org.apache.fineract.portfolio.calendar.domain.Calendar; @@ -29,11 +30,10 @@ import org.apache.fineract.portfolio.calendar.service.CalendarUtils; import org.apache.fineract.portfolio.common.domain.DayOfWeekType; import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType; import org.apache.fineract.portfolio.loanaccount.data.HolidayDetailDTO; -import org.joda.time.Days; -import org.joda.time.LocalDate; -import org.joda.time.Months; -import org.joda.time.Weeks; -import org.joda.time.Years; +import org.joda.time.*; + +import java.util.ArrayList; +import java.util.List; public class DefaultScheduledDateGenerator implements ScheduledDateGenerator { @@ -57,10 +57,10 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator { boolean isFirstRepayment, final HolidayDetailDTO holidayDetailDTO) { final LocalDate firstRepaymentPeriodDate = loanApplicationTerms.getCalculatedRepaymentsStartingFromLocalDate(); LocalDate dueRepaymentPeriodDate = null; + Calendar currentCalendar = loanApplicationTerms.getLoanCalendar(); if (isFirstRepayment && firstRepaymentPeriodDate != null) { dueRepaymentPeriodDate = firstRepaymentPeriodDate; } else { - Calendar currentCalendar = loanApplicationTerms.getLoanCalendar(); dueRepaymentPeriodDate = getRepaymentPeriodDate(loanApplicationTerms.getRepaymentPeriodFrequencyType(), loanApplicationTerms.getRepaymentEvery(), lastRepaymentDate, null, null); @@ -96,10 +96,33 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator { loanApplicationTerms.getNumberOfdays()); } } - + if (currentCalendar == null && holidayDetailDTO.getWorkingDays().getExtendTermForRepaymentsOnHolidays()) { + boolean repaymentDateIsOnHoliday = false; + // compile the list of holidays into Intervals to see if this date lands on a holiday + final List<Interval> holidayInterval = new ArrayList<>(); + for (Holiday holiday : holidayDetailDTO.getHolidays()) { + holidayInterval.add(new Interval( + holiday.getFromDateLocalDate().toDateTimeAtStartOfDay(), + holiday.getToDateLocalDate().toDateTime(LocalTime.parse("23:59:59")) + )); + } + while (intervalListContainsDate(holidayInterval, dueRepaymentPeriodDate)) { + LocalDate previousDate = dueRepaymentPeriodDate; + dueRepaymentPeriodDate = getRepaymentPeriodDate(loanApplicationTerms.getRepaymentPeriodFrequencyType(), + loanApplicationTerms.getRepaymentEvery(), dueRepaymentPeriodDate, loanApplicationTerms.getNthDay(), + loanApplicationTerms.getWeekDayType()); + } + } return dueRepaymentPeriodDate; } - + private boolean intervalListContainsDate(List<Interval> intervalList, LocalDate date) { + for (Interval interval : intervalList) { + if (interval.contains(date.toDateTime(LocalTime.parse("11:59:59")))) { + return true; + } + } + return false; + } @Override public LocalDate adjustRepaymentDate(final LocalDate dueRepaymentPeriodDate, final LoanApplicationTerms loanApplicationTerms, final HolidayDetailDTO holidayDetailDTO) { http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/b478064a/fineract-provider/src/main/resources/sql/migrations/core_db/V320__add_holiday_payment_reschedule.sql ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/resources/sql/migrations/core_db/V320__add_holiday_payment_reschedule.sql b/fineract-provider/src/main/resources/sql/migrations/core_db/V320__add_holiday_payment_reschedule.sql new file mode 100644 index 0000000..0b25e00 --- /dev/null +++ b/fineract-provider/src/main/resources/sql/migrations/core_db/V320__add_holiday_payment_reschedule.sql @@ -0,0 +1,20 @@ +-- +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you under the Apache License, Version 2.0 (the +-- "License"); you may not use this file except in compliance +-- with the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, +-- software distributed under the License is distributed on an +-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +-- KIND, either express or implied. See the License for the +-- specific language governing permissions and limitations +-- under the License. +-- + +ALTER TABLE m_working_days ADD extend_term_holiday_repayment BOOLEAN NOT NULL DEFAULT 0;