1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 package org.kuali.kpme.tklm.leave.payout.web;
32
33 import java.math.BigDecimal;
34 import java.util.Collections;
35 import java.util.Comparator;
36 import java.util.List;
37
38 import javax.servlet.http.HttpServletRequest;
39 import javax.servlet.http.HttpServletResponse;
40
41 import org.apache.commons.lang.StringUtils;
42 import org.apache.log4j.Logger;
43 import org.apache.struts.action.ActionForm;
44 import org.apache.struts.action.ActionForward;
45 import org.apache.struts.action.ActionMapping;
46 import org.apache.struts.action.ActionRedirect;
47 import org.joda.time.LocalDate;
48 import org.kuali.kpme.core.accrualcategory.AccrualCategory;
49 import org.kuali.kpme.core.accrualcategory.rule.AccrualCategoryRule;
50 import org.kuali.kpme.core.calendar.entry.CalendarEntry;
51 import org.kuali.kpme.core.service.HrServiceLocator;
52 import org.kuali.kpme.core.util.HrConstants;
53 import org.kuali.kpme.core.web.KPMEAction;
54 import org.kuali.kpme.tklm.leave.block.LeaveBlock;
55 import org.kuali.kpme.tklm.leave.calendar.LeaveCalendarDocument;
56 import org.kuali.kpme.tklm.leave.payout.LeavePayout;
57 import org.kuali.kpme.tklm.leave.payout.validation.LeavePayoutValidationUtils;
58 import org.kuali.kpme.tklm.leave.service.LmServiceLocator;
59 import org.kuali.kpme.tklm.leave.workflow.LeaveCalendarDocumentHeader;
60 import org.kuali.kpme.tklm.time.service.TkServiceLocator;
61 import org.kuali.kpme.tklm.time.timesheet.TimesheetDocument;
62 import org.kuali.kpme.tklm.time.workflow.TimesheetDocumentHeader;
63 import org.kuali.rice.krad.service.KRADServiceLocator;
64 import org.kuali.rice.krad.util.GlobalVariables;
65 import org.kuali.rice.krad.util.KRADConstants;
66 import org.kuali.rice.krad.util.ObjectUtils;
67
68 public class LeavePayoutAction extends KPMEAction {
69
70 private static final Logger LOG = Logger.getLogger(LeavePayoutAction.class);
71
72 public ActionForward leavePayoutOnLeaveApproval(ActionMapping mapping, ActionForm form,
73 HttpServletRequest request, HttpServletResponse response) throws Exception {
74
75
76 LeavePayoutForm lpf = (LeavePayoutForm) form;
77 LeavePayout leavePayout = lpf.getLeavePayout();
78
79 boolean valid = LeavePayoutValidationUtils.validatePayout(leavePayout);
80
81
82
83
84
85 if(valid) {
86
87 String accrualRuleId = leavePayout.getAccrualCategoryRule();
88
89 String documentId = leavePayout.getLeaveCalendarDocumentId();
90 TimesheetDocumentHeader tsdh = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeader(documentId);
91 LeaveCalendarDocumentHeader lcdh = LmServiceLocator.getLeaveCalendarDocumentHeaderService().getDocumentHeader(documentId);
92 CalendarEntry calendarEntry = null;
93 String strutsActionForward = "";
94 String methodToCall = "approveLeaveCalendar";
95 if(ObjectUtils.isNull(tsdh) && ObjectUtils.isNull(lcdh)) {
96 LOG.error("No document found");
97
98 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, "error.document.notfound");
99 mapping.findForward("basic");
100 }
101 else if(ObjectUtils.isNotNull(tsdh)) {
102
103 TimesheetDocument tsd = TkServiceLocator.getTimesheetService().getTimesheetDocument(documentId);
104 calendarEntry = tsd == null ? null : tsd.getCalendarEntry();
105 strutsActionForward = "timesheetPayoutSuccess";
106 methodToCall = "approveTimesheet";
107 }
108 else {
109 LeaveCalendarDocument lcd = LmServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(documentId);
110 calendarEntry = lcd == null ? null : lcd.getCalendarEntry();
111 strutsActionForward = "leaveCalendarPayoutSuccess";
112 methodToCall = "approveLeaveCalendar";
113 }
114
115 if(ObjectUtils.isNull(calendarEntry)) {
116 LOG.error("Could not retreive calendar entry for document " + documentId);
117
118 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, "error.calendarentry.notfound", new String[] {documentId});
119 return mapping.findForward("basic");
120 }
121
122 AccrualCategoryRule accrualRule = HrServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(accrualRuleId);
123 AccrualCategory accrualCategory = HrServiceLocator.getAccrualCategoryService().getAccrualCategory(accrualRule.getLmAccrualCategoryId());
124 BigDecimal accruedBalance = LmServiceLocator.getAccrualService().getAccruedBalanceForPrincipal(leavePayout.getPrincipalId(), accrualCategory, leavePayout.getEffectiveLocalDate());
125
126 LeavePayout defaultBT = LmServiceLocator.getLeavePayoutService().initializePayout(leavePayout.getPrincipalId(), accrualRuleId, accruedBalance, leavePayout.getEffectiveLocalDate());
127 if(leavePayout.getPayoutAmount().compareTo(defaultBT.getPayoutAmount()) != 0) {
128
129
130 leavePayout = defaultBT.adjust(leavePayout.getPayoutAmount());
131
132
133
134
135
136 leavePayout.setLeaveCalendarDocumentId(documentId);
137 }
138
139 LmServiceLocator.getLeavePayoutService().submitToWorkflow(leavePayout);
140
141 if(ObjectUtils.isNotNull(documentId)) {
142 if(StringUtils.equals(accrualRule.getMaxBalanceActionFrequency(),HrConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE) ||
143 StringUtils.equals(accrualRule.getMaxBalanceActionFrequency(), HrConstants.MAX_BAL_ACTION_FREQ.YEAR_END)) {
144
145 ActionForward forward = new ActionForward(mapping.findForward(strutsActionForward));
146 forward.setPath(forward.getPath()+"?documentId="+documentId+"&action=R&methodToCall="+methodToCall);
147 return forward;
148 }
149 else
150 return mapping.findForward("closeLeavePayoutDoc");
151 }
152 else
153 return mapping.findForward("closeLeavePayoutDoc");
154 }
155 else
156 return mapping.findForward("basic");
157 }
158
159 public ActionForward cancel(ActionMapping mapping, ActionForm form,
160 HttpServletRequest request, HttpServletResponse response)
161 throws Exception {
162
163 LeavePayoutForm lpf = (LeavePayoutForm) form;
164 LeavePayout leavePayout = lpf.getLeavePayout();
165 String accrualCategoryRuleId = leavePayout.getAccrualCategoryRule();
166 AccrualCategoryRule accrualRule = HrServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(accrualCategoryRuleId);
167 String actionFrequency = accrualRule.getMaxBalanceActionFrequency();
168
169 if(StringUtils.equals(actionFrequency,HrConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND))
170 return mapping.findForward("closeLeavePayoutDoc");
171 else
172 if(StringUtils.equals(actionFrequency, HrConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE) ||
173 StringUtils.equals(actionFrequency, HrConstants.MAX_BAL_ACTION_FREQ.YEAR_END)) {
174
175 String documentId = leavePayout.getLeaveCalendarDocumentId();
176 TimesheetDocumentHeader tsdh = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeader(documentId);
177 LeaveCalendarDocumentHeader lcdh = LmServiceLocator.getLeaveCalendarDocumentHeaderService().getDocumentHeader(documentId);
178 String strutsActionForward = "";
179 if(ObjectUtils.isNull(tsdh) && ObjectUtils.isNull(lcdh)) {
180 strutsActionForward = "/";
181 }
182 else if(ObjectUtils.isNotNull(tsdh)) {
183
184 strutsActionForward = mapping.findForward("timesheetCancel").getPath() + "?documentId=" + leavePayout.getLeaveCalendarDocumentId();
185 }
186 else {
187 strutsActionForward = mapping.findForward("leaveCalendarCancel").getPath() + "?documentId=" + leavePayout.getLeaveCalendarDocumentId();
188 }
189
190 ActionRedirect redirect = new ActionRedirect();
191 redirect.setPath(strutsActionForward);
192 return redirect;
193
194 }
195 else {
196 LOG.warn("Action should only be reachable through triggers with frequency ON_DEMAND or LEAVE_APPROVE");
197 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, "action.reachable.through.triggers");
198
199 return mapping.findForward("basic");
200 }
201 }
202
203
204
205 public ActionForward leavePayoutOnDemand(ActionMapping mapping, ActionForm form,
206 HttpServletRequest request, HttpServletResponse response)
207 throws Exception {
208 GlobalVariables.getMessageMap().putWarning("document.payoutAmount","leavePayout.payoutAmount.adjust");
209
210 LeavePayoutForm lpf = (LeavePayoutForm) form;
211
212 String documentId = request.getParameter("documentId");
213 String leaveBlockId = request.getParameter("accrualRuleId");
214 String timesheet = request.getParameter("timesheet");
215
216 boolean isTimesheet = false;
217 if(StringUtils.equals(timesheet, "true")) {
218 lpf.isTimesheet(true);
219 isTimesheet = true;
220 }
221 if(ObjectUtils.isNotNull(leaveBlockId)) {
222 AccrualCategoryRule aRule = HrServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(leaveBlockId);
223 if(ObjectUtils.isNotNull(aRule)) {
224
225 if(!StringUtils.equals(aRule.getMaxBalanceActionFrequency(),HrConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND)) {
226
227 LOG.error("attempted to execute on-demand balance payout for accrual category with action frequency " + aRule.getMaxBalanceActionFrequency());
228 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, "attempted.payout.accrualcategory",new String[] { aRule.getMaxBalanceActionFrequency()});
229 return mapping.findForward("basic");
230 } else {
231 TimesheetDocument tsd = null;
232 LeaveCalendarDocument lcd = null;
233 String principalId = null;
234 CalendarEntry calendarEntry = null;
235
236 if(isTimesheet) {
237 tsd = TkServiceLocator.getTimesheetService().getTimesheetDocument(documentId);
238 principalId = tsd == null ? null : tsd.getPrincipalId();
239 }
240 else {
241 lcd = LmServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(documentId);
242 principalId = lcd == null ? null : lcd.getPrincipalId();
243 }
244
245 AccrualCategoryRule accrualRule = HrServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(leaveBlockId);
246 AccrualCategory accrualCategory = HrServiceLocator.getAccrualCategoryService().getAccrualCategory(accrualRule.getLmAccrualCategoryId());
247 BigDecimal accruedBalance = LmServiceLocator.getAccrualService().getAccruedBalanceForPrincipal(principalId, accrualCategory, LocalDate.now());
248
249 LeavePayout leavePayout = LmServiceLocator.getLeavePayoutService().initializePayout(principalId, leaveBlockId, accruedBalance, LocalDate.now());
250 leavePayout.setLeaveCalendarDocumentId(documentId);
251 if(ObjectUtils.isNotNull(leavePayout)) {
252 if(StringUtils.equals(aRule.getActionAtMaxBalance(),HrConstants.ACTION_AT_MAX_BALANCE.LOSE)) {
253
254
255
256
257
258 leavePayout = LmServiceLocator.getLeavePayoutService().payout(leavePayout);
259
260 LeaveBlock forfeitedLeaveBlock = LmServiceLocator.getLeaveBlockService().getLeaveBlock(leavePayout.getForfeitedLeaveBlockId());
261 forfeitedLeaveBlock.setRequestStatus(HrConstants.REQUEST_STATUS.APPROVED);
262 LmServiceLocator.getLeaveBlockService().updateLeaveBlock(forfeitedLeaveBlock, principalId);
263 return mapping.findForward("closeLeavePayoutDoc");
264 }
265 else {
266 ActionForward forward = mapping.findForward("basic");
267 lpf.setLeaveCalendarDocumentId(documentId);
268 lpf.setLeavePayout(leavePayout);
269 lpf.setPayoutAmount(leavePayout.getPayoutAmount());
270 return forward;
271 }
272 }
273 else {
274
275 LOG.error("could not initialize a balance payout");
276 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, "couldnot.initialize.payout");
277 return mapping.findForward("basic");
278 }
279 }
280 }
281 else {
282 LOG.error("No rule for this accrual category could be found");
283
284 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, "no.acccatrule.found");
285 return mapping.findForward("basic");
286 }
287 }
288 else {
289 LOG.error("No accrual category rule id has been sent in the request.");
290 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, "no.acccat.ruleid.sent");
291 return mapping.findForward("basic");
292
293 }
294 }
295
296
297
298 public ActionForward approveLeaveCalendar(ActionMapping mapping, ActionForm form,
299 HttpServletRequest request, HttpServletResponse response)
300 throws Exception {
301
302 GlobalVariables.getMessageMap().putWarning("document.newMaintainableObj.transferAmount","leavePayout.transferAmount.adjust");
303 LeavePayoutForm btf = (LeavePayoutForm) form;
304
305 List<LeaveBlock> eligiblePayouts = (List<LeaveBlock>) request.getSession().getAttribute("eligibilities");
306 if(!eligiblePayouts.isEmpty()) {
307
308 Collections.sort(eligiblePayouts, new Comparator() {
309
310 @Override
311 public int compare(Object o1, Object o2) {
312 LeaveBlock l1 = (LeaveBlock) o1;
313 LeaveBlock l2 = (LeaveBlock) o2;
314 return l1.getLeaveDate().compareTo(l2.getLeaveDate());
315 }
316
317 });
318
319
320
321 String leaveCalendarDocumentId = request.getParameter("documentId");
322 ActionForward forward = new ActionForward(mapping.findForward("basic"));
323 LeaveCalendarDocument lcd = LmServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(leaveCalendarDocumentId);
324
325 String principalId = lcd == null ? null : lcd.getPrincipalId();
326 LeaveBlock leaveBlock = eligiblePayouts.get(0);
327 LocalDate effectiveDate = leaveBlock.getLeaveLocalDate();
328 AccrualCategoryRule accrualRule = leaveBlock.getAccrualCategoryRule();
329 if(accrualRule != null) {
330 AccrualCategory accrualCategory = HrServiceLocator.getAccrualCategoryService().getAccrualCategory(accrualRule.getLmAccrualCategoryId());
331 BigDecimal accruedBalance = LmServiceLocator.getAccrualService().getAccruedBalanceForPrincipal(principalId, accrualCategory, effectiveDate);
332
333 LeavePayout leavePayout = LmServiceLocator.getLeavePayoutService().initializePayout(principalId, accrualRule.getLmAccrualCategoryRuleId(), accruedBalance, effectiveDate);
334 leavePayout.setLeaveCalendarDocumentId(leaveCalendarDocumentId);
335
336 if(ObjectUtils.isNotNull(leavePayout)) {
337
338 if(StringUtils.equals(accrualRule.getActionAtMaxBalance(),HrConstants.ACTION_AT_MAX_BALANCE.LOSE)) {
339
340
341
342 leavePayout = LmServiceLocator.getLeavePayoutService().payout(leavePayout);
343
344 LeaveBlock forfeitedLeaveBlock = LmServiceLocator.getLeaveBlockService().getLeaveBlock(leavePayout.getForfeitedLeaveBlockId());
345 KRADServiceLocator.getBusinessObjectService().save(leavePayout);
346 forfeitedLeaveBlock.setRequestStatus(HrConstants.REQUEST_STATUS.APPROVED);
347 LmServiceLocator.getLeaveBlockService().updateLeaveBlock(forfeitedLeaveBlock, principalId);
348
349 if(ObjectUtils.isNotNull(leaveCalendarDocumentId)) {
350 if(StringUtils.equals(accrualRule.getMaxBalanceActionFrequency(),HrConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE) ||
351 StringUtils.equals(accrualRule.getMaxBalanceActionFrequency(), HrConstants.MAX_BAL_ACTION_FREQ.YEAR_END)) {
352 ActionForward loseForward = new ActionForward(mapping.findForward("leaveCalendarPayoutSuccess"));
353 loseForward.setPath(loseForward.getPath()+"?documentId="+leaveCalendarDocumentId+"&action=R&methodToCall=approveLeaveCalendar");
354 return loseForward;
355 }
356
357 }
358
359 } else {
360 btf.setLeaveCalendarDocumentId(leaveCalendarDocumentId);
361 btf.setLeavePayout(leavePayout);
362 btf.setPayoutAmount(leavePayout.getPayoutAmount());
363 return forward;
364 }
365
366 } else {
367 LOG.error("could not initialize balance transfer.");
368 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, "couldnot.initialize.baltransfer");
369 return mapping.findForward("basic");
370
371
372 }
373
374 }
375 else {
376 LOG.error("unable to fetch the accrual category that triggerred this transfer");
377 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, "unable.fetch.acccat");
378 return mapping.findForward("basic");
379
380 }
381 }
382 else {
383 LOG.error("No infractions given");
384 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, "no.infractions.given");
385 return mapping.findForward("basic");
386
387 }
388 return mapping.findForward("basic");
389 }
390
391 public ActionForward approveTimesheet(ActionMapping mapping, ActionForm form,
392 HttpServletRequest request, HttpServletResponse response)
393 throws Exception {
394
395 GlobalVariables.getMessageMap().putWarning("document.newMaintainableObj.transferAmount","leavePayout.transferAmount.adjust");
396 LeavePayoutForm btf = (LeavePayoutForm) form;
397
398 List<LeaveBlock> eligiblePayouts = (List<LeaveBlock>) request.getSession().getAttribute("eligibilities");
399 if(!eligiblePayouts.isEmpty()) {
400
401 Collections.sort(eligiblePayouts, new Comparator() {
402
403 @Override
404 public int compare(Object o1, Object o2) {
405 LeaveBlock l1 = (LeaveBlock) o1;
406 LeaveBlock l2 = (LeaveBlock) o2;
407 return l1.getLeaveDate().compareTo(l2.getLeaveDate());
408 }
409
410 });
411
412
413
414 String timesheetDocumentId = request.getParameter("documentId");
415 ActionForward forward = new ActionForward(mapping.findForward("basic"));
416 TimesheetDocument tsd = TkServiceLocator.getTimesheetService().getTimesheetDocument(timesheetDocumentId);
417 String principalId = tsd == null ? null : tsd.getPrincipalId();
418
419 LeaveBlock leaveBlock = eligiblePayouts.get(0);
420 LocalDate effectiveDate = leaveBlock.getLeaveLocalDate();
421 String accrualCategoryRuleId = leaveBlock.getAccrualCategoryRuleId();
422 AccrualCategoryRule accrualRule = leaveBlock.getAccrualCategoryRule();
423 if(accrualRule != null) {
424 AccrualCategory accrualCategory = HrServiceLocator.getAccrualCategoryService().getAccrualCategory(accrualRule.getLmAccrualCategoryId());
425 BigDecimal accruedBalance = LmServiceLocator.getAccrualService().getAccruedBalanceForPrincipal(principalId, accrualCategory, effectiveDate);
426
427 LeavePayout leavePayout = LmServiceLocator.getLeavePayoutService().initializePayout(principalId, accrualCategoryRuleId, accruedBalance, effectiveDate);
428 leavePayout.setLeaveCalendarDocumentId(timesheetDocumentId);
429
430 if(ObjectUtils.isNotNull(leavePayout)) {
431
432 if(StringUtils.equals(accrualRule.getActionAtMaxBalance(),HrConstants.ACTION_AT_MAX_BALANCE.LOSE)) {
433
434
435 leavePayout = LmServiceLocator.getLeavePayoutService().payout(leavePayout);
436 KRADServiceLocator.getBusinessObjectService().save(leavePayout);
437
438
439 LeaveBlock forfeitedLeaveBlock = LmServiceLocator.getLeaveBlockService().getLeaveBlock(leavePayout.getForfeitedLeaveBlockId());
440 forfeitedLeaveBlock.setRequestStatus(HrConstants.REQUEST_STATUS.APPROVED);
441 LmServiceLocator.getLeaveBlockService().updateLeaveBlock(forfeitedLeaveBlock, principalId);
442
443 if(ObjectUtils.isNotNull(timesheetDocumentId)) {
444 if(StringUtils.equals(accrualRule.getMaxBalanceActionFrequency(),HrConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE) ||
445 StringUtils.equals(accrualRule.getMaxBalanceActionFrequency(), HrConstants.MAX_BAL_ACTION_FREQ.YEAR_END)) {
446 ActionForward loseForward = new ActionForward(mapping.findForward("timesheetPayoutSuccess"));
447 loseForward.setPath(loseForward.getPath()+"?documentId="+timesheetDocumentId+"&action=R&methodToCall=approveTimesheet");
448 return loseForward;
449 }
450
451 }
452
453 } else {
454 btf.setLeaveCalendarDocumentId(timesheetDocumentId);
455 btf.setLeavePayout(leavePayout);
456 btf.setPayoutAmount(leavePayout.getPayoutAmount());
457 return forward;
458 }
459
460 }
461
462 LOG.error("could not initialize balance transfer");
463 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, "couldnot.initialize.baltransfer");
464 return mapping.findForward("basic");
465
466 }
467 else {
468 LOG.error("unable to fetch the accrual category that triggerred this transfer");
469 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, "unable.fetch.acccat");
470 return mapping.findForward("basic");
471
472
473 }
474 }
475 else {
476 LOG.error("no eligible transfers exist");
477 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, "error.eligible.transfer.notExist");
478 return mapping.findForward("basic");
479
480
481 }
482 }
483
484 public ActionForward closeLeavePayoutDoc(ActionMapping mapping, ActionForm form,
485 HttpServletRequest request, HttpServletResponse response)
486 throws Exception {
487 return mapping.findForward("closeLeavePayoutDoc");
488 }
489 }