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 }