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.balancetransfer.BalanceTransfer; 023 import org.kuali.hr.lm.leaveblock.LeaveBlock; 024 import org.kuali.hr.time.assignment.Assignment; 025 import org.kuali.hr.time.calendar.CalendarEntries; 026 import org.kuali.hr.time.roles.TkRole; 027 import org.kuali.hr.time.roles.service.TkRoleService; 028 import org.kuali.hr.time.service.base.TkServiceLocator; 029 import org.kuali.hr.time.util.TKUtils; 030 import org.kuali.hr.time.util.TkConstants; 031 import org.kuali.hr.time.workarea.WorkArea; 032 import org.kuali.rice.kew.api.exception.WorkflowException; 033 import org.kuali.rice.kew.api.identity.Id; 034 import org.kuali.rice.kew.api.identity.PrincipalId; 035 import org.kuali.rice.kew.api.rule.RoleName; 036 import org.kuali.rice.kew.engine.RouteContext; 037 import org.kuali.rice.kew.routeheader.DocumentContent; 038 import org.kuali.rice.kew.rule.AbstractRoleAttribute; 039 import org.kuali.rice.kew.rule.ResolvedQualifiedRole; 040 import org.kuali.rice.krad.maintenance.MaintenanceDocument; 041 import org.kuali.rice.krad.service.KRADServiceLocatorWeb; 042 import org.kuali.rice.krad.util.ObjectUtils; 043 044 import java.util.ArrayList; 045 import java.util.Collections; 046 import java.util.List; 047 048 public class BalanceTransferWorkflowAttribute extends AbstractRoleAttribute { 049 private static final Logger LOG = Logger.getLogger(BalanceTransferWorkflowAttribute.class); 050 051 @Override 052 public List<String> getQualifiedRoleNames(String roleName, DocumentContent documentContent) { 053 List<String> roles = new ArrayList<String>(); 054 String documentNumber = documentContent.getRouteContext().getDocument().getDocumentId(); 055 MaintenanceDocument document = null; 056 try { 057 document = (MaintenanceDocument) KRADServiceLocatorWeb.getDocumentService().getByDocumentHeaderId(documentNumber); 058 } catch (WorkflowException e) { 059 // TODO Auto-generated catch block 060 e.printStackTrace(); 061 } 062 BalanceTransfer balanceTransfer = null; 063 if(ObjectUtils.isNotNull(document)) 064 balanceTransfer = (BalanceTransfer) document.getNewMaintainableObject().getDataObject(); 065 066 if (balanceTransfer != null) { 067 List<Assignment> assignments = TkServiceLocator.getAssignmentService().getAssignments(balanceTransfer.getPrincipalId(), balanceTransfer.getEffectiveDate()); 068 for(Assignment assignment : assignments) { 069 String roleStr = roleName+"_"+assignment.getWorkArea(); 070 if(!roles.contains(roleStr)) 071 roles.add(roleStr); 072 } 073 074 } 075 return roles; 076 } 077 078 /** 079 * Role name is passed in in the routing rule. 080 */ 081 @Override 082 public ResolvedQualifiedRole resolveQualifiedRole(RouteContext routeContext, String roleName, String qualifiedRole) { 083 ResolvedQualifiedRole rqr = new ResolvedQualifiedRole(); 084 Long workAreaNumber = null; 085 086 try { 087 int pos = qualifiedRole.lastIndexOf("_"); 088 if (pos > -1) { 089 String subs = qualifiedRole.substring(pos+1, qualifiedRole.length()); 090 workAreaNumber = Long.parseLong(subs); 091 } 092 } catch (NumberFormatException nfe) { 093 LOG.error("qualifiedRole did not contain numeric data for work area."); 094 } 095 096 if (workAreaNumber == null) { 097 throw new RuntimeException("Unable to resolve work area during routing."); 098 } 099 100 List<Id> principals = new ArrayList<Id>(); 101 String routeHeaderId = routeContext.getDocument().getDocumentId(); 102 MaintenanceDocument document = null; 103 try { 104 document = (MaintenanceDocument) KRADServiceLocatorWeb.getDocumentService().getByDocumentHeaderId(routeHeaderId); 105 } catch (WorkflowException e) { 106 LOG.error("unable to retrieve the Maintenance Document with route hearder id: " + routeHeaderId); 107 e.printStackTrace(); 108 } 109 TkRoleService roleService = TkServiceLocator.getTkRoleService(); 110 BalanceTransfer balanceTransfer = null; 111 if(ObjectUtils.isNotNull(document)) { 112 balanceTransfer = (BalanceTransfer) document.getNewMaintainableObject().getDataObject(); 113 } 114 if(ObjectUtils.isNotNull(balanceTransfer)) { 115 WorkArea workArea = TkServiceLocator.getWorkAreaService().getWorkArea(workAreaNumber, balanceTransfer.getEffectiveDate()); 116 117 // KPME-1071 118 List<TkRole> approvers = roleService.getWorkAreaRoles(workAreaNumber, roleName, TKUtils.getCurrentDate()); 119 List<TkRole> approverDelegates = roleService.getWorkAreaRoles(workAreaNumber, TkConstants.ROLE_TK_APPROVER_DELEGATE, TKUtils.getCurrentDate()); 120 List<TkRole> roles = new ArrayList<TkRole>(); 121 roles.addAll(approvers); 122 roles.addAll(approverDelegates); 123 124 for (TkRole role : roles) { 125 //Position routing 126 if(StringUtils.isEmpty(role.getPrincipalId())){ 127 String positionNumber = role.getPositionNumber(); 128 List<Job> lstJobsForPosition = TkServiceLocator.getJobService().getActiveJobsForPosition(positionNumber, balanceTransfer.getEffectiveDate()); 129 for(Job job : lstJobsForPosition){ 130 PrincipalId pid = new PrincipalId(job.getPrincipalId()); 131 if (!principals.contains(pid)) { 132 principals.add(pid); 133 } 134 } 135 } else { 136 PrincipalId pid = new PrincipalId(role.getPrincipalId()); 137 if (!principals.contains(pid)) { 138 principals.add(pid); 139 } 140 } 141 } 142 143 if (principals.size() == 0) { 144 throw new RuntimeException("No principals to route to. Push to exception routing."); 145 } 146 rqr.setRecipients(principals); 147 rqr.setAnnotation("Dept: "+ workArea.getDept()+", Work Area: "+workArea.getWorkArea()); 148 return rqr; 149 } 150 else { 151 throw new RuntimeException("no business object could be retreived"); 152 } 153 } 154 155 @Override 156 public List<RoleName> getRoleNames() { 157 return Collections.EMPTY_LIST; 158 } 159 160 private CalendarEntries getCalendarEntry(LeaveBlock leaveBlock) { 161 return TkServiceLocator.getCalendarEntriesService().getCalendarEntries(leaveBlock.getCalendarId()); 162 } 163 }