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.workflow;
017    
018    import org.apache.log4j.Logger;
019    import org.kuali.hr.time.assignment.Assignment;
020    import org.kuali.hr.time.missedpunch.MissedPunchDocument;
021    import org.kuali.hr.time.roles.TkRole;
022    import org.kuali.hr.time.roles.service.TkRoleService;
023    import org.kuali.hr.time.service.base.TkServiceLocator;
024    import org.kuali.hr.time.timesheet.TimesheetDocument;
025    import org.kuali.hr.time.util.TKUtils;
026    import org.kuali.hr.time.util.TkConstants;
027    import org.kuali.rice.kew.api.identity.Id;
028    import org.kuali.rice.kew.api.identity.PrincipalId;
029    import org.kuali.rice.kew.api.rule.RoleName;
030    import org.kuali.rice.kew.engine.RouteContext;
031    import org.kuali.rice.kew.routeheader.DocumentContent;
032    import org.kuali.rice.kew.rule.AbstractRoleAttribute;
033    import org.kuali.rice.kew.rule.ResolvedQualifiedRole;
034    
035    import java.util.*;
036    
037    public class TkWorkflowMissedPunchAttribute extends AbstractRoleAttribute {
038    
039        private static final Logger LOG = Logger.getLogger(TkWorkflowMissedPunchAttribute.class);
040    
041        // Root of the XPath expression needed to retrieve relevant data
042    
043        public static final String XP_BO_ROOT = "/documentContent/applicationContent/org.kuali.rice.kns.workflow.KualiDocumentXmlMaterializer/document/newMaintainableObject/businessObject";
044        // Attributes on the MissedPunch object we require to determine route recipients.
045        public static final String XP_MD_A_ASSIGN = "/assignment/text()";
046        public static final String XP_MD_A_TDOCID = "/timesheetDocumentId/text()";
047    
048            @Override
049            public List<String> getQualifiedRoleNames(String roleName, DocumentContent documentContent) {
050                    List<String> roles = new ArrayList<String>();
051                    roles.add(roleName);
052                    return roles;
053            }
054    
055            /**
056             * Role name is passed in in the routing rule.
057             */
058            @Override
059            public ResolvedQualifiedRole resolveQualifiedRole(RouteContext routeContext, String roleName, String qualifiedRole) {
060                    ResolvedQualifiedRole rqr = new ResolvedQualifiedRole();
061                    List<Id> principals = new ArrayList<Id>();
062                    Long routeHeaderId = new Long(routeContext.getDocument().getDocumentId());
063    
064                    TkRoleService roleService = TkServiceLocator.getTkRoleService();
065            MissedPunchDocument missedPunch = TkServiceLocator.getMissedPunchService().getMissedPunchByRouteHeader(routeHeaderId.toString());
066    
067            String assign_string = missedPunch.getAssignment();
068            String tsDocIdString = missedPunch.getTimesheetDocumentId();
069    
070            if (tsDocIdString != null && assign_string != null) {
071                TimesheetDocument tdoc = TkServiceLocator.getTimesheetService().getTimesheetDocument(tsDocIdString);
072                if (tdoc != null) {
073                    Assignment assignment = TkServiceLocator.getAssignmentService().getAssignment(tdoc, assign_string);
074                    if (assignment != null) {
075                        List<String> users = roleService.getResponsibleParties(assignment, roleName, tdoc.getAsOfDate());
076                       
077                        // add approver delegates to users
078                        Long workAreaNumber = assignment.getWorkArea();
079                        List<TkRole> approvers = roleService.getWorkAreaRoles(workAreaNumber, roleName, TKUtils.getCurrentDate());
080                        List<TkRole> approverDelegates = roleService.getWorkAreaRoles(workAreaNumber, TkConstants.ROLE_TK_APPROVER_DELEGATE, TKUtils.getCurrentDate());
081                        Set<TkRole> roles = new HashSet<TkRole>();
082                        roles.addAll(approvers);
083                        roles.addAll(approverDelegates);
084                        for(TkRole aRole : roles) {
085                            users.add(aRole.getPrincipalId());
086                        }
087                        
088                        if(users.isEmpty()){
089                            throw new RuntimeException("No responsible people for work area" + assignment.getWorkArea());
090                        }
091                        for (String user : users) {
092                            if(user != null) {
093                                    PrincipalId pid = new PrincipalId(user);
094                                    if (!principals.contains(pid)) {
095                                        principals.add(pid);
096                                    }
097                            }
098                        }
099                    } else {
100                        throw new RuntimeException("Could not obtain Assignment.");
101                    }
102                } else {
103                    throw new RuntimeException("Could not obtain TimesheetDocument.");
104                }
105            } else {
106                throw new RuntimeException("Could not obtain Timesheet Document ID or Assignment ID");
107            }
108    
109    
110                    if (principals.size() == 0)
111                            throw new RuntimeException("No principals to route to. Push to exception routing.");
112    
113                    rqr.setRecipients(principals);
114                    return rqr;
115            }
116    
117            @Override
118            public List<RoleName> getRoleNames() {
119            return Collections.EMPTY_LIST;
120            }
121    }