View Javadoc

1   /**
2    * Copyright 2004-2013 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.hr.lm.leaverequest.service;
17  
18  
19  import java.util.ArrayList;
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.apache.log4j.Logger;
26  import org.kuali.hr.job.Job;
27  import org.kuali.hr.lm.leaveblock.LeaveBlock;
28  import org.kuali.hr.lm.leaverequest.LeaveRequestActionValue;
29  import org.kuali.hr.lm.leaverequest.dao.LeaveRequestDocumentDao;
30  import org.kuali.hr.lm.workflow.LeaveRequestDocument;
31  import org.kuali.hr.time.assignment.Assignment;
32  import org.kuali.hr.time.calendar.CalendarEntries;
33  import org.kuali.hr.time.service.base.TkServiceLocator;
34  import org.kuali.hr.time.util.TKContext;
35  import org.kuali.hr.time.util.TKUtils;
36  import org.kuali.hr.time.workarea.WorkArea;
37  import org.kuali.rice.kew.api.KewApiServiceLocator;
38  import org.kuali.rice.kew.api.WorkflowDocument;
39  import org.kuali.rice.kew.api.action.ActionTaken;
40  import org.kuali.rice.kew.api.action.ActionType;
41  import org.kuali.rice.kew.api.action.DocumentActionParameters;
42  import org.kuali.rice.kew.api.action.ValidActions;
43  import org.kuali.rice.kew.api.action.WorkflowDocumentActionsService;
44  import org.kuali.rice.kew.api.document.DocumentStatus;
45  import org.kuali.rice.kew.api.exception.WorkflowException;
46  import org.kuali.rice.kim.api.identity.Person;
47  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
48  import org.kuali.rice.krad.bo.DocumentHeader;
49  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
50  import org.kuali.rice.krad.util.GlobalVariables;
51  
52  public class LeaveRequestDocumentServiceImpl implements LeaveRequestDocumentService {
53      private static final Logger LOG = Logger.getLogger(LeaveRequestDocumentServiceImpl.class);
54      private LeaveRequestDocumentDao leaveRequestDocumentDao;
55  
56      @Override
57      public LeaveRequestDocument getLeaveRequestDocument(String documentId) {
58          LeaveRequestDocument document = null;
59          try {
60              document = (LeaveRequestDocument)KRADServiceLocatorWeb.getDocumentService().getByDocumentHeaderId(documentId);
61          } catch (WorkflowException e) {
62              LOG.error("Document with documentId: " + documentId + " does not exist");
63          }
64          return document;
65      }
66  
67      @Override
68      public List<LeaveRequestDocument> getLeaveRequestDocumentsByLeaveBlockId(String leaveBlockId) {
69      	List<LeaveRequestDocument> docList = getLeaveRequestDocumentDao().getLeaveRequestDocumentsByLeaveBlockId(leaveBlockId);
70      	List<LeaveRequestDocument> results = new ArrayList<LeaveRequestDocument>();
71      	for(LeaveRequestDocument aDoc : docList) {
72      		results.add(this.getLeaveRequestDocument(aDoc.getDocumentNumber()));
73      	}
74      	return results;
75      }
76  
77      @Override
78      public LeaveRequestDocument saveLeaveRequestDocument(LeaveRequestDocument document) {
79          LeaveRequestDocument lrd = null;
80          try {
81              lrd = (LeaveRequestDocument)KRADServiceLocatorWeb.getDocumentService().saveDocument(document);
82          } catch (WorkflowException e) {
83              LOG.error(e.getStackTrace());
84              return null;
85          }
86          return lrd;
87      }
88  
89      @Override
90      public LeaveRequestDocument createLeaveRequestDocument(String leaveBlockId) {
91          LeaveRequestDocument lrd = initiateLeaveRequestDocument(TKContext.getTargetPrincipalId(), leaveBlockId);
92  
93          return saveLeaveRequestDocument(lrd);
94      }
95  
96      @Override
97      public void requestLeave(String documentId) {
98          LeaveRequestDocument doc = getLeaveRequestDocument(documentId);
99          doc.getDocumentHeader().getWorkflowDocument().route("");
100 
101     }
102 
103     @Override
104     public void approveLeave(String documentId, String principalId, String reason) {
105         //verify principal has an action item to approve...
106         //KewApiServiceLocator.
107         LeaveRequestDocument doc = getLeaveRequestDocument(documentId);
108         
109         //do we need to switch ids?
110         doc.getDocumentHeader().getWorkflowDocument().switchPrincipal(principalId);
111         ValidActions validActions = doc.getDocumentHeader().getWorkflowDocument().getValidActions();
112         if (validActions.getValidActions().contains(ActionType.APPROVE)) {
113         	if(StringUtils.isNotEmpty(reason)) {
114     	        doc.setDescription(reason);
115     	        saveLeaveRequestDocument(doc);
116             }
117             doc.getDocumentHeader().getWorkflowDocument().approve("");
118         }
119     }
120 
121     @Override
122     public void disapproveLeave(String documentId, String principalId, String reason) {
123         LeaveRequestDocument doc = getLeaveRequestDocument(documentId);        
124         doc.getDocumentHeader().getWorkflowDocument().switchPrincipal(principalId);
125         ValidActions validActions = doc.getDocumentHeader().getWorkflowDocument().getValidActions();        
126         if (validActions.getValidActions().contains(ActionType.DISAPPROVE)) {
127         	if(StringUtils.isNotEmpty(reason)) {
128     	        doc.setDescription(reason);
129     	        saveLeaveRequestDocument(doc);
130             }
131             doc.getDocumentHeader().getWorkflowDocument().disapprove("");
132         }
133     }
134 
135     @Override
136     public void deferLeave(String documentId, String principalId, String reason) {
137         LeaveRequestDocument doc = getLeaveRequestDocument(documentId);
138         doc.getDocumentHeader().getWorkflowDocument().switchPrincipal(principalId);
139         ValidActions validActions = doc.getDocumentHeader().getWorkflowDocument().getValidActions();       
140         if (validActions.getValidActions().contains(ActionType.CANCEL)) {
141         	 if(StringUtils.isNotEmpty(reason)) {
142      	        doc.setDescription(reason);
143      	        saveLeaveRequestDocument(doc);
144              }
145         	doc.getDocumentHeader().getWorkflowDocument().cancel("");
146         }
147     }
148     
149     @Override
150     public void recallAndCancelLeave(String documentId, String principalId, String reason) {
151         LeaveRequestDocument doc = getLeaveRequestDocument(documentId);
152         if (principalId.equals(doc.getDocumentHeader().getWorkflowDocument().getInitiatorPrincipalId())) {
153             doc.getDocumentHeader().getWorkflowDocument().switchPrincipal(principalId);
154             if(StringUtils.isNotEmpty(reason)) {
155      	        doc.setDescription(reason);
156      	        saveLeaveRequestDocument(doc);
157              }
158             doc.getDocumentHeader().getWorkflowDocument().recall("", true);
159         }
160     }
161 
162     @Override
163     public void suBlanketApproveLeave(String documentId, String principalId) {
164         WorkflowDocumentActionsService docActionService = KewApiServiceLocator.getWorkflowDocumentActionsService();
165         DocumentActionParameters parameters = DocumentActionParameters.create(documentId, principalId);
166         docActionService.superUserBlanketApprove(parameters, true);
167     }
168    
169     public LeaveRequestDocumentDao getLeaveRequestDocumentDao() {
170         return leaveRequestDocumentDao;
171     }
172 
173     public void setLeaveRequestDocumentDao(LeaveRequestDocumentDao leaveRequestDocumentDao) {
174         this.leaveRequestDocumentDao = leaveRequestDocumentDao;
175     }
176 
177     private LeaveRequestDocument initiateLeaveRequestDocument(String principalId, String leaveBlockId) {
178         //LeaveRequestDocument leaveRequestDocument = new LeaveRequestDocument(leaveBlockId);
179         LeaveRequestDocument leaveRequestDocument = null;
180         try {
181             leaveRequestDocument = (LeaveRequestDocument) KRADServiceLocatorWeb.getDocumentService().getNewDocument(LeaveRequestDocument.LEAVE_REQUEST_DOCUMENT_TYPE);
182         } catch (WorkflowException e) {
183             LOG.error(e.getMessage());
184             return null;
185         }
186         
187         Person person = KimApiServiceLocator.getPersonService().getPerson(principalId);
188         LeaveBlock leaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(leaveBlockId);
189 
190         String principalName = person != null ? person.getName() : StringUtils.EMPTY;
191         String leaveRequestDateString = leaveBlock != null ? TKUtils.formatDate(leaveBlock.getLeaveDate()) : StringUtils.EMPTY;
192         String leaveRequestDocumentTitle = principalName + " (" + principalId + ") - " + leaveRequestDateString;
193         
194         leaveRequestDocument.setLmLeaveBlockId(leaveBlockId);
195         leaveRequestDocument.getDocumentHeader().setDocumentDescription(leaveRequestDocumentTitle);
196         leaveRequestDocument.setDescription(leaveBlock != null ? leaveBlock.getDescription() : StringUtils.EMPTY);
197         leaveRequestDocument.setActionCode(LeaveRequestActionValue.NO_ACTION.getCode());
198         initiateSearchableAttributes(leaveRequestDocument);
199 
200         return leaveRequestDocument;
201     }
202 
203     private void initiateSearchableAttributes(LeaveRequestDocument leaveRequestDocument) {
204         DocumentHeader dh = leaveRequestDocument.getDocumentHeader();
205         WorkflowDocument workflowDocument = dh.getWorkflowDocument();
206         if (!DocumentStatus.FINAL.equals(workflowDocument.getStatus())) {
207             try {
208                 workflowDocument.setApplicationContent(createSearchableAttributeXml(leaveRequestDocument, leaveRequestDocument.getLeaveBlock()));
209                 workflowDocument.saveDocument("");
210                 if (!"I".equals(workflowDocument.getStatus().getCode())) {
211                     if (GlobalVariables.getUserSession() != null && workflowDocument.getInitiatorPrincipalId().equals(GlobalVariables.getUserSession().getPrincipalId())) {
212                         workflowDocument.saveDocument("");
213                     } else{
214                         workflowDocument.saveDocumentData();
215                     }
216                 } else{
217                     workflowDocument.saveDocument("");
218                 }
219 
220 
221             } catch (Exception e) {
222                 LOG.warn("Exception during searchable attribute update.");
223                 throw new RuntimeException(e);
224             }
225         }
226     }
227 
228     private String createSearchableAttributeXml(LeaveRequestDocument document, LeaveBlock leaveBlock) {
229         List<Long> workAreas = new ArrayList<Long>();
230         Map<String,List<Long>> deptToListOfWorkAreas = new HashMap<String,List<Long>>();
231         List<String> salGroups = new ArrayList<String>();
232         CalendarEntries ce = getCalendarEntry(leaveBlock);
233         if (ce != null) {
234             List<Assignment> assignments = TkServiceLocator.getAssignmentService().getAssignmentsByCalEntryForLeaveCalendar(leaveBlock.getPrincipalId(), ce);
235 
236             for(Assignment assign: assignments){
237                 if(!workAreas.contains(assign.getWorkArea())){
238                     workAreas.add(assign.getWorkArea());
239                 }
240                 Job job = TkServiceLocator.getJobService().getJob(assign.getPrincipalId(), assign.getJobNumber(), leaveBlock.getLeaveDate());
241 
242                 if(!salGroups.contains(job.getHrSalGroup())){
243                     salGroups.add(job.getHrSalGroup());
244                 }
245             }
246         }
247         for(Long workArea : workAreas){
248             WorkArea workAreaObj = TkServiceLocator.getWorkAreaService().getWorkArea(workArea, TKUtils.getTimelessDate(leaveBlock.getLeaveDate()));
249             if(deptToListOfWorkAreas.containsKey(workAreaObj.getDept())){
250                 List<Long> deptWorkAreas = deptToListOfWorkAreas.get(workAreaObj.getDept());
251                 deptWorkAreas.add(workArea);
252             } else {
253                 List<Long> deptWorkAreas = new ArrayList<Long>();
254                 deptWorkAreas.add(workArea);
255                 deptToListOfWorkAreas.put(workAreaObj.getDept(), deptWorkAreas);
256             }
257         }
258         StringBuilder sb = new StringBuilder();
259         String className = document.getClass().getSimpleName();
260         sb.append("<documentContext><applicationContent><").append(className).append(">");
261         sb.append("<DEPARTMENTS>");
262         for(String dept : deptToListOfWorkAreas.keySet()){
263             sb.append("<DEPARTMENT value=\""+dept+"\">");
264             List<Long> deptWorkAreas = deptToListOfWorkAreas.get(dept);
265             for(Long workArea : deptWorkAreas){
266                 sb.append("<WORKAREA value=\""+workArea+"\"/>");
267             }
268             sb.append("</DEPARTMENT>");
269         }
270         sb.append("</DEPARTMENTS>");
271         for(String salGroup : salGroups){
272             sb.append("<SALGROUP value=\""+salGroup+"\"/>");
273         }
274 
275         sb.append("<PAYENDDATE value=\""+leaveBlock.getLeaveDate()+"\"/>");
276         sb.append("</").append(className).append("></applicationContent></documentContext>");
277 
278         return sb.toString();
279     }
280 
281     private CalendarEntries getCalendarEntry(LeaveBlock leaveBlock) {
282         return TkServiceLocator.getCalendarEntriesService().getCalendarEntries(leaveBlock.getCalendarId());
283     }
284     
285     public List<String> getApproverIdList(String documentId) {
286     	List<String> idList = new ArrayList<String>();
287     	List<ActionTaken> actions = KewApiServiceLocator.getWorkflowDocumentService().getActionsTaken(documentId);
288     	for(ActionTaken anAction : actions) {
289     		if(anAction.getActionTaken().getCode().equals(ActionType.APPROVE.getCode())
290     				&& StringUtils.isNotEmpty(anAction.getPrincipalId()) ) {
291     			idList.add(anAction.getPrincipalId());
292     		}
293     	}
294         return idList;
295     }
296     
297 }