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 }