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.leaverequest.service;
017
018
019 import java.util.ArrayList;
020 import java.util.HashMap;
021 import java.util.List;
022 import java.util.Map;
023
024 import org.apache.commons.lang.StringUtils;
025 import org.apache.log4j.Logger;
026 import org.kuali.hr.job.Job;
027 import org.kuali.hr.lm.leaveblock.LeaveBlock;
028 import org.kuali.hr.lm.leaverequest.LeaveRequestActionValue;
029 import org.kuali.hr.lm.leaverequest.dao.LeaveRequestDocumentDao;
030 import org.kuali.hr.lm.workflow.LeaveRequestDocument;
031 import org.kuali.hr.time.assignment.Assignment;
032 import org.kuali.hr.time.calendar.CalendarEntries;
033 import org.kuali.hr.time.service.base.TkServiceLocator;
034 import org.kuali.hr.time.util.TKContext;
035 import org.kuali.hr.time.util.TKUtils;
036 import org.kuali.hr.time.workarea.WorkArea;
037 import org.kuali.rice.kew.api.KewApiServiceLocator;
038 import org.kuali.rice.kew.api.WorkflowDocument;
039 import org.kuali.rice.kew.api.action.ActionTaken;
040 import org.kuali.rice.kew.api.action.ActionType;
041 import org.kuali.rice.kew.api.action.DocumentActionParameters;
042 import org.kuali.rice.kew.api.action.ValidActions;
043 import org.kuali.rice.kew.api.action.WorkflowDocumentActionsService;
044 import org.kuali.rice.kew.api.document.DocumentStatus;
045 import org.kuali.rice.kew.api.exception.WorkflowException;
046 import org.kuali.rice.kim.api.identity.Person;
047 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
048 import org.kuali.rice.krad.bo.DocumentHeader;
049 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
050 import org.kuali.rice.krad.util.GlobalVariables;
051
052 public class LeaveRequestDocumentServiceImpl implements LeaveRequestDocumentService {
053 private static final Logger LOG = Logger.getLogger(LeaveRequestDocumentServiceImpl.class);
054 private LeaveRequestDocumentDao leaveRequestDocumentDao;
055
056 @Override
057 public LeaveRequestDocument getLeaveRequestDocument(String documentId) {
058 LeaveRequestDocument document = null;
059 try {
060 document = (LeaveRequestDocument)KRADServiceLocatorWeb.getDocumentService().getByDocumentHeaderId(documentId);
061 } catch (WorkflowException e) {
062 LOG.error("Document with documentId: " + documentId + " does not exist");
063 }
064 return document;
065 }
066
067 @Override
068 public List<LeaveRequestDocument> getLeaveRequestDocumentsByLeaveBlockId(String leaveBlockId) {
069 List<LeaveRequestDocument> docList = getLeaveRequestDocumentDao().getLeaveRequestDocumentsByLeaveBlockId(leaveBlockId);
070 List<LeaveRequestDocument> results = new ArrayList<LeaveRequestDocument>();
071 for(LeaveRequestDocument aDoc : docList) {
072 results.add(this.getLeaveRequestDocument(aDoc.getDocumentNumber()));
073 }
074 return results;
075 }
076
077 @Override
078 public LeaveRequestDocument saveLeaveRequestDocument(LeaveRequestDocument document) {
079 LeaveRequestDocument lrd = null;
080 try {
081 lrd = (LeaveRequestDocument)KRADServiceLocatorWeb.getDocumentService().saveDocument(document);
082 } catch (WorkflowException e) {
083 LOG.error(e.getStackTrace());
084 return null;
085 }
086 return lrd;
087 }
088
089 @Override
090 public LeaveRequestDocument createLeaveRequestDocument(String leaveBlockId) {
091 LeaveRequestDocument lrd = initiateLeaveRequestDocument(TKContext.getTargetPrincipalId(), leaveBlockId);
092
093 return saveLeaveRequestDocument(lrd);
094 }
095
096 @Override
097 public void requestLeave(String documentId) {
098 LeaveRequestDocument doc = getLeaveRequestDocument(documentId);
099 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 }