001 /*
002 * Copyright 2011 The Kuali Foundation.
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.kfs.module.endow.document.service.impl;
017
018 import java.sql.Date;
019 import java.util.Calendar;
020
021 import org.kuali.kfs.module.endow.EndowConstants;
022 import org.kuali.kfs.module.endow.document.service.ValidateDateBasedOnFrequencyCodeService;
023
024 /**
025 * This class...
026 */
027 public class ValidateDateBasedOnFrequencyCodeServiceImpl implements ValidateDateBasedOnFrequencyCodeService {
028
029 /**
030 * @see org.kuali.kfs.module.endow.document.service.ValidateDateBasedOnFrequencyCodeService#validateDateBasedOnFrequencyCode(java.sql.Date,
031 * java.lang.String)
032 */
033 public boolean validateDateBasedOnFrequencyCode(Date date, String frequencyCode) {
034 boolean isValid = true;
035 Calendar calendar = Calendar.getInstance();
036 calendar.setTime(date);
037
038 String frequencyType = frequencyCode.substring(0, 1);
039
040 if (frequencyType.equalsIgnoreCase(EndowConstants.FrequencyTypes.DAILY)) {
041 // any date is valid
042 return true;
043 }
044
045 if (frequencyType.equalsIgnoreCase(EndowConstants.FrequencyTypes.WEEKLY)) {
046 String dayOfWeek = frequencyCode.substring(1, 4).toUpperCase();
047 int calendarDayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
048
049 return validateWeekly(dayOfWeek, calendarDayOfWeek);
050
051 }
052
053 if (frequencyType.equalsIgnoreCase(EndowConstants.FrequencyTypes.SEMI_MONTHLY) || frequencyType.equalsIgnoreCase(EndowConstants.FrequencyTypes.MONTHLY)) {
054 String dayOfMonth = frequencyCode.substring(1, 3);
055 int calendarDayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
056 return validateDayOfMonth(dayOfMonth, calendarDayOfMonth);
057 }
058
059 if (frequencyType.equalsIgnoreCase(EndowConstants.FrequencyTypes.QUARTERLY)) {
060 String month = frequencyCode.substring(1, 2);
061 int calendarMonth = calendar.get(Calendar.MONTH);
062 String dayOfMonth = frequencyCode.substring(2, 4);
063 int calendarDayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
064
065 return validateQuarterly(month, calendarMonth, dayOfMonth, calendarDayOfMonth);
066 }
067
068 if (frequencyType.equalsIgnoreCase(EndowConstants.FrequencyTypes.SEMI_ANNUALLY)) {
069
070 String month = frequencyCode.substring(1, 2);
071 int calendarMonth = calendar.get(Calendar.MONTH);
072 String dayOfMonth = frequencyCode.substring(2, 4);
073 int calendarDayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
074
075 return validateSemiAnnually(month, calendarMonth, dayOfMonth, calendarDayOfMonth);
076 }
077
078 if (frequencyType.equalsIgnoreCase(EndowConstants.FrequencyTypes.ANNUALLY)) {
079 String month = frequencyCode.substring(1, 2);
080 int calendarMonth = calendar.get(Calendar.MONTH);
081 String dayOfMonth = frequencyCode.substring(2, 4);
082 int calendarDayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
083
084 return validateDayAndMonth(month, calendarMonth, dayOfMonth, calendarDayOfMonth);
085
086 }
087
088 return isValid;
089 }
090
091 /**
092 * Validates that the day of the given date corresponds to the day part of the weekly frequency code.
093 *
094 * @param dayOfWeek
095 * @param calendarDayOfWeek
096 * @return true if valid, false otherwise
097 */
098 private boolean validateWeekly(String dayOfWeek, int calendarDayOfWeek) {
099 boolean isValid = true;
100
101 if (EndowConstants.FrequencyWeekDays.MONDAY.equalsIgnoreCase(dayOfWeek)) {
102 if (calendarDayOfWeek != Calendar.MONDAY) {
103 return false;
104 }
105 }
106 if (EndowConstants.FrequencyWeekDays.TUESDAY.equalsIgnoreCase(dayOfWeek)) {
107 if (calendarDayOfWeek != Calendar.TUESDAY) {
108 return false;
109 }
110 }
111 if (EndowConstants.FrequencyWeekDays.WEDNESDAY.equalsIgnoreCase(dayOfWeek)) {
112 if (calendarDayOfWeek != Calendar.WEDNESDAY) {
113 return false;
114 }
115 }
116 if (EndowConstants.FrequencyWeekDays.THURSDAY.equalsIgnoreCase(dayOfWeek)) {
117 if (calendarDayOfWeek != Calendar.THURSDAY) {
118 return false;
119 }
120 }
121 if (EndowConstants.FrequencyWeekDays.FRIDAY.equalsIgnoreCase(dayOfWeek)) {
122 if (calendarDayOfWeek != Calendar.FRIDAY) {
123 return false;
124 }
125 }
126
127 return isValid;
128 }
129
130 /**
131 * Validates the the day of the month part of the given date matches the day of the month part of the frequency code.
132 *
133 * @param dayOfMonth
134 * @param calendarDayOfMonth
135 * @return true if valid, false otherwise
136 */
137 private boolean validateDayOfMonth(String dayOfMonth, int calendarDayOfMonth) {
138 boolean isValid = true;
139 int frequencyCodeDayOfMonth = Integer.parseInt(dayOfMonth);
140
141 if (frequencyCodeDayOfMonth != calendarDayOfMonth) {
142 return false;
143 }
144 return isValid;
145 }
146
147
148 /**
149 * Validates that the day and month of the given date match the day and month of the frequency code.
150 *
151 * @param month
152 * @param calendarMonth
153 * @param dayOfMonth
154 * @param calendarDayOfMonth
155 * @return true if valid, false otherwise
156 */
157 private boolean validateDayAndMonth(String month, int calendarMonth, String dayOfMonth, int calendarDayOfMonth) {
158 boolean isValid = true;
159
160 if (EndowConstants.FrequencyMonthly.MONTH_END.equalsIgnoreCase(dayOfMonth)) {
161 dayOfMonth = String.valueOf(checkMaximumDaysInMonth(calendarMonth));
162 }
163
164 if (!validateDayOfMonth(dayOfMonth, calendarDayOfMonth)) {
165 return false;
166 }
167 else {
168
169 if (EndowConstants.FrequencyMonths.JANUARY.equalsIgnoreCase(month)) {
170 if (calendarMonth != Calendar.JANUARY) {
171 return false;
172 }
173 }
174 if (EndowConstants.FrequencyMonths.FEBRUARY.equalsIgnoreCase(month)) {
175 if (calendarMonth != Calendar.FEBRUARY) {
176 return false;
177 }
178 }
179 if (EndowConstants.FrequencyMonths.MARCH.equalsIgnoreCase(month)) {
180 if (calendarMonth != Calendar.MARCH) {
181 return false;
182 }
183 }
184 if (EndowConstants.FrequencyMonths.APRIL.equalsIgnoreCase(month)) {
185 if (calendarMonth != Calendar.APRIL) {
186 return false;
187 }
188 }
189 if (EndowConstants.FrequencyMonths.MAY.equalsIgnoreCase(month)) {
190 if (calendarMonth != Calendar.MAY) {
191 return false;
192 }
193 }
194 if (EndowConstants.FrequencyMonths.JUNE.equalsIgnoreCase(month)) {
195 if (calendarMonth != Calendar.JUNE) {
196 return false;
197 }
198 }
199 if (EndowConstants.FrequencyMonths.JULY.equalsIgnoreCase(month)) {
200 if (calendarDayOfMonth != Calendar.JULY) {
201 return false;
202 }
203 }
204 if (EndowConstants.FrequencyMonths.AUGUST.equalsIgnoreCase(month)) {
205 if (calendarMonth != Calendar.AUGUST) {
206 return false;
207 }
208 }
209 if (EndowConstants.FrequencyMonths.SEPTEMBER.equalsIgnoreCase(month)) {
210 if (calendarMonth != Calendar.SEPTEMBER) {
211 return false;
212 }
213 }
214 if (EndowConstants.FrequencyMonths.OCTOBER.equalsIgnoreCase(month)) {
215 if (calendarMonth != Calendar.OCTOBER) {
216 return false;
217 }
218 }
219 if (EndowConstants.FrequencyMonths.NOVEMBER.equalsIgnoreCase(month)) {
220 if (calendarMonth != Calendar.NOVEMBER) {
221 return false;
222 }
223 }
224 if (EndowConstants.FrequencyMonths.DECEMBER.equalsIgnoreCase(month)) {
225 if (calendarMonth != Calendar.DECEMBER) {
226 return false;
227 }
228 }
229 }
230 return isValid;
231 }
232
233 /**
234 * Validates that the given date day and month coincide with valid values for the quarterly frequency code. For the Quarterly
235 * frequency code the month part can be J=January, F=February and M=March. Any of this months plus 3, 6, 9 months will be a
236 * valid value for the month.
237 *
238 * @param month
239 * @param calendarMonth
240 * @param dayOfMonth
241 * @param calendarDayOfMonth
242 * @return true if valid, false otherwise
243 */
244 private boolean validateQuarterly(String month, int calendarMonth, String dayOfMonth, int calendarDayOfMonth) {
245 boolean isValid = true;
246
247 if (EndowConstants.FrequencyMonthly.MONTH_END.equalsIgnoreCase(dayOfMonth)) {
248 dayOfMonth = String.valueOf(checkMaximumDaysInMonth(calendarMonth));
249 }
250
251 if (!validateDayOfMonth(dayOfMonth, calendarDayOfMonth)) {
252 return false;
253 }
254
255 if (EndowConstants.FrequencyMonths.JANUARY.equalsIgnoreCase(month)) {
256 if (!(calendarMonth == Calendar.JANUARY || calendarMonth == Calendar.APRIL || calendarMonth == Calendar.JULY || calendarMonth == Calendar.OCTOBER)) {
257 return false;
258 }
259 }
260
261 if (EndowConstants.FrequencyMonths.FEBRUARY.equalsIgnoreCase(month)) {
262 if (!(calendarMonth == Calendar.FEBRUARY || calendarMonth == Calendar.MAY || calendarMonth == Calendar.AUGUST || calendarMonth == Calendar.NOVEMBER)) {
263 return false;
264 }
265 }
266
267 if (EndowConstants.FrequencyMonths.MARCH.equalsIgnoreCase(month)) {
268 if (!(calendarMonth == Calendar.MARCH || calendarMonth == Calendar.JUNE || calendarMonth == Calendar.SEPTEMBER || calendarMonth == Calendar.DECEMBER)) {
269 return false;
270 }
271 }
272
273 return isValid;
274 }
275
276 /**
277 * Validates the given date day and month coincide with a valid value for the semi-annually frequency code. The month part of
278 * the frequency code can be J=January, F=February, M=March, A=April, Y=May, U=June. Any of these month plus 6 months is a valid
279 * value.
280 *
281 * @param month
282 * @param calendarMonth
283 * @param dayOfMonth
284 * @param calendarDayOfMonth
285 * @return true if valid, false otherwise
286 */
287 private boolean validateSemiAnnually(String month, int calendarMonth, String dayOfMonth, int calendarDayOfMonth) {
288 boolean isValid = true;
289
290 if (EndowConstants.FrequencyMonthly.MONTH_END.equalsIgnoreCase(dayOfMonth)) {
291 dayOfMonth = String.valueOf(checkMaximumDaysInMonth(calendarMonth));
292 }
293
294 if (!validateDayOfMonth(dayOfMonth, calendarDayOfMonth)) {
295 return false;
296 }
297
298 if (EndowConstants.FrequencyMonths.JANUARY.equalsIgnoreCase(month)) {
299 if (!(calendarMonth == Calendar.JANUARY || calendarMonth == Calendar.JULY)) {
300 return false;
301 }
302 }
303
304 if (EndowConstants.FrequencyMonths.FEBRUARY.equalsIgnoreCase(month)) {
305 if (!(calendarMonth == Calendar.FEBRUARY || calendarMonth == Calendar.AUGUST)) {
306 return false;
307 }
308 }
309
310 if (EndowConstants.FrequencyMonths.MARCH.equalsIgnoreCase(month)) {
311 if (!(calendarMonth == Calendar.MARCH || calendarMonth == Calendar.SEPTEMBER)) {
312 return false;
313 }
314 }
315
316 if (EndowConstants.FrequencyMonths.APRIL.equalsIgnoreCase(month)) {
317 if (!(calendarMonth == Calendar.APRIL || calendarMonth == Calendar.OCTOBER)) {
318 return false;
319 }
320 }
321
322 if (EndowConstants.FrequencyMonths.MAY.equalsIgnoreCase(month)) {
323 if (!(calendarMonth == Calendar.MAY || calendarMonth == Calendar.NOVEMBER)) {
324 return false;
325 }
326 }
327
328 if (EndowConstants.FrequencyMonths.JUNE.equalsIgnoreCase(month)) {
329 if (!(calendarMonth == Calendar.JUNE || calendarMonth == Calendar.DECEMBER)) {
330 return false;
331 }
332 }
333
334 return isValid;
335 }
336
337 /**
338 * This method will check and return maximum days in a month.
339 *
340 * @param monthNumber The number of the month to test for maximum days..
341 * @return maxDays Maximum number of days in the month of February for calendar.
342 */
343 private int checkMaximumDaysInMonth(int monthNumber) {
344 int maxDays;
345
346 Calendar calendar = Calendar.getInstance();
347 calendar.set(Calendar.MONTH, monthNumber);
348 maxDays = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
349
350 return maxDays;
351 }
352 }