View Javadoc

1   /**
2    * Copyright 2004-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.hr.time.util;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.hr.lm.LMConstants;
20  import org.kuali.hr.lm.accrual.AccrualCategory;
21  import org.kuali.hr.lm.earncodesec.EarnCodeSecurity;
22  import org.kuali.hr.lm.leaveplan.LeavePlan;
23  import org.kuali.hr.location.Location;
24  import org.kuali.hr.paygrade.PayGrade;
25  import org.kuali.hr.time.authorization.DepartmentalRule;
26  import org.kuali.hr.time.calendar.Calendar;
27  import org.kuali.hr.time.department.Department;
28  import org.kuali.hr.time.earncode.EarnCode;
29  import org.kuali.hr.time.earncodegroup.EarnCodeGroup;
30  import org.kuali.hr.time.earncodegroup.EarnCodeGroupDefinition;
31  import org.kuali.hr.time.paytype.PayType;
32  import org.kuali.hr.time.principal.PrincipalHRAttributes;
33  import org.kuali.hr.time.salgroup.SalGroup;
34  import org.kuali.hr.time.service.base.TkServiceLocator;
35  import org.kuali.hr.time.task.Task;
36  import org.kuali.hr.time.workarea.WorkArea;
37  import org.kuali.kfs.coa.businessobject.Chart;
38  import org.kuali.rice.kim.api.identity.principal.Principal;
39  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
40  import org.kuali.rice.krad.service.KRADServiceLocator;
41  
42  import java.math.BigDecimal;
43  import java.sql.Date;
44  import java.util.HashMap;
45  import java.util.List;
46  import java.util.Map;
47  
48  /**
49   * A few methods to assist with various validation tasks.
50   */
51  public class ValidationUtils {
52  
53      /**
54       * For DepartmentalRule objects, if a work area is defined, you can not
55       * leave the department field with a wildcard. Permission for wildcarding
56       * will be checked with other methods.
57       *
58       * @param dr The DepartmentalRule to examine.
59       * @return true if valid, false otherwise.
60       */
61      public static boolean validateWorkAreaDeptWildcarding(DepartmentalRule dr) {
62          boolean ret = true;
63  
64          if (StringUtils.equals(dr.getDept(), TkConstants.WILDCARD_CHARACTER)) {
65              ret = dr.getWorkArea().equals(TkConstants.WILDCARD_LONG);
66          }
67  
68          return ret;
69      }
70  
71  	/**
72  	 * Most basic validation: Only checks for presence in the database.
73  	 */
74  	public static boolean validateWorkArea(Long workArea) {
75  		return validateWorkArea(workArea, null);
76  	}
77  
78  	/**
79  	 * Most basic validation: Only checks for presence in the database.
80  	 */
81  	public static boolean validateDepartment(String department) {
82  		return validateDepartment(department, null);
83  	}
84  
85  	/**
86  	 * Most basic validation: Only checks for presence in the database.
87  	 */
88  	public static boolean validateAccrualCategory(String accrualCategory) {
89  		return validateAccrualCategory(accrualCategory, null);
90  	}
91  
92  
93  	public static boolean validateSalGroup(String salGroup, Date asOfDate) {
94  		boolean valid = false;
95  
96  		if (StringUtils.equals(salGroup, TkConstants.WILDCARD_CHARACTER)) {
97  			valid = true;
98  		} else if (asOfDate != null) {
99  			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 }