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