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