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