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    }