/** * Given that the date is in a non-moratorium holiday, shift it past the holiday until either it * is no longer in a holiday or moratorium, or until it no longer moves (e.g., lands in a same-day * holiday). * * <p>If the date shifts into a moratorium period, then shift it out using the RepaymentRuleType * of the most recent non-moratorium holiday that the date was shifted out of. For example, if * shifting the date out of a next-working-day holiday lands it in a moratorium period, then use * the next-working-day repayment rule to shift it past the moratorium period. * * @param date the DateTime to be shifted * @return the shifted date */ private DateTime shiftDatePastNonMoratoriumHoliday(DateTime date) { assert date != null; assert isEnclosedByAHoliday(date); assert !isEnclosedByAHolidayWithRepaymentRule(date, RepaymentRuleTypes.REPAYMENT_MORATORIUM); Holiday currentlyEnclosingHoliday = getHolidayEnclosing(date); RepaymentRuleTypes mostRecentNonMoratoriumRepaymentRule = currentlyEnclosingHoliday.getRepaymentRuleType(); // never REPAYMENT_MORATORIUM DateTime previousDate = null; DateTime adjustedDate = date; do { previousDate = adjustedDate; if (currentlyEnclosingHoliday.getRepaymentRuleType() == RepaymentRuleTypes.REPAYMENT_MORATORIUM) { adjustedDate = buildHolidayFromCurrentHolidayWithRepaymentRule( currentlyEnclosingHoliday, mostRecentNonMoratoriumRepaymentRule) .adjust(previousDate, workingDays, scheduledEvent); } else { adjustedDate = currentlyEnclosingHoliday.adjust(previousDate, workingDays, scheduledEvent); mostRecentNonMoratoriumRepaymentRule = currentlyEnclosingHoliday.getRepaymentRuleType(); } if (isEnclosedByAHoliday(adjustedDate)) { currentlyEnclosingHoliday = getHolidayEnclosing(adjustedDate); } } while (isEnclosedByAHoliday(adjustedDate) && (!adjustedDate.equals(previousDate))); return adjustedDate; }
private boolean isEnclosedByAHoliday(DateTime date) { for (Holiday holiday : this.upcomingHolidays) { if (holiday.encloses(date.toDate())) { return true; } } return false; }
private boolean isEnclosedByAHolidayWithRepaymentRule(DateTime date, RepaymentRuleTypes rule) { for (Holiday holiday : this.upcomingHolidays) { if (holiday.encloses(date.toDate()) && (holiday.getRepaymentRuleType() == rule)) { return true; } } return false; }
private List<Holiday> getNonMoratoriumHolidays() { List<Holiday> nonMoratoriumHolidays = new ArrayList<Holiday>(); for (Holiday holiday : this.upcomingHolidays) { if (!(holiday.getRepaymentRuleType() == RepaymentRuleTypes.REPAYMENT_MORATORIUM)) { nonMoratoriumHolidays.add(holiday); } } return nonMoratoriumHolidays; }
private Holiday getHolidayEnclosing(DateTime date) { assert isEnclosedByAHoliday(date); Holiday holidayEnclosingDate = null; for (Holiday holiday : upcomingHolidays) { if (holiday.encloses(date.toDate())) { holidayEnclosingDate = holiday; } } return holidayEnclosingDate; }
private Holiday buildHolidayFromCurrentHolidayWithRepaymentRule( Holiday originalHoliday, RepaymentRuleTypes rule) { HolidayPK holidayPK = new HolidayPK((short) 1, originalHoliday.getFromDate().toDate()); RepaymentRuleEntity repaymentRuleEntity = new RepaymentRuleEntity(rule.getValue(), "lookup.value.key"); try { return new HolidayBO( holidayPK, originalHoliday.getThruDate().toDate(), "temporaryHoliday", repaymentRuleEntity); } catch (ApplicationException e) { throw new IllegalStateException("Could not create temporary holiday", e); } }
/** * Given that the first date in the list falls in a non-Moratorium holiday, return the list of * dates that fall in the holiday, but shifted out of the holiday using the holiday's repayment * rule. TODO keithp: once dates are shifted past all non-moratorium holidays, then check whether * any fall in a moratorium period. If they do, push them past the moratorium, but do not push out * future dates. TODO keithp: if shifting a date does not change the date (e.g. same day holiday), * then we're done with it, so move to the next date. */ private List<DateTime> shiftDatesInNonMoratoriumHoliday(List<DateTime> dates) { assert dates != null; assert !dates.isEmpty(); assert isEnclosedByAHoliday(dates.get(0)); assert !isEnclosedByAHolidayWithRepaymentRule( dates.get(0), RepaymentRuleTypes.REPAYMENT_MORATORIUM); Holiday enclosingHoliday = getHolidayEnclosing(dates.get(0)); List<DateTime> shiftedDatesInHoliday = new ArrayList<DateTime>(); for (int i = 0; i < dates.size(); i++) { if (enclosingHoliday.encloses(dates.get(i).toDate())) { shiftedDatesInHoliday.add(nonMoratoriumAdjustmentStrategy.adjust(dates.get(i))); } } return shiftedDatesInHoliday; }
private int countDatesEnclosedByHoliday(List<DateTime> dates, Holiday holiday) { int countEnclosedDates = 0; for (int i = 0; i < dates.size(); i++) { if (holiday.encloses(dates.get(i).toDate())) { countEnclosedDates++; } } return countEnclosedDates; }
private List<Object[]> getListOfAccountIdsHavingSchedulesWithinAHoliday( final String queryName, final Holiday holiday) throws PersistenceException { Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put("HOLIDAY_ID", holiday.getId()); parameters.put( "HOLIDAY_FROM_DATE", DateUtils.getLocalDateFromDate(holiday.getFromDate().toDate()).toString()); parameters.put( "HOLIDAY_THRU_DATE", DateUtils.getLocalDateFromDate(holiday.getThruDate().toDate()).toString()); List<Object[]> queryResult = executeNamedQuery(queryName, parameters); if (queryResult != null) { return queryResult; } return new ArrayList<Object[]>(); }