001 /**
002 * Copyright 2004-2012 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.hr.time.util;
017
018 import java.math.BigDecimal;
019 import java.sql.Date;
020 import java.util.HashMap;
021 import java.util.List;
022 import java.util.Map;
023
024 import org.apache.commons.lang.StringUtils;
025 import org.kuali.hr.earncodesec.EarnCodeSecurity;
026 import org.kuali.hr.location.Location;
027 import org.kuali.hr.paygrade.PayGrade;
028 import org.kuali.hr.time.accrual.AccrualCategory;
029 import org.kuali.hr.time.accrual.TimeOffAccrual;
030 import org.kuali.hr.time.authorization.DepartmentalRule;
031 import org.kuali.hr.time.calendar.Calendar;
032 import org.kuali.hr.time.department.Department;
033 import org.kuali.hr.time.earncode.EarnCode;
034 import org.kuali.hr.time.earngroup.EarnGroup;
035 import org.kuali.hr.time.earngroup.EarnGroupDefinition;
036 import org.kuali.hr.time.paytype.PayType;
037 import org.kuali.hr.time.salgroup.SalGroup;
038 import org.kuali.hr.time.service.base.TkServiceLocator;
039 import org.kuali.hr.time.task.Task;
040 import org.kuali.hr.time.workarea.WorkArea;
041 import org.kuali.kfs.coa.businessobject.Chart;
042 import org.kuali.rice.kim.api.identity.Person;
043 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
044 import org.kuali.rice.krad.service.KRADServiceLocator;
045
046 /**
047 * A few methods to assist with various validation tasks.
048 */
049 public class ValidationUtils {
050
051 /**
052 * For DepartmentalRule objects, if a work area is defined, you can not
053 * leave the department field with a wildcard. Permission for wildcarding
054 * will be checked with other methods.
055 *
056 * @param dr The DepartmentalRule to examine.
057 * @return true if valid, false otherwise.
058 */
059 public static boolean validateWorkAreaDeptWildcarding(DepartmentalRule dr) {
060 boolean ret = true;
061
062 if (StringUtils.equals(dr.getDept(), TkConstants.WILDCARD_CHARACTER)) {
063 ret = dr.getWorkArea().equals(TkConstants.WILDCARD_LONG);
064 }
065
066 return ret;
067 }
068
069 /**
070 * Most basic validation: Only checks for presence in the database.
071 */
072 public static boolean validateWorkArea(Long workArea) {
073 return validateWorkArea(workArea, null);
074 }
075
076 /**
077 * Most basic validation: Only checks for presence in the database.
078 */
079 public static boolean validateDepartment(String department) {
080 return validateDepartment(department, null);
081 }
082
083 /**
084 * Most basic validation: Only checks for presence in the database.
085 */
086 public static boolean validateAccrualCategory(String accrualCategory) {
087 return validateAccrualCategory(accrualCategory, null);
088 }
089
090
091 public static boolean validateSalGroup(String salGroup, Date asOfDate) {
092 boolean valid = false;
093
094 if (StringUtils.equals(salGroup, TkConstants.WILDCARD_CHARACTER)) {
095 valid = true;
096 } else if (asOfDate != null) {
097 SalGroup sg = TkServiceLocator.getSalGroupService().getSalGroup(salGroup, asOfDate);
098 valid = (sg != null);
099 } else {
100 int count = TkServiceLocator.getSalGroupService().getSalGroupCount(salGroup);
101 valid = (count > 0);
102 }
103
104 return valid;
105 }
106
107 public static boolean validateEarnCode(String earnCode, Date asOfDate) {
108 boolean valid = false;
109
110 if (asOfDate != null) {
111 EarnCode ec = TkServiceLocator.getEarnCodeService().getEarnCode(earnCode, asOfDate);
112 valid = (ec != null);
113 } else {
114 int count = TkServiceLocator.getEarnCodeService().getEarnCodeCount(earnCode);
115 valid = (count > 0);
116 }
117
118 return valid;
119 }
120
121 public static boolean validateEarnCodeOfAccrualCategory(String earnCode, String accrualCategory, String principalId, Date asOfDate) {
122 boolean valid = false;
123
124 return valid;
125 }
126
127 public static boolean validateAccCategory(String accrualCategory, Date asOfDate) {
128 boolean valid = false;
129
130 if (asOfDate != null) {
131 AccrualCategory ac = TkServiceLocator.getAccrualCategoryService().getAccrualCategory(accrualCategory, asOfDate);
132 valid = (ac != null);
133 } else {
134 Map<String, String> fieldValues = new HashMap<String, String>();
135 fieldValues.put("accrualCategory", accrualCategory);
136 int matches = KRADServiceLocator.getBusinessObjectService().countMatching(AccrualCategory.class, fieldValues);
137
138 valid = matches > 0;
139 }
140
141 return valid;
142 }
143
144 public static boolean validateLocation(String location, Date asOfDate) {
145 boolean valid = false;
146
147 if (asOfDate != null) {
148 Location l = TkServiceLocator.getLocationService().getLocation(location, asOfDate);
149 valid = (l != null);
150 } else {
151 int count = TkServiceLocator.getLocationService().getLocationCount(location);
152 valid = (count > 0);
153 }
154
155 return valid;
156 }
157
158 public static boolean validatePayType(String payType, Date asOfDate) {
159 boolean valid = false;
160
161 if (asOfDate != null) {
162 PayType pt = TkServiceLocator.getPayTypeService().getPayType(payType, asOfDate);
163 valid = (pt != null);
164 } else {
165 int count = TkServiceLocator.getPayTypeService().getPayTypeCount(payType);
166 valid = (count > 0);
167 }
168
169 return valid;
170 }
171
172
173 public static boolean validatePayGrade(String payGrade, Date asOfDate) {
174 boolean valid = false;
175
176 if (asOfDate != null) {
177 PayGrade pg = TkServiceLocator.getPayGradeService().getPayGrade(payGrade, asOfDate);
178 valid = (pg != null);
179 } else {
180 int count = TkServiceLocator.getPayGradeService().getPayGradeCount(payGrade);
181 valid = (count > 0);
182 }
183
184 return valid;
185 }
186
187 /**
188 *
189 * @param earnCode
190 * @param otEarnCode If true, earn code is valid ONLY if it is an overtime earn code.
191 * @param asOfDate
192 * @return
193 */
194 public static boolean validateEarnCode(String earnCode, boolean otEarnCode, Date asOfDate) {
195 boolean valid = false;
196
197 if (asOfDate != null) {
198 EarnCode ec = TkServiceLocator.getEarnCodeService().getEarnCode(earnCode, asOfDate);
199 valid = (ec != null) && (otEarnCode ? ec.getOvtEarnCode().booleanValue() : true);
200 }
201
202 return valid;
203 }
204
205 /**
206 * Checks for row presence of a department, and optionally whether or not
207 * it is active as of the specified date.
208 */
209 public static boolean validateDepartment(String department, Date asOfDate) {
210 boolean valid = false;
211
212 if (StringUtils.isEmpty(department)) {
213 // do nothing, let false be returned.
214 } else if (asOfDate != null) {
215 Department d = TkServiceLocator.getDepartmentService().getDepartment(department, asOfDate);
216 valid = (d != null);
217 } else {
218 int count = TkServiceLocator.getDepartmentService().getDepartmentCount(department);
219 valid = (count > 0);
220 }
221
222 return valid;
223 }
224
225 public static boolean validateChart(String chart) {
226 boolean valid = false;
227
228 if (!StringUtils.isEmpty(chart)) {
229 Object o = KRADServiceLocator.getBusinessObjectService().findBySinglePrimaryKey(Chart.class, chart);
230 valid = (o instanceof Chart);
231 }
232
233 return valid;
234 }
235
236 /**
237 * Checks for row presence of a work area, and optionally whether or not
238 * it is active as of the specified date.
239 */
240 public static boolean validateWorkArea(Long workArea, Date asOfDate) {
241 return ValidationUtils.validateWorkArea(workArea, null, asOfDate);
242 }
243
244 public static boolean validateWorkArea(Long workArea, String dept, Date asOfDate) {
245 boolean valid = false;
246
247 if (workArea == null) {
248 valid = false;
249 } else if (workArea.equals(TkConstants.WILDCARD_LONG)) {
250 valid = true;
251 } else if (asOfDate != null) {
252 WorkArea wa = TkServiceLocator.getWorkAreaService().getWorkArea(workArea, asOfDate);
253 if (wa != null && dept != null) {
254 valid = StringUtils.equalsIgnoreCase(dept, wa.getDept());
255 } else {
256 valid = (wa != null);
257 }
258 } else {
259 // Not valid if no date is passed.
260 }
261
262 return valid;
263 }
264 /**
265 * Checks for row presence of a Accrual Category, and optionally whether or not
266 * it is active as of the specified date.
267 */
268 public static boolean validateAccrualCategory(String accrualCategory, Date asOfDate) {
269 boolean valid = false;
270
271 if (StringUtils.equals(accrualCategory, TkConstants.WILDCARD_CHARACTER)) {
272 valid = true;
273 } else if (asOfDate != null) {
274 AccrualCategory ac = TkServiceLocator.getAccrualCategoryService().getAccrualCategory(accrualCategory, asOfDate);
275 valid = (ac != null);
276 }
277
278 return valid;
279 }
280
281 /**
282 * Checks for row presence of a principal Id, and optionally whether or not
283 * it is active as of the specified date.
284 */
285 public static boolean validatePrincipalId(String principalId) {
286 boolean valid = false;
287 if (principalId != null) {
288 Person p = KimApiServiceLocator.getPersonService().getPerson(principalId);
289 valid = (p != null);
290 }
291 return valid;
292 }
293
294 /**
295 * No wildcarding is accounted for in this method.
296 * @param task Task "Long Name"
297 * @param asOfDate Can be null, if we just want to look for the general case.
298 * @return True if the task is present / valid.
299 */
300 public static boolean validateTask(Long task, Date asOfDate) {
301 boolean valid = false;
302
303 if (task != null && asOfDate != null) {
304 Task t = TkServiceLocator.getTaskService().getTask(task, asOfDate);
305 valid = (t != null);
306 } else if (task != null) {
307 int count = TkServiceLocator.getTaskService().getTaskCount(task);
308 valid = (count > 0);
309 }
310
311 return valid;
312 }
313
314 /**
315 * No wildcarding is accounted for in this method.
316 * @param earnGroup EarnCodeGroup
317 * @param asOfDate Can be null, if we just want to look for the general case.
318 * @return True if the EarnCodeGroup is present / valid.
319 */
320 public static boolean validateEarnGroup(String earnGroup, Date asOfDate) {
321 boolean valid = false;
322
323 if (earnGroup != null && asOfDate != null) {
324 EarnGroup eg = TkServiceLocator.getEarnGroupService().getEarnGroup(earnGroup, asOfDate);
325 valid = (eg != null);
326 } else if (earnGroup != null) {
327 int count = TkServiceLocator.getEarnGroupService().getEarnGroupCount(earnGroup);
328 valid = (count > 0);
329 }
330
331 return valid;
332 }
333
334 /**
335 * @param earnGroup EarnCodeGroup
336 * @param asOfDate
337 * @return True if the EarnCodeGroup has overtime earn codes
338 */
339 public static boolean earnGroupHasOvertimeEarnCodes(String earnGroup, Date asOfDate) {
340 if (earnGroup != null && asOfDate != null) {
341 EarnGroup eg = TkServiceLocator.getEarnGroupService().getEarnGroup(earnGroup, asOfDate);
342 if(eg != null) {
343 for(EarnGroupDefinition egd : eg.getEarnGroups()) {
344 if(egd.getEarnCode() != null) {
345 EarnCode ec = TkServiceLocator.getEarnCodeService().getEarnCode(egd.getEarnCode(), asOfDate);
346 if(ec != null && ec.getOvtEarnCode()) {
347 return true;
348 }
349 }
350 }
351 }
352 }
353
354 return false;
355 }
356
357
358 /**
359 * Checks for row presence of a pay calendar
360 */
361 public static boolean validateCalendar(String calendarName) {
362 Map<String, String> fieldValues = new HashMap<String, String>();
363 fieldValues.put("calendarName", calendarName);
364 int matches = KRADServiceLocator.getBusinessObjectService().countMatching(Calendar.class, fieldValues);
365
366 return matches > 0;
367 }
368
369 public static boolean duplicateDeptEarnCodeExists(EarnCodeSecurity deptEarnCode) {
370 boolean valid = false;
371 int count = TkServiceLocator.getEarnCodeSecurityService().getEarnCodeSecurityCount
372 (deptEarnCode.getDept(), deptEarnCode.getHrSalGroup(), deptEarnCode.getEarnCode(), deptEarnCode.isEmployee() ? "1" : "0",
373 deptEarnCode.isApprover() ? "1" : "0", deptEarnCode.getLocation(), deptEarnCode.getActive() ? "Y" : "N", deptEarnCode.getEffectiveDate(), null);
374 if(count == 1) {
375 valid = true;
376 count = TkServiceLocator.getEarnCodeSecurityService().getEarnCodeSecurityCount
377 (deptEarnCode.getDept(), deptEarnCode.getHrSalGroup(), deptEarnCode.getEarnCode(), deptEarnCode.isEmployee() ? "1" : "0",
378 deptEarnCode.isApprover() ? "1" : "0", deptEarnCode.getLocation(), deptEarnCode.getActive() ? "Y" : "N", deptEarnCode.getEffectiveDate(), deptEarnCode.getHrEarnCodeSecurityId());
379 if(count == 1) {
380 valid = false;
381 }
382 } else if(count > 1) {
383 valid = true;
384 }
385
386 return valid;
387 }
388
389 public static boolean duplicateTimeOffAccrual (TimeOffAccrual timeOffAccrual) {
390 boolean valid = false;
391 int count = TkServiceLocator.getTimeOffAccrualService().getTimeOffAccrualCount
392 (timeOffAccrual.getAccrualCategory(), timeOffAccrual.getEffectiveDate(), timeOffAccrual.getPrincipalId(), null);
393 if(count == 1) {
394 valid = true;
395 count = TkServiceLocator.getTimeOffAccrualService().getTimeOffAccrualCount
396 (timeOffAccrual.getAccrualCategory(), timeOffAccrual.getEffectiveDate(), timeOffAccrual.getPrincipalId(), timeOffAccrual.getLmAccrualId());
397 if(count == 1) {
398 valid = false;
399 }
400 } else if(count > 1) {
401 valid = true;
402 }
403 return valid;
404 }
405
406 /**
407 * Checks for date not more than one year in the future or current date
408 *
409 */
410
411 public static boolean validateOneYearFutureDate(Date date){
412 java.util.Calendar startDate = java.util.Calendar.getInstance();
413 startDate.add(java.util.Calendar.DATE, -1);
414 startDate.set(java.util.Calendar.SECOND, 0);
415 startDate.set(java.util.Calendar.MINUTE, 0);
416 startDate.set(java.util.Calendar.HOUR_OF_DAY, 0);
417 java.util.Calendar endDate = java.util.Calendar.getInstance();
418 endDate.add(java.util.Calendar.YEAR, 1); // One year after the current date
419 return date.compareTo(startDate.getTime()) * date.compareTo(endDate.getTime()) <= 0;
420 }
421
422 /**
423 * Checks for date not more than one year in the future and does not consider past date
424 *
425 */
426
427 public static boolean validateOneYearFutureEffectiveDate(Date date){
428 java.util.Calendar startDate = java.util.Calendar.getInstance();
429 startDate.set(java.util.Calendar.MILLISECOND, 0);
430 startDate.set(java.util.Calendar.SECOND, 0);
431 startDate.set(java.util.Calendar.MINUTE, 0);
432 startDate.set(java.util.Calendar.HOUR_OF_DAY, 0);
433 startDate.add(java.util.Calendar.YEAR, 1); // One year after the current date
434 return date.compareTo(startDate.getTime()) <= 0;
435 }
436
437 /**
438 * Checks for date in the future
439 *
440 */
441
442 public static boolean validateFutureDate(Date date){
443 java.util.Calendar startDate = java.util.Calendar.getInstance();
444 startDate.add(java.util.Calendar.DATE, 0);
445 startDate.set(java.util.Calendar.SECOND, 0);
446 startDate.set(java.util.Calendar.MINUTE, 0);
447 startDate.set(java.util.Calendar.HOUR_OF_DAY, 0);
448 return date.compareTo(startDate.getTime()) > 0;
449 }
450
451 /**
452 * Checks for row presence of a pay calendar by calendar type
453 */
454 public static boolean validateCalendarByType(String calendarName, String calendarType) {
455 Map<String, String> fieldValues = new HashMap<String, String>();
456 fieldValues.put("calendarName", calendarName);
457 fieldValues.put("calendarTypes", calendarType);
458 int matches = KRADServiceLocator.getBusinessObjectService().countMatching(Calendar.class, fieldValues);
459
460 return matches > 0;
461 }
462
463 public static boolean validateRecordMethod(String recordMethod, String accrualCategory, Date asOfDate) {
464 boolean valid = false;
465 if (asOfDate != null) {
466 AccrualCategory ac = TkServiceLocator.getAccrualCategoryService().getAccrualCategory(accrualCategory, asOfDate);
467 if (ac != null
468 && ac.getUnitOfTime() != null) {
469 if (TkConstants.RECORD_METHOD.HOUR.equals(ac.getUnitOfTime())
470 && (TkConstants.RECORD_METHOD.HOUR.equals(recordMethod))
471 || TkConstants.RECORD_METHOD.TIME.equals(recordMethod)) {
472 valid = true;
473 } else {
474 valid = StringUtils.equalsIgnoreCase(ac.getUnitOfTime(), recordMethod);
475 }
476
477 }
478 }
479 return valid;
480 }
481
482 }