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.lm.workflow; 017 018 019 import org.apache.cxf.common.util.StringUtils; 020 import org.apache.log4j.Logger; 021 import org.kuali.hr.job.Job; 022 import org.kuali.hr.lm.leaveblock.LeaveBlock; 023 import org.kuali.hr.time.assignment.Assignment; 024 import org.kuali.hr.time.calendar.CalendarEntries; 025 import org.kuali.hr.time.roles.TkRole; 026 import org.kuali.hr.time.roles.service.TkRoleService; 027 import org.kuali.hr.time.service.base.TkServiceLocator; 028 import org.kuali.hr.time.util.TKUtils; 029 import org.kuali.hr.time.util.TkConstants; 030 import org.kuali.hr.time.workarea.WorkArea; 031 import org.kuali.rice.kew.api.identity.Id; 032 import org.kuali.rice.kew.api.identity.PrincipalId; 033 import org.kuali.rice.kew.api.rule.RoleName; 034 import org.kuali.rice.kew.engine.RouteContext; 035 import org.kuali.rice.kew.routeheader.DocumentContent; 036 import org.kuali.rice.kew.rule.AbstractRoleAttribute; 037 import org.kuali.rice.kew.rule.ResolvedQualifiedRole; 038 039 import java.util.ArrayList; 040 import java.util.Collections; 041 import java.util.List; 042 043 public class LeaveRequestWorkflowAttribute extends AbstractRoleAttribute { 044 private static final Logger LOG = Logger.getLogger(LeaveRequestWorkflowAttribute.class); 045 046 @Override 047 public List<String> getQualifiedRoleNames(String roleName, DocumentContent documentContent) { 048 List<String> roles = new ArrayList<String>(); 049 String documentNumber = documentContent.getRouteContext().getDocument().getDocumentId(); 050 LeaveRequestDocument leaveRequestDocument = TkServiceLocator.getLeaveRequestDocumentService().getLeaveRequestDocument(documentNumber); 051 052 if (leaveRequestDocument != null) { 053 LeaveBlock leaveBlock = leaveRequestDocument.getLeaveBlock(); 054 CalendarEntries ce = getCalendarEntry(leaveBlock); 055 List<Assignment> assignments = TkServiceLocator.getAssignmentService().getAssignmentsByCalEntryForLeaveCalendar(leaveBlock.getPrincipalId(), ce); 056 for (Assignment assignment : assignments) { 057 String roleStr = roleName + "_" +assignment.getWorkArea(); 058 if(!roles.contains(roleStr)){ 059 roles.add(roleStr); 060 } 061 } 062 } 063 return roles; 064 } 065 066 /** 067 * Role name is passed in in the routing rule. 068 */ 069 @Override 070 public ResolvedQualifiedRole resolveQualifiedRole(RouteContext routeContext, String roleName, String qualifiedRole) { 071 ResolvedQualifiedRole rqr = new ResolvedQualifiedRole(); 072 Long workAreaNumber = null; 073 074 try { 075 int pos = qualifiedRole.lastIndexOf("_"); 076 if (pos > -1) { 077 String subs = qualifiedRole.substring(pos+1, qualifiedRole.length()); 078 workAreaNumber = Long.parseLong(subs); 079 } 080 } catch (NumberFormatException nfe) { 081 LOG.error("qualifiedRole did not contain numeric data for work area."); 082 } 083 084 if (workAreaNumber == null) { 085 throw new RuntimeException("Unable to resolve work area during routing."); 086 } 087 088 List<Id> principals = new ArrayList<Id>(); 089 String routeHeaderId = routeContext.getDocument().getDocumentId(); 090 TkRoleService roleService = TkServiceLocator.getTkRoleService(); 091 LeaveRequestDocument leaveRequestDocument = TkServiceLocator.getLeaveRequestDocumentService().getLeaveRequestDocument(routeHeaderId); 092 LeaveBlock leaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(leaveRequestDocument.getLmLeaveBlockId()); 093 WorkArea workArea = TkServiceLocator.getWorkAreaService().getWorkArea(workAreaNumber, leaveBlock.getLeaveDate()); 094 095 // KPME-1071 096 List<TkRole> approvers = roleService.getWorkAreaRoles(workAreaNumber, roleName, TKUtils.getCurrentDate()); 097 List<TkRole> approverDelegates = roleService.getWorkAreaRoles(workAreaNumber, TkConstants.ROLE_TK_APPROVER_DELEGATE, TKUtils.getCurrentDate()); 098 List<TkRole> roles = new ArrayList<TkRole>(); 099 roles.addAll(approvers); 100 roles.addAll(approverDelegates); 101 102 for (TkRole role : roles) { 103 //Position routing 104 if(StringUtils.isEmpty(role.getPrincipalId())){ 105 String positionNumber = role.getPositionNumber(); 106 List<Job> lstJobsForPosition = TkServiceLocator.getJobService().getActiveJobsForPosition(positionNumber, getCalendarEntry(leaveBlock).getEndPeriodDateTime()); 107 for(Job job : lstJobsForPosition){ 108 PrincipalId pid = new PrincipalId(job.getPrincipalId()); 109 if (!principals.contains(pid)) { 110 principals.add(pid); 111 } 112 } 113 } else { 114 PrincipalId pid = new PrincipalId(role.getPrincipalId()); 115 if (!principals.contains(pid)) { 116 principals.add(pid); 117 } 118 } 119 } 120 121 if (principals.size() == 0) 122 throw new RuntimeException("No principals to route to. Push to exception routing."); 123 124 rqr.setRecipients(principals); 125 rqr.setAnnotation("Dept: "+ workArea.getDept()+", Work Area: "+workArea.getWorkArea()); 126 127 return rqr; 128 } 129 130 @Override 131 public List<RoleName> getRoleNames() { 132 return Collections.EMPTY_LIST; 133 } 134 135 private CalendarEntries getCalendarEntry(LeaveBlock leaveBlock) { 136 return TkServiceLocator.getCalendarEntriesService().getCalendarEntries(leaveBlock.getCalendarId()); 137 } 138 }