1 /** 2 * Copyright 2004-2014 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.kpme.tklm.leave.payout.validation; 17 18 import java.math.BigDecimal; 19 import java.util.Date; 20 import java.util.HashMap; 21 import java.util.List; 22 import java.util.Map; 23 24 import org.apache.commons.lang.StringUtils; 25 import org.joda.time.DateTime; 26 import org.joda.time.LocalDate; 27 import org.kuali.kpme.core.KPMENamespace; 28 import org.kuali.kpme.core.accrualcategory.AccrualCategory; 29 import org.kuali.kpme.core.accrualcategory.rule.AccrualCategoryRule; 30 import org.kuali.kpme.core.assignment.Assignment; 31 import org.kuali.kpme.core.department.Department; 32 import org.kuali.kpme.core.earncode.EarnCode; 33 import org.kuali.kpme.core.job.Job; 34 import org.kuali.kpme.core.leaveplan.LeavePlan; 35 import org.kuali.kpme.core.permission.KPMEPermissionTemplate; 36 import org.kuali.kpme.core.principal.PrincipalHRAttributes; 37 import org.kuali.kpme.core.role.KPMERole; 38 import org.kuali.kpme.core.role.KPMERoleMemberAttribute; 39 import org.kuali.kpme.core.service.HrServiceLocator; 40 import org.kuali.kpme.core.util.HrContext; 41 import org.kuali.kpme.core.util.ValidationUtils; 42 import org.kuali.kpme.tklm.common.TkConstants; 43 import org.kuali.kpme.tklm.leave.override.EmployeeOverride; 44 import org.kuali.kpme.tklm.leave.payout.LeavePayout; 45 import org.kuali.kpme.tklm.leave.service.LmServiceLocator; 46 import org.kuali.kpme.tklm.leave.summary.LeaveSummary; 47 import org.kuali.kpme.tklm.leave.summary.LeaveSummaryRow; 48 import org.kuali.kpme.tklm.time.util.TkContext; 49 import org.kuali.rice.kew.api.WorkflowDocument; 50 import org.kuali.rice.kew.api.action.RequestedActions; 51 import org.kuali.rice.kew.api.document.DocumentContent; 52 import org.kuali.rice.kew.api.document.node.RouteNodeInstance; 53 import org.kuali.rice.kim.api.KimConstants; 54 import org.kuali.rice.kim.api.identity.Person; 55 import org.kuali.rice.kim.api.services.KimApiServiceLocator; 56 import org.kuali.rice.kns.document.MaintenanceDocument; 57 import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase; 58 import org.kuali.rice.krad.bo.PersistableBusinessObject; 59 import org.kuali.rice.krad.util.GlobalVariables; 60 import org.kuali.rice.krad.util.ObjectUtils; 61 62 public class LeavePayoutValidation extends MaintenanceDocumentRuleBase { 63 64 /* private boolean validateAgainstLeavePlan(PrincipalHRAttributes pha, AccrualCategory fromAccrualCategory, LocalDate effectiveDate) { 65 boolean isValid = true; 66 if(pha==null) { 67 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.principalId", "leavePayout.principal.noLeavePlan"); 68 isValid &= false; 69 } 70 else { 71 List<AccrualCategory> accrualCategories = HrServiceLocator.getAccrualCategoryService().getActiveAccrualCategoriesForLeavePlan(pha.getLeavePlan(), effectiveDate); 72 if(accrualCategories.size() > 0) { 73 if(fromAccrualCategory != null) { 74 boolean isFromInLeavePlan = false; 75 for(AccrualCategory activeAccrualCategory : accrualCategories) { 76 if(StringUtils.equals(activeAccrualCategory.getLmAccrualCategoryId(),fromAccrualCategory.getLmAccrualCategoryId())) { 77 isFromInLeavePlan = true; 78 } 79 } 80 if(!isFromInLeavePlan) { 81 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.fromAccrualCategory", "leavePayout.accrualCategory.notInLeavePlan", fromAccrualCategory.getAccrualCategory()); 82 isValid &= false; 83 } 84 } 85 } 86 else { 87 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.principalId", "leavePayout.principal.noACinLeavePlan"); 88 isValid &=false; 89 } 90 } 91 return isValid; 92 } 93 94 //Employee Overrides??? 95 *//** 96 * Transfer amount could be validated against several variables, including max transfer amount, 97 * max carry over. 98 * ( if transfers count as usage ). 99 * @param transferAmount 100 * @param debitedAccrualCategory 101 * @param creditedAccrualCategory 102 * @param principalId TODO 103 * @param effectiveDate TODO 104 * @param isSomeAdmin 105 * @return true if transfer amount is valid 106 *//* 107 private boolean validatePayoutAmount(BigDecimal transferAmount, 108 AccrualCategory debitedAccrualCategory, 109 EarnCode payoutEarnCode, String principalId, LocalDate effectiveDate, boolean isSomeAdmin) { 110 if(transferAmount != null) { 111 if(transferAmount.compareTo(BigDecimal.ZERO) <= 0 ) { 112 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.payoutAmount", "leavePayout.payoutAmount.negative"); 113 return false; 114 } 115 if(debitedAccrualCategory != null) { 116 BigDecimal balance = LmServiceLocator.getLeaveSummaryService().getLeaveBalanceForAccrCatUpToDate(principalId, effectiveDate, effectiveDate, debitedAccrualCategory.getAccrualCategory(), effectiveDate); 117 if(balance != null) { 118 if(transferAmount.compareTo(balance) > 0 && !isSomeAdmin) { 119 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.payoutAmount", "leavePayout.payoutAmount.exceeds.balance"); 120 return false; 121 } 122 } 123 } 124 } 125 else { 126 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.payoutAmount", "leavePayout.payoutAmount.required"); 127 } 128 129 return true; 130 } 131 132 *//** 133 * Is the "From" accrual category required to be over its maximum balance before a transfer can take place? 134 * The "From" accrual category must be defined in an accrual category rule as having a max bal rule. 135 * @param accrualCategory 136 * @param effectiveDate 137 * @param principalId 138 * @param fromAccrualCategory 139 * @return 140 *//* 141 private boolean validateTransferFromAccrualCategory(AccrualCategory accrualCategory, String principalId, 142 LocalDate effectiveDate, String fromAccrualCategory) { 143 boolean isValid = ValidationUtils.validateAccCategory(fromAccrualCategory, principalId, effectiveDate); 144 if(!isValid) { 145 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.fromAccrualCategory","balanceTransfer.accrualcategory.exists",fromAccrualCategory); 146 } 147 return isValid; 148 } 149 150 private boolean validateTransferToEarnCode(EarnCode transferToEarnCode, AccrualCategoryRule acr, String principalId, PrincipalHRAttributes pha, LocalDate effectiveDate, boolean isSomeAdmin) { 151 boolean isValid = true; 152 //commenting out for KPME-2847 153 if(transferToEarnCode != null && !isSomeAdmin) { 154 LeavePlan earnCodeLeavePlan = HrServiceLocator.getLeavePlanService().getLeavePlan(transferToEarnCode.getLeavePlan(),effectiveDate); 155 if(earnCodeLeavePlan != null) { 156 LeavePlan phaLeavePlan = HrServiceLocator.getLeavePlanService().getLeavePlan(pha.getLeavePlan(), effectiveDate); 157 if(phaLeavePlan != null) { 158 //transfer to earn code should be in the employee's leave plan. 159 if(!StringUtils.equals(earnCodeLeavePlan.getLmLeavePlanId(),phaLeavePlan.getLmLeavePlanId()) && !isSomeAdmin) { 160 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.earnCode", "leavePayout.earncode.leaveplan.inconsistent"); 161 isValid &= false; 162 } 163 } 164 } 165 else { 166 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.earnCode", "leavePayout.earncode.leaveplan.exists"); 167 isValid &= false; 168 } 169 } 170 if (transferToEarnCode == null) { 171 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.earnCode", "leavePayout.earncode.exists"); 172 isValid &= false; 173 } 174 return isValid; 175 } 176 177 //transfer amount must be under max limit when submitted via max balance triggered action or by a work area approver. 178 private boolean isPayoutAmountUnderMaxLimit(String principalId, LocalDate effectiveDate, String accrualCategory, 179 BigDecimal payoutAmount, AccrualCategoryRule accrualRule, String leavePlan) { 180 181 if(ObjectUtils.isNotNull(accrualRule)) { 182 183 BigDecimal maxPayoutAmount = null; 184 if(ObjectUtils.isNotNull(accrualRule.getMaxTransferAmount())) { 185 maxPayoutAmount = new BigDecimal(accrualRule.getMaxTransferAmount()); 186 } 187 if(ObjectUtils.isNotNull(maxPayoutAmount)) { 188 EmployeeOverride eo = LmServiceLocator.getEmployeeOverrideService().getEmployeeOverride(principalId, leavePlan, accrualCategory, TkConstants.EMPLOYEE_OVERRIDE_TYPE.get("MPA"), effectiveDate); 189 if(ObjectUtils.isNotNull(eo)) 190 if(ObjectUtils.isNull(eo.getOverrideValue())) 191 maxPayoutAmount = new BigDecimal(Long.MAX_VALUE); 192 else 193 maxPayoutAmount = new BigDecimal(eo.getOverrideValue()); 194 else { 195 BigDecimal fteSum = HrServiceLocator.getJobService().getFteSumForAllActiveLeaveEligibleJobs(principalId, effectiveDate); 196 maxPayoutAmount = maxPayoutAmount.multiply(fteSum); 197 } 198 if(payoutAmount.compareTo(maxPayoutAmount) > 0) { 199 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.payoutAmount","leavePayout.exceeds.payoutLimit"); 200 return false; 201 } 202 } 203 } 204 return true; 205 } 206 207 private boolean validateAccrualCategoryRule(AccrualCategoryRule acr, 208 EarnCode payoutEarnCode, AccrualCategory fromCat, LocalDate effectiveDate) { 209 if(acr != null) { 210 EarnCode earnCode = HrServiceLocator.getEarnCodeService().getEarnCode(acr.getMaxPayoutEarnCode(),effectiveDate); 211 if(earnCode == null) { 212 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.fromAccrualCategory", "leavePayout.earncode.exists"); 213 return false; 214 } 215 else { 216 if(!StringUtils.equals(earnCode.getHrEarnCodeId(), payoutEarnCode.getHrEarnCodeId())) { 217 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.earnCode", "leavePayout.payoutEarnCode.noMatch",payoutEarnCode.getEarnCode()); 218 return false; 219 } 220 } 221 } 222 else { 223 if(!(TkContext.isDepartmentAdmin() || HrContext.isSystemAdmin() || TkContext.isLocationAdmin())) { 224 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.fromAccrualCategory", "leavePayout.fromAccrualCategory.rules.exist",fromCat.getAccrualCategory()); 225 return false; 226 } 227 } 228 return true; 229 } 230 231 @Override 232 public boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) { 233 boolean isValid = true; 234 LOG.debug("entering custom validation for Balance Transfer"); 235 236 PersistableBusinessObject pbo = (PersistableBusinessObject) this.getNewBo(); 237 238 if(pbo instanceof LeavePayout) { 239 240 LeavePayout leavePayout = (LeavePayout) pbo; 241 242 *//** 243 * Validation is basically governed by accrual category rules. Get accrual category 244 * rules for both the "To" and "From" accrual categories, pass to validators along with the 245 * values needing to be validated. 246 * 247 * Balance transfers initiated from the leave calendar display should already have all values 248 * populated, thus validated, including the accrual category rule for the "From" accrual category. 249 * 250 * Balance transfers initiated via the Maintenance tab will have no values populated. 251 *//* 252 String principalId = leavePayout.getPrincipalId(); 253 LocalDate effectiveDate = leavePayout.getEffectiveLocalDate(); 254 String fromAccrualCategory = leavePayout.getFromAccrualCategory(); 255 EarnCode payoutEarnCode = leavePayout.getEarnCodeObj(); 256 AccrualCategory fromCat = HrServiceLocator.getAccrualCategoryService().getAccrualCategory(fromAccrualCategory, effectiveDate); 257 PrincipalHRAttributes pha = HrServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(principalId,effectiveDate); 258 259 boolean isDeptAdmin = TkContext.isDepartmentAdmin(); 260 boolean isSysAdmin = HrContext.isSystemAdmin(); 261 boolean isLocAdmin = TkContext.isLocationAdmin(); 262 263 if(ObjectUtils.isNotNull(pha)) { 264 if(ObjectUtils.isNotNull(pha.getLeavePlan())) { 265 if(isDeptAdmin || isSysAdmin || isLocAdmin) { 266 isValid &= validatePayoutAmount(leavePayout.getPayoutAmount(),fromCat,payoutEarnCode, principalId, effectiveDate,true); 267 isValid &= validateAgainstLeavePlan(pha,fromCat,effectiveDate); 268 isValid &= validatePrincipal(pha,principalId,true); 269 isValid &= validateTransferFromAccrualCategory(fromCat,principalId,effectiveDate,fromAccrualCategory); 270 isValid &= validateTransferToEarnCode(payoutEarnCode,null,principalId,pha,effectiveDate,true); 271 } else { 272 AccrualCategoryRule acr = HrServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRuleForDate(fromCat, effectiveDate, pha.getServiceLocalDate()); 273 if(ObjectUtils.isNotNull(acr)) { 274 if(ObjectUtils.isNotNull(acr.getMaxBalFlag()) 275 && StringUtils.isNotBlank(acr.getMaxBalFlag()) 276 && StringUtils.isNotEmpty(acr.getMaxBalFlag()) 277 && StringUtils.equals(acr.getMaxBalFlag(), "Y")) { 278 if(ObjectUtils.isNotNull(payoutEarnCode)) { 279 isValid &= validatePrincipal(pha,principalId,false); 280 isValid &= validateEffectiveDate(effectiveDate); 281 isValid &= validateAccrualCategoryRule(acr,payoutEarnCode,fromCat,effectiveDate); 282 isValid &= validateTransferToEarnCode(payoutEarnCode,acr,principalId,pha,effectiveDate,false); 283 isValid &= validateAgainstLeavePlan(pha,fromCat,effectiveDate); 284 isValid &= validateTransferFromAccrualCategory(fromCat,principalId,effectiveDate,fromAccrualCategory); 285 isValid &= validatePayoutAmount(leavePayout.getPayoutAmount(),fromCat,payoutEarnCode, null, null,false); 286 isValid &= isPayoutAmountUnderMaxLimit(principalId, effectiveDate, fromAccrualCategory, leavePayout.getPayoutAmount(), acr, pha.getLeavePlan()); 287 } 288 else { 289 //should never be the case if accrual category rules are validated correctly. 290 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.fromAccrualCategory", 291 "leavePayout.fromAccrualCategory.rules.payoutToEarnCode", 292 fromAccrualCategory); 293 isValid &= false; 294 } 295 } 296 else { 297 //max bal flag null, blank, empty, or "N" 298 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.fromAccrualCategory", 299 "leavePayout.fromAccrualCategory.rules.maxBalFlag", fromAccrualCategory); 300 isValid &= false; 301 } 302 } 303 else { 304 //department admins must validate amount to transfer does not exceed current balance. 305 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.fromAccrualCategory", 306 "leavePayout.fromAccrualCategory.rules.exist",fromCat.getAccrualCategory()); 307 isValid &= false; 308 } 309 } 310 } 311 else { 312 //if the principal doesn't have a leave plan, there aren't any accrual categories that can be debited/credited. 313 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.principalId","leavePayout.principal.noLeavePlan"); 314 isValid &=false; 315 } 316 } 317 else { 318 //if the principal has no principal hr attributes, they're not a principal. 319 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.principalId","leavePayout.principal.noAttributes"); 320 isValid &= false; 321 } 322 } 323 return isValid; 324 }*/ 325 326 @Override 327 protected boolean processCustomRouteDocumentBusinessRules( 328 MaintenanceDocument document) { 329 boolean isValid = true; 330 331 LOG.debug("entering custom validation for Balance Transfer"); 332 333 PersistableBusinessObject pbo = (PersistableBusinessObject) this.getNewBo(); 334 335 if(pbo instanceof LeavePayout) { 336 337 LeavePayout leavePayout = (LeavePayout) pbo; 338 String fromAccrualCat = leavePayout.getFromAccrualCategory(); 339 String toEarnCode = leavePayout.getEarnCode(); 340 String principalId = leavePayout.getPrincipalId(); 341 BigDecimal payoutAmount = leavePayout.getPayoutAmount(); 342 343 isValid &= validateEffectiveDate(leavePayout.getEffectiveLocalDate()); 344 isValid &= validateAccrualCateogry(fromAccrualCat,leavePayout.getEffectiveLocalDate()); 345 isValid &= validateEarnCode(toEarnCode,leavePayout.getEffectiveLocalDate()); 346 isValid &= validatePayoutAmount(principalId,payoutAmount,fromAccrualCat,leavePayout.getEffectiveLocalDate()); 347 if(validatePrincipalId(principalId,leavePayout.getEffectiveLocalDate())) { 348 isValid &= validatePrincipal(principalId,leavePayout.getEffectiveDate(),GlobalVariables.getUserSession().getPrincipalId(),document.getDocumentHeader().getWorkflowDocument()); 349 } 350 else { 351 isValid &= false; 352 } 353 354 } 355 return isValid; 356 } 357 358 private boolean validateEffectiveDate(LocalDate date) { 359 //Limit on future dates? 360 if(date.isAfter(LocalDate.now().plusYears(1))) { 361 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.effectiveDate", "leavePayout.effectiveDate.overOneYear"); 362 return false; 363 } 364 return true; 365 } 366 367 private boolean validateAccrualCateogry(String fromAccrualCat, 368 LocalDate effectiveLocalDate) { 369 boolean valid = true; 370 if(StringUtils.isNotEmpty(fromAccrualCat)) { 371 valid &= ValidationUtils.validateAccCategory(fromAccrualCat, effectiveLocalDate); 372 if(!valid) { 373 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.fromAccrualCategory", "leavePayout.fromAccrualCategory.exists"); 374 } 375 } 376 return valid; 377 } 378 379 private boolean validatePayoutAmount(String principalId, BigDecimal payoutAmount, 380 String fromAccrualCat, LocalDate effectiveLocalDate) { 381 boolean isValid = true; 382 if(payoutAmount != null) { 383 LeaveSummary leaveSummary = LmServiceLocator.getLeaveSummaryService().getLeaveSummaryAsOfDateForAccrualCategory(principalId, effectiveLocalDate, fromAccrualCat); 384 if(leaveSummary != null) { 385 LeaveSummaryRow leaveSummaryRow = leaveSummary.getLeaveSummaryRowForAccrualCtgy(fromAccrualCat); 386 if(leaveSummaryRow != null) { 387 BigDecimal accruedBalance = leaveSummaryRow.getAccruedBalance(); 388 if(payoutAmount.compareTo(accruedBalance) > 0) { 389 isValid &= false; 390 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.payoutAmount", "leavePayout.payoutAmount.exceeds.balance"); 391 } 392 } 393 } 394 if(payoutAmount.compareTo(BigDecimal.ZERO) < 0 ) { 395 isValid &= false; 396 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.payoutAmount", "leavePayout.payoutAmount.negative"); 397 } 398 } 399 return isValid; 400 } 401 402 private boolean validatePrincipalId(String principalId, 403 LocalDate effectiveLocalDate) { 404 boolean isValid = true; 405 if(StringUtils.isNotEmpty(principalId)) { 406 isValid &= ValidationUtils.validatePrincipalId(principalId); 407 if(!isValid) { 408 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.principalId", "leavePayout.principal.exists"); 409 } 410 } 411 return isValid; 412 } 413 414 private boolean validateEarnCode(String toEarnCode, 415 LocalDate effectiveLocalDate) { 416 boolean isValid = true; 417 if(StringUtils.isNotEmpty(toEarnCode)) { 418 isValid &= ValidationUtils.validateEarnCode(toEarnCode, effectiveLocalDate); 419 if(!isValid) { 420 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.earnCode", "leavePayout.earncode.exists"); 421 } 422 } 423 return isValid; 424 } 425 426 private boolean validatePrincipal(String principalId, Date effectiveDate, String userPrincipalId, WorkflowDocument workflowDocument) { 427 boolean isValid = true; 428 PrincipalHRAttributes pha = HrServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(principalId, LocalDate.fromDateFields(effectiveDate)); 429 430 if(pha == null) { 431 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.principalId", "balanceTransfer.principal.noAttributes"); 432 isValid &= false; 433 } 434 else { 435 boolean canCreate = false; 436 if(!StringUtils.equals(principalId,userPrincipalId)) { 437 List<Job> principalsJobs = HrServiceLocator.getJobService().getActiveLeaveJobs(principalId, LocalDate.fromDateFields(effectiveDate)); 438 //TODO - performance get job/dept map in 1 query? 439 for(Job job : principalsJobs) { 440 441 442 if(job.isEligibleForLeave()) { 443 444 String department = job != null ? job.getDept() : null; 445 Department departmentObj = job != null ? HrServiceLocator.getDepartmentService().getDepartmentWithoutRoles(department, LocalDate.fromDateFields(effectiveDate)) : null; 446 String location = departmentObj != null ? departmentObj.getLocation() : null; 447 448 //logged in user may ONLY submit documents for principals in authorized departments / location. 449 if (LmServiceLocator.getLMPermissionService().isAuthorizedInDepartment(userPrincipalId, "Create Leave Payout", department, new DateTime(effectiveDate.getTime())) 450 || LmServiceLocator.getLMPermissionService().isAuthorizedInLocation(userPrincipalId, "Create Leave Payout", location, new DateTime(effectiveDate.getTime()))) { 451 canCreate = true; 452 break; 453 } 454 else { 455 //do NOT block approvers, processors, delegates from approving the document. 456 List<Assignment> assignments = HrServiceLocator.getAssignmentService().getActiveAssignmentsForJob(principalId, job.getJobNumber(), LocalDate.fromDateFields(effectiveDate)); 457 for(Assignment assignment : assignments) { 458 if(HrServiceLocator.getKPMERoleService().principalHasRoleInWorkArea(userPrincipalId, KPMENamespace.KPME_HR.getNamespaceCode(), KPMERole.APPROVER.getRoleName(), assignment.getWorkArea(), new DateTime(effectiveDate)) 459 || HrServiceLocator.getKPMERoleService().principalHasRoleInWorkArea(userPrincipalId, KPMENamespace.KPME_HR.getNamespaceCode(), KPMERole.APPROVER_DELEGATE.getRoleName(), assignment.getWorkArea(), new DateTime(effectiveDate)) 460 || HrServiceLocator.getKPMERoleService().principalHasRoleInDepartment(userPrincipalId, KPMENamespace.KPME_HR.getNamespaceCode(), KPMERole.PAYROLL_PROCESSOR.getRoleName(), assignment.getDept(), new DateTime(effectiveDate)) 461 || HrServiceLocator.getKPMERoleService().principalHasRoleInDepartment(userPrincipalId, KPMENamespace.KPME_HR.getNamespaceCode(), KPMERole.PAYROLL_PROCESSOR_DELEGATE.getRoleName(), assignment.getDept(), new DateTime(effectiveDate))) { 462 canCreate = true; 463 break; 464 } 465 } 466 } 467 } 468 } 469 } 470 else { 471 //should be able to submit their own transaction documents... 472 //max balance triggered transactions go through this validation. Set a userPrincipal to system and deny LEAVE DEPT/LOC Admins ability to submit their own 473 //transactions these simplified rules?? 474 canCreate = false; 475 } 476 477 if(!canCreate) { 478 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.principalId", "balanceTransfer.userNotAuthorized"); 479 isValid &= false; 480 } 481 } 482 return isValid; 483 } 484 }