1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.hr.lm.request.approval.web;
17
18 import java.sql.Date;
19 import java.text.DateFormat;
20 import java.text.SimpleDateFormat;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.Comparator;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Set;
28
29 import javax.servlet.http.HttpServletRequest;
30 import javax.servlet.http.HttpServletResponse;
31
32 import org.apache.commons.collections.CollectionUtils;
33 import org.apache.commons.lang.ObjectUtils;
34 import org.apache.commons.lang.StringUtils;
35 import org.apache.log4j.Logger;
36 import org.apache.struts.action.ActionForm;
37 import org.apache.struts.action.ActionForward;
38 import org.apache.struts.action.ActionMapping;
39 import org.hsqldb.lib.StringUtil;
40 import org.json.simple.JSONArray;
41 import org.json.simple.JSONValue;
42 import org.kuali.hr.lm.leaveblock.LeaveBlock;
43 import org.kuali.hr.lm.workflow.LeaveRequestDocument;
44 import org.kuali.hr.time.assignment.Assignment;
45 import org.kuali.hr.time.base.web.ApprovalAction;
46 import org.kuali.hr.time.service.base.TkServiceLocator;
47 import org.kuali.hr.time.util.TKContext;
48 import org.kuali.hr.time.util.TKUser;
49 import org.kuali.hr.time.util.TKUtils;
50 import org.kuali.hr.time.workarea.WorkArea;
51 import org.kuali.rice.kew.api.KewApiServiceLocator;
52 import org.kuali.rice.kew.api.action.ActionItem;
53 import org.kuali.rice.kim.api.identity.Person;
54 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
55
56 public class LeaveRequestApprovalAction extends ApprovalAction {
57
58 private static final Logger LOG = Logger.getLogger(LeaveRequestApprovalAction.class);
59 public static final String DOC_SEPARATOR = "----";
60 public static final String ID_SEPARATOR = "____";
61 public static final String DOC_NOT_FOUND = "Leave request document not found with id ";
62 public static final String LEAVE_BLOCK_NOT_FOUND = "Leave Block not found for Leave request document ";
63
64 @Override
65 public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
66 ActionForward forward = super.execute(mapping, form, request, response);
67 LeaveRequestApprovalActionForm lraaForm = (LeaveRequestApprovalActionForm) form;
68
69 Date currentDate = TKUtils.getCurrentDate();
70 Set<Long> workAreas = TkServiceLocator.getTkRoleService().getWorkAreasForApprover(TKContext.getPrincipalId(), currentDate);
71 List<String> principalIds = new ArrayList<String>();
72 for (Long workArea : workAreas) {
73 List<Assignment> assignments = TkServiceLocator.getAssignmentService().getActiveAssignmentsForWorkArea(workArea, currentDate);
74 for (Assignment a : assignments) {
75 principalIds.add(a.getPrincipalId());
76 }
77 }
78
79
80 List<String> calGroups = new ArrayList<String>();
81 if (CollectionUtils.isNotEmpty(principalIds)) {
82 calGroups = TkServiceLocator.getLeaveApprovalService().getUniqueLeavePayGroupsForPrincipalIds(principalIds);
83 }
84 lraaForm.setPayCalendarGroups(calGroups);
85
86 List<String> depts = new ArrayList<String>(TKContext.getUser().getReportingApprovalDepartments().keySet());
87 Collections.sort(depts);
88 lraaForm.setDepartments(depts);
89
90
91 List<ActionItem> items = filterActionsWithSeletedParameters(lraaForm.getSelectedPayCalendarGroup(),
92 lraaForm.getSelectedDept(), this.getWorkAreaList(lraaForm));
93 List<LeaveRequestApprovalEmployeeRow> rowList = this.getEmployeeRows(items);
94 lraaForm.setEmployeeRows(rowList);
95 return forward;
96 }
97
98 public ActionForward loadApprovalTab(ActionMapping mapping, ActionForm form,
99 HttpServletRequest request, HttpServletResponse response) throws Exception {
100 ActionForward fwd = mapping.findForward("basic");
101 LeaveRequestApprovalActionForm lraaForm = (LeaveRequestApprovalActionForm) form;
102 Date currentDate = TKUtils.getCurrentDate();
103
104
105 if(StringUtils.isEmpty(lraaForm.getSelectedDept())) {
106 resetState(form, request);
107
108 Set<Long> workAreas = TkServiceLocator.getTkRoleService().getWorkAreasForApprover(TKContext.getPrincipalId(), currentDate);
109 List<String> principalIds = new ArrayList<String>();
110 for (Long workArea : workAreas) {
111 List<Assignment> assignments = TkServiceLocator.getAssignmentService().getActiveAssignmentsForWorkArea(workArea, currentDate);
112 for (Assignment a : assignments) {
113 principalIds.add(a.getPrincipalId());
114 }
115 }
116
117 List<String> calGroups = new ArrayList<String>();
118 if (CollectionUtils.isNotEmpty(principalIds)) {
119 calGroups = TkServiceLocator.getLeaveApprovalService().getUniqueLeavePayGroupsForPrincipalIds(principalIds);
120 }
121 lraaForm.setPayCalendarGroups(calGroups);
122 if (StringUtils.isBlank(lraaForm.getSelectedPayCalendarGroup())
123 && CollectionUtils.isNotEmpty(calGroups)) {
124 lraaForm.setSelectedPayCalendarGroup(calGroups.get(0));
125 }
126
127 List<String> depts = new ArrayList<String>(TKContext.getUser().getReportingApprovalDepartments().keySet());
128 Collections.sort(depts);
129 lraaForm.setDepartments(depts);
130 if (StringUtils.isBlank(lraaForm.getSelectedDept())
131 && lraaForm.getDepartments().size() == 1) {
132 lraaForm.setSelectedDept(lraaForm.getDepartments().get(0));
133 lraaForm.getWorkAreaDescr().clear();
134 List<WorkArea> workAreaList = TkServiceLocator.getWorkAreaService().getWorkAreas(lraaForm.getSelectedDept(), currentDate);
135 for(WorkArea wa : workAreaList){
136 if (TKContext.getUser().getApproverWorkAreas().contains(wa.getWorkArea())
137 || TKContext.getUser().getReviewerWorkAreas().contains(wa.getWorkArea())) {
138 lraaForm.getWorkAreaDescr().put(wa.getWorkArea(),wa.getDescription()+"("+wa.getWorkArea()+")");
139 }
140 }
141 }
142 }
143
144
145 List<ActionItem> items = filterActionsWithSeletedParameters(lraaForm.getSelectedPayCalendarGroup(),
146 lraaForm.getSelectedDept(), this.getWorkAreaList(lraaForm));
147 List<LeaveRequestApprovalEmployeeRow> rowList = this.getEmployeeRows(items);
148 lraaForm.setEmployeeRows(rowList);
149
150 return fwd;
151 }
152
153 public ActionForward selectNewPayCalendar(ActionMapping mapping, ActionForm form,
154 HttpServletRequest request, HttpServletResponse response)
155 throws Exception {
156
157 super.resetMainFields(form);
158 LeaveRequestApprovalActionForm lraaForm = (LeaveRequestApprovalActionForm) form;
159 lraaForm.setEmployeeRows(new ArrayList<LeaveRequestApprovalEmployeeRow>());
160
161 return loadApprovalTab(mapping, form, request, response);
162 }
163
164 public ActionForward selectNewDept(ActionMapping mapping, ActionForm form,
165 HttpServletRequest request, HttpServletResponse response)
166 throws Exception {
167 LeaveRequestApprovalActionForm lraaForm = (LeaveRequestApprovalActionForm) form;
168
169 Date currentDate = TKUtils.getCurrentDate();
170
171 lraaForm.getWorkAreaDescr().clear();
172 List<WorkArea> workAreas = TkServiceLocator.getWorkAreaService().getWorkAreas(lraaForm.getSelectedDept(), currentDate);
173 for(WorkArea wa : workAreas){
174 if (TKContext.getUser().getApproverWorkAreas().contains(wa.getWorkArea())
175 || TKContext.getUser().getReviewerWorkAreas().contains(wa.getWorkArea())) {
176 lraaForm.getWorkAreaDescr().put(wa.getWorkArea(),wa.getDescription()+"("+wa.getWorkArea()+")");
177 }
178 }
179
180 List<ActionItem> items = filterActionsWithSeletedParameters(lraaForm.getSelectedPayCalendarGroup(),
181 lraaForm.getSelectedDept(), this.getWorkAreaList(lraaForm));
182 List<LeaveRequestApprovalEmployeeRow> rowList = this.getEmployeeRows(items);
183 lraaForm.setEmployeeRows(rowList);
184
185 return mapping.findForward("basic");
186 }
187
188 public ActionForward selectNewWorkArea(ActionMapping mapping, ActionForm form,
189 HttpServletRequest request, HttpServletResponse response)
190 throws Exception {
191 LeaveRequestApprovalActionForm lraaForm = (LeaveRequestApprovalActionForm) form;
192
193
194 List<ActionItem> items = filterActionsWithSeletedParameters(lraaForm.getSelectedPayCalendarGroup(),
195 lraaForm.getSelectedDept(), this.getWorkAreaList(lraaForm));
196 List<LeaveRequestApprovalEmployeeRow> rowList = this.getEmployeeRows(items);
197 lraaForm.setEmployeeRows(rowList);
198
199 return mapping.findForward("basic");
200 }
201
202 private List<ActionItem> filterActionsWithSeletedParameters(String calGroup, String dept, List<String> workAreaList) {
203 String principalId = TKUser.getCurrentTargetPerson().getPrincipalId();
204 List<ActionItem> actionList = KewApiServiceLocator.getActionListService().getActionItemsForPrincipal(principalId);
205 List<ActionItem> resultsList = new ArrayList<ActionItem>();
206
207 Date currentDate = TKUtils.getCurrentDate();
208 List<String> principalIds = TkServiceLocator.getLeaveApprovalService()
209 .getLeavePrincipalIdsWithSearchCriteria(workAreaList, calGroup, currentDate, currentDate, currentDate);
210
211 if(CollectionUtils.isNotEmpty(principalIds)) {
212 for(ActionItem anAction : actionList) {
213 String docId = anAction.getDocumentId();
214 if(anAction.getDocName().equals(LeaveRequestDocument.LEAVE_REQUEST_DOCUMENT_TYPE)) {
215 LeaveRequestDocument lrd = TkServiceLocator.getLeaveRequestDocumentService().getLeaveRequestDocument(docId);
216 if(lrd != null) {
217 LeaveBlock lb = lrd.getLeaveBlock();
218 if(lb != null) {
219 if(principalIds.contains(lb.getPrincipalId())) {
220 resultsList.add(anAction);
221 }
222 }
223 }
224 }
225 }
226 }
227
228 return resultsList;
229 }
230
231 private List<String> getWorkAreaList(LeaveRequestApprovalActionForm lraaForm) {
232 List<String> workAreaList = new ArrayList<String>();
233 if(StringUtil.isEmpty(lraaForm.getSelectedWorkArea())) {
234 for(Long aKey : lraaForm.getWorkAreaDescr().keySet()) {
235 workAreaList.add(aKey.toString());
236 }
237 } else {
238 workAreaList.add(lraaForm.getSelectedWorkArea());
239 }
240 return workAreaList;
241 }
242
243 public void resetState(ActionForm form, HttpServletRequest request) {
244 LeaveRequestApprovalActionForm lraaForm = (LeaveRequestApprovalActionForm) form;
245 lraaForm.getDepartments().clear();
246 lraaForm.getWorkAreaDescr().clear();
247 lraaForm.setEmployeeRows(new ArrayList<LeaveRequestApprovalEmployeeRow>());
248 lraaForm.setSelectedDept(null);
249 lraaForm.setSearchField(null);
250 lraaForm.setSearchTerm(null);
251 }
252
253 public ActionForward takeActionOnEmployee(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
254 LeaveRequestApprovalActionForm lraaForm = (LeaveRequestApprovalActionForm) form;
255
256 if(StringUtils.isNotEmpty(lraaForm.getApproveList())) {
257 String[] approveList = lraaForm.getApproveList().split(DOC_SEPARATOR);
258 for(String eachAction : approveList){
259 String[] fields = eachAction.split(ID_SEPARATOR);
260 String docId = fields[0];
261 String reasonString = fields.length > 1 ? fields[1] : "";
262 TkServiceLocator.getLeaveRequestDocumentService().approveLeave(docId, TKContext.getPrincipalId(), reasonString);
263
264 }
265 }
266 if(StringUtils.isNotEmpty(lraaForm.getDisapproveList())) {
267 String[] disapproveList = lraaForm.getDisapproveList().split(DOC_SEPARATOR);
268 for(String eachAction : disapproveList){
269 String[] fields = eachAction.split(ID_SEPARATOR);
270 String docId = fields[0];
271 String reasonString = fields.length > 1 ? fields[1] : "";
272 TkServiceLocator.getLeaveRequestDocumentService().disapproveLeave(docId, TKContext.getPrincipalId(), reasonString);
273
274 }
275 }
276 if(StringUtils.isNotEmpty(lraaForm.getDeferList())) {
277 String[] deferList = lraaForm.getDeferList().split(DOC_SEPARATOR);
278 for(String eachAction : deferList){
279 String[] fields = eachAction.split(ID_SEPARATOR);
280 String docId = fields[0];
281 String reasonString = fields.length > 1 ? fields[1] : "";
282 TkServiceLocator.getLeaveRequestDocumentService().deferLeave(docId, TKContext.getPrincipalId(), reasonString);
283
284 }
285 }
286 return mapping.findForward("basic");
287 }
288
289 private List<LeaveRequestApprovalEmployeeRow> getEmployeeRows(List<ActionItem> actionList) {
290 List<LeaveRequestApprovalEmployeeRow> empRowList = new ArrayList<LeaveRequestApprovalEmployeeRow>();
291 Map<String, List<LeaveRequestDocument>> docMap = new HashMap<String, List<LeaveRequestDocument>>();
292 for(ActionItem action : actionList) {
293 if(action.getDocName().equals(LeaveRequestDocument.LEAVE_REQUEST_DOCUMENT_TYPE)) {
294 String docId = action.getDocumentId();
295 LeaveRequestDocument lrd = TkServiceLocator.getLeaveRequestDocumentService().getLeaveRequestDocument(docId);
296 if(lrd != null) {
297 LeaveBlock lb = lrd.getLeaveBlock();
298 if(lb != null) {
299 String lbPrincipalId = lb.getPrincipalId();
300 List<LeaveRequestDocument> docList = docMap.get(lbPrincipalId) == null ? new ArrayList<LeaveRequestDocument>() : docMap.get(lbPrincipalId);
301 docList.add(lrd);
302 docMap.put(lbPrincipalId, docList);
303 }
304 }
305
306 }
307 }
308 for (Map.Entry<String, List<LeaveRequestDocument>> entry : docMap.entrySet()) {
309 LeaveRequestApprovalEmployeeRow aRow = this.getAnEmployeeRow(entry.getKey(), entry.getValue());
310 if(aRow != null) {
311 empRowList.add(aRow);
312 }
313 }
314
315 Collections.sort(empRowList, new Comparator<LeaveRequestApprovalEmployeeRow>() {
316 @Override
317 public int compare(LeaveRequestApprovalEmployeeRow row1, LeaveRequestApprovalEmployeeRow row2) {
318 return ObjectUtils.compare(row1.getEmployeeName(), row2.getEmployeeName());
319 }
320 });
321
322 return empRowList;
323 }
324
325 private LeaveRequestApprovalEmployeeRow getAnEmployeeRow(String principalId, List<LeaveRequestDocument> docList) {
326 if(CollectionUtils.isEmpty(docList) || StringUtils.isEmpty(principalId)) {
327 return null;
328 }
329 Person principal = KimApiServiceLocator.getPersonService().getPerson(principalId);
330 if(principal == null) {
331 return null;
332 }
333 LeaveRequestApprovalEmployeeRow empRow = new LeaveRequestApprovalEmployeeRow();
334 empRow.setPrincipalId(principalId);
335 empRow.setEmployeeName(principal.getName());
336 List<LeaveRequestApprovalRow> rowList = new ArrayList<LeaveRequestApprovalRow>();
337 for(LeaveRequestDocument lrd : docList) {
338 if(lrd == null) {
339 return null;
340 }
341 LeaveBlock lb = lrd.getLeaveBlock();
342 if(lb == null) {
343 return null;
344 }
345 LeaveRequestApprovalRow aRow = new LeaveRequestApprovalRow();
346 aRow.setLeaveRequestDocId(lrd.getDocumentNumber());
347 aRow.setLeaveCode(lb.getEarnCode());
348 aRow.setRequestedDate(TKUtils.formatDate(lb.getLeaveDate()));
349 aRow.setRequestedHours(lb.getLeaveAmount().toString());
350 aRow.setDescription(lrd.getDescription());
351 DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
352 aRow.setSubmittedTime(df.format( new Date(lrd.getDocumentHeader().getWorkflowDocument().getDateCreated().getMillis())));
353 rowList.add(aRow);
354 }
355
356 if(CollectionUtils.isNotEmpty(rowList)) {
357 Collections.sort(rowList, new Comparator<LeaveRequestApprovalRow>() {
358 @Override
359 public int compare(LeaveRequestApprovalRow row1, LeaveRequestApprovalRow row2) {
360 return ObjectUtils.compare(row1.getRequestedDate(), row2.getRequestedDate());
361 }
362 });
363 empRow.setLeaveRequestList(rowList);
364 }
365 return empRow;
366 }
367
368 @SuppressWarnings("unchecked")
369 public ActionForward validateActions(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
370 LeaveRequestApprovalActionForm lraaForm = (LeaveRequestApprovalActionForm) form;
371 JSONArray errorMsgList = new JSONArray();
372 List<String> errors = new ArrayList<String>();
373 if(StringUtils.isEmpty(lraaForm.getApproveList())
374 && StringUtils.isEmpty(lraaForm.getDisapproveList())
375 && StringUtils.isEmpty(lraaForm.getDeferList())) {
376 errors.add("No Actions selected. Please try again.");
377 } else {
378 if(StringUtils.isNotEmpty(lraaForm.getApproveList())) {
379 String[] approveList = lraaForm.getApproveList().split(DOC_SEPARATOR);
380 for(String eachAction : approveList){
381 String[] fields = eachAction.split(ID_SEPARATOR);
382 String docId = fields[0];
383 LeaveRequestDocument lrd = TkServiceLocator.getLeaveRequestDocumentService().getLeaveRequestDocument(docId);
384 if(lrd == null) {
385 errors.add(DOC_NOT_FOUND + docId);
386 break;
387 } else {
388 LeaveBlock lb = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lrd.getLmLeaveBlockId());
389 if(lb == null) {
390 errors.add(LEAVE_BLOCK_NOT_FOUND + docId);
391 break;
392 }
393 }
394 }
395 }
396 if(StringUtils.isNotEmpty(lraaForm.getDisapproveList())) {
397 String[] disapproveList = lraaForm.getDisapproveList().split(DOC_SEPARATOR);
398 for(String eachAction : disapproveList){
399 String[] fields = eachAction.split(ID_SEPARATOR);
400 String docId = fields[0];
401 String reasonString = fields.length > 1 ? fields[1] : "";
402 if(StringUtils.isEmpty(reasonString)) {
403 errors.add("Reason is required for Disapprove action");
404 break;
405 } else {
406 LeaveRequestDocument lrd = TkServiceLocator.getLeaveRequestDocumentService().getLeaveRequestDocument(docId);
407 if(lrd == null) {
408 errors.add(DOC_NOT_FOUND + docId);
409 break;
410 }else {
411 LeaveBlock lb = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lrd.getLmLeaveBlockId());
412 if(lb == null) {
413 errors.add(LEAVE_BLOCK_NOT_FOUND + docId);
414 break;
415 }
416 }
417 }
418 }
419 }
420 if(StringUtils.isNotEmpty(lraaForm.getDeferList())) {
421 String[] deferList = lraaForm.getDeferList().split(DOC_SEPARATOR);
422 for(String eachAction : deferList){
423 String[] fields = eachAction.split(ID_SEPARATOR);
424 String docId = fields[0];
425 String reasonString = fields.length > 1 ? fields[1] : "";
426 if(StringUtils.isEmpty(reasonString)) {
427 errors.add("Reason is required for Defer action");
428 break;
429 } else {
430 LeaveRequestDocument lrd = TkServiceLocator.getLeaveRequestDocumentService().getLeaveRequestDocument(docId);
431 if(lrd == null) {
432 errors.add(DOC_NOT_FOUND + docId);
433 break;
434 }else {
435 LeaveBlock lb = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lrd.getLmLeaveBlockId());
436 if(lb == null) {
437 errors.add(LEAVE_BLOCK_NOT_FOUND + docId);
438 break;
439 }
440 }
441 }
442 }
443 }
444 }
445 errorMsgList.addAll(errors);
446 lraaForm.setOutputString(JSONValue.toJSONString(errorMsgList));
447 return mapping.findForward("ws");
448 }
449 }