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 /**
017 * Copyright 2004-2013 The Kuali Foundation
018 *
019 * Licensed under the Educational Community License, Version 2.0 (the "License");
020 * you may not use this file except in compliance with the License.
021 * You may obtain a copy of the License at
022 *
023 * http://www.opensource.org/licenses/ecl2.php
024 *
025 * Unless required by applicable law or agreed to in writing, software
026 * distributed under the License is distributed on an "AS IS" BASIS,
027 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
028 * See the License for the specific language governing permissions and
029 * limitations under the License.
030 */
031 package org.kuali.kpme.tklm.leave.payout.web;
032
033 import java.math.BigDecimal;
034 import java.util.Collections;
035 import java.util.Comparator;
036 import java.util.List;
037
038 import javax.servlet.http.HttpServletRequest;
039 import javax.servlet.http.HttpServletResponse;
040
041 import org.apache.commons.lang.StringUtils;
042 import org.apache.log4j.Logger;
043 import org.apache.struts.action.ActionForm;
044 import org.apache.struts.action.ActionForward;
045 import org.apache.struts.action.ActionMapping;
046 import org.apache.struts.action.ActionRedirect;
047 import org.joda.time.LocalDate;
048 import org.kuali.kpme.core.accrualcategory.AccrualCategory;
049 import org.kuali.kpme.core.accrualcategory.rule.AccrualCategoryRule;
050 import org.kuali.kpme.core.calendar.entry.CalendarEntry;
051 import org.kuali.kpme.core.service.HrServiceLocator;
052 import org.kuali.kpme.core.util.HrConstants;
053 import org.kuali.kpme.core.web.KPMEAction;
054 import org.kuali.kpme.tklm.leave.block.LeaveBlock;
055 import org.kuali.kpme.tklm.leave.calendar.LeaveCalendarDocument;
056 import org.kuali.kpme.tklm.leave.payout.LeavePayout;
057 import org.kuali.kpme.tklm.leave.payout.validation.LeavePayoutValidationUtils;
058 import org.kuali.kpme.tklm.leave.service.LmServiceLocator;
059 import org.kuali.kpme.tklm.leave.workflow.LeaveCalendarDocumentHeader;
060 import org.kuali.kpme.tklm.time.service.TkServiceLocator;
061 import org.kuali.kpme.tklm.time.timesheet.TimesheetDocument;
062 import org.kuali.kpme.tklm.time.workflow.TimesheetDocumentHeader;
063 import org.kuali.rice.krad.service.KRADServiceLocator;
064 import org.kuali.rice.krad.util.GlobalVariables;
065 import org.kuali.rice.krad.util.KRADConstants;
066 import org.kuali.rice.krad.util.ObjectUtils;
067
068 public class LeavePayoutAction extends KPMEAction {
069
070 private static final Logger LOG = Logger.getLogger(LeavePayoutAction.class);
071
072 public ActionForward leavePayoutOnLeaveApproval(ActionMapping mapping, ActionForm form,
073 HttpServletRequest request, HttpServletResponse response) throws Exception {
074
075 //if action was submit, execute the payout
076 LeavePayoutForm lpf = (LeavePayoutForm) form;
077 LeavePayout leavePayout = lpf.getLeavePayout();
078
079 boolean valid = LeavePayoutValidationUtils.validatePayout(leavePayout);
080
081 //if payout amount has changed, and the resulting change produces forfeiture
082 //or changes the forfeiture amount, prompt for confirmation with the amount of
083 //forfeiture that the entered amount would produce.
084
085 if(valid) {
086
087 String accrualRuleId = leavePayout.getAccrualCategoryRule();
088
089 String documentId = leavePayout.getLeaveCalendarDocumentId();
090 TimesheetDocumentHeader tsdh = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeader(documentId);
091 LeaveCalendarDocumentHeader lcdh = LmServiceLocator.getLeaveCalendarDocumentHeaderService().getDocumentHeader(documentId);
092 CalendarEntry calendarEntry = null;
093 String strutsActionForward = "";
094 String methodToCall = "approveLeaveCalendar";
095 if(ObjectUtils.isNull(tsdh) && ObjectUtils.isNull(lcdh)) {
096 LOG.error("No document found");
097 // throw new RuntimeException("No document found");
098 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, "error.document.notfound");
099 mapping.findForward("basic");
100 }
101 else if(ObjectUtils.isNotNull(tsdh)) {
102 //Throws runtime exception, separate action forwards for timesheet/leave calendar payouts.
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 // throw new RuntimeException("Could not retreive calendar entry for document " + documentId);
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 //employee changed the payout amount, recalculate forfeiture.
129 //Note: payout form has been validated.
130 leavePayout = defaultBT.adjust(leavePayout.getPayoutAmount());
131 // showing the adjusted balance payout via the execution of another forward
132 // would cause a loop that would break only if the original payout amount was re-established in the form.
133 // javascript must be written if the forfeited amount is to be updated on the form object.
134 // an alternative to javascript would be to render a "re-calculate" button attached to a dedicated action forward method.
135 // must re-set leaveCalendarDocumentId, as leavePayout is now just an adjustment of the default initialized BT with no leave calendar doc id.
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 //show user errors.
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 //Throws runtime exception, separate action forwards for timesheet/leave calendar transfers.
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 // throw new RuntimeException("Action should only be reachable through triggers with frequency ON_DEMAND or LEAVE_APPROVE");
199 return mapping.findForward("basic");
200 }
201 }
202
203 //Entry point for LeavePayout.do for accrual category rule triggered payouts with action frequency On Demand.
204 //May be better suited in the LeaveCalendarAction class.
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 //the leave calendar document that triggered this balance payout.
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 //should somewhat safegaurd against url fabrication.
225 if(!StringUtils.equals(aRule.getMaxBalanceActionFrequency(),HrConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND)) {
226 // throw new RuntimeException("attempted to execute on-demand balance payout for accrual category with action frequency " + aRule.getMaxBalanceActionFrequency());
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 // this particular combination of action / action frequency does not particularly make sense
254 // unless for some reason users still need to be prompted to submit the loss.
255 // For now, we treat as though it is a valid use-case.
256 //LmServiceLocator.getLeavePayoutService().submitToWorkflow(leavePayout);
257 // May need to update to save the business object to KPME's tables for record keeping.
258 leavePayout = LmServiceLocator.getLeavePayoutService().payout(leavePayout);
259 // May need to update to save the business object to KPME's tables for record keeping.
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 // throw new RuntimeException("could not initialize a balance payout");
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 // throw new RuntimeException("No rule for this accrual category could be found");
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 // throw new RuntimeException("No accrual category rule id has been sent in the request.");
293 }
294 }
295
296 //Entry point for LeavePayout.do for accrual category rule triggered transfers with action frequency Leave Approve.
297 //TODO: Rename method to differentiate from ActionForward with same name in LeaveCalendarSubmit.
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 //This is the leave calendar document that triggered this balance transfer.
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 String accrualCategoryRuleId = leaveBlock.getAccrualCategoryRuleId();
329 if(!StringUtils.isBlank(accrualCategoryRuleId)) {
330 AccrualCategoryRule accrualRule = HrServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(accrualCategoryRuleId);
331 AccrualCategory accrualCategory = HrServiceLocator.getAccrualCategoryService().getAccrualCategory(accrualRule.getLmAccrualCategoryId());
332 BigDecimal accruedBalance = LmServiceLocator.getAccrualService().getAccruedBalanceForPrincipal(principalId, accrualCategory, effectiveDate);
333
334 LeavePayout leavePayout = LmServiceLocator.getLeavePayoutService().initializePayout(principalId, accrualCategoryRuleId, accruedBalance, effectiveDate);
335 leavePayout.setLeaveCalendarDocumentId(leaveCalendarDocumentId);
336
337 if(ObjectUtils.isNotNull(leavePayout)) {
338
339 if(StringUtils.equals(accrualRule.getActionAtMaxBalance(),HrConstants.ACTION_AT_MAX_BALANCE.LOSE)) {
340 //payouts should never contain losses.
341 //losses are treated as a special case of transfer
342 //LmServiceLocator.getLeavePayoutService().submitToWorkflow(leavePayout);
343 leavePayout = LmServiceLocator.getLeavePayoutService().payout(leavePayout);
344 // May need to update to save the business object to KPME's tables for record keeping.
345 LeaveBlock forfeitedLeaveBlock = LmServiceLocator.getLeaveBlockService().getLeaveBlock(leavePayout.getForfeitedLeaveBlockId());
346 KRADServiceLocator.getBusinessObjectService().save(leavePayout);
347 forfeitedLeaveBlock.setRequestStatus(HrConstants.REQUEST_STATUS.APPROVED);
348 LmServiceLocator.getLeaveBlockService().updateLeaveBlock(forfeitedLeaveBlock, principalId);
349
350 if(ObjectUtils.isNotNull(leaveCalendarDocumentId)) {
351 if(StringUtils.equals(accrualRule.getMaxBalanceActionFrequency(),HrConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE) ||
352 StringUtils.equals(accrualRule.getMaxBalanceActionFrequency(), HrConstants.MAX_BAL_ACTION_FREQ.YEAR_END)) {
353 ActionForward loseForward = new ActionForward(mapping.findForward("leaveCalendarPayoutSuccess"));
354 loseForward.setPath(loseForward.getPath()+"?documentId="+leaveCalendarDocumentId+"&action=R&methodToCall=approveLeaveCalendar");
355 return loseForward;
356 }
357 //on demand handled in separate action forward.
358 }
359
360 } else {
361 btf.setLeaveCalendarDocumentId(leaveCalendarDocumentId);
362 btf.setLeavePayout(leavePayout);
363 btf.setPayoutAmount(leavePayout.getPayoutAmount());
364 return forward;
365 }
366
367 } else {
368 LOG.error("could not initialize balance transfer.");
369 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, "couldnot.initialize.baltransfer");
370 return mapping.findForward("basic");
371
372 // throw new RuntimeException("could not initialize balance transfer");
373 }
374
375 }
376 else {
377 LOG.error("unable to fetch the accrual category that triggerred this transfer");
378 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, "unable.fetch.acccat");
379 return mapping.findForward("basic");
380 // throw new RuntimeException("unable to fetch the accrual category that triggerred this transfer");
381 }
382 }
383 else {
384 LOG.error("No infractions given");
385 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, "no.infractions.given");
386 return mapping.findForward("basic");
387 // throw new RuntimeException("No infractions given");
388 }
389 return mapping.findForward("basic");
390 }
391
392 public ActionForward approveTimesheet(ActionMapping mapping, ActionForm form,
393 HttpServletRequest request, HttpServletResponse response)
394 throws Exception {
395
396 GlobalVariables.getMessageMap().putWarning("document.newMaintainableObj.transferAmount","leavePayout.transferAmount.adjust");
397 LeavePayoutForm btf = (LeavePayoutForm) form;
398
399 List<LeaveBlock> eligiblePayouts = (List<LeaveBlock>) request.getSession().getAttribute("eligibilities");
400 if(!eligiblePayouts.isEmpty()) {
401
402 Collections.sort(eligiblePayouts, new Comparator() {
403
404 @Override
405 public int compare(Object o1, Object o2) {
406 LeaveBlock l1 = (LeaveBlock) o1;
407 LeaveBlock l2 = (LeaveBlock) o2;
408 return l1.getLeaveDate().compareTo(l2.getLeaveDate());
409 }
410
411 });
412
413 //This is the leave calendar document that triggered this balance transfer.
414
415 String timesheetDocumentId = request.getParameter("documentId");
416 ActionForward forward = new ActionForward(mapping.findForward("basic"));
417 TimesheetDocument tsd = TkServiceLocator.getTimesheetService().getTimesheetDocument(timesheetDocumentId);
418 String principalId = tsd == null ? null : tsd.getPrincipalId();
419
420 LeaveBlock leaveBlock = eligiblePayouts.get(0);
421 LocalDate effectiveDate = leaveBlock.getLeaveLocalDate();
422 String accrualCategoryRuleId = leaveBlock.getAccrualCategoryRuleId();
423 if(!StringUtils.isBlank(accrualCategoryRuleId)) {
424 AccrualCategoryRule accrualRule = HrServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(accrualCategoryRuleId);
425 AccrualCategory accrualCategory = HrServiceLocator.getAccrualCategoryService().getAccrualCategory(accrualRule.getLmAccrualCategoryId());
426 BigDecimal accruedBalance = LmServiceLocator.getAccrualService().getAccruedBalanceForPrincipal(principalId, accrualCategory, effectiveDate);
427
428 LeavePayout leavePayout = LmServiceLocator.getLeavePayoutService().initializePayout(principalId, accrualCategoryRuleId, accruedBalance, effectiveDate);
429 leavePayout.setLeaveCalendarDocumentId(timesheetDocumentId);
430
431 if(ObjectUtils.isNotNull(leavePayout)) {
432
433 if(StringUtils.equals(accrualRule.getActionAtMaxBalance(),HrConstants.ACTION_AT_MAX_BALANCE.LOSE)) {
434 // TODO: Redirect user to prompt stating excess leave will be forfeited and ask for confirmation.
435 // Do not submit the object to workflow for this max balance action.
436 leavePayout = LmServiceLocator.getLeavePayoutService().payout(leavePayout);
437 KRADServiceLocator.getBusinessObjectService().save(leavePayout);
438
439 // May need to update to save the business object to KPME's tables for record keeping.
440 LeaveBlock forfeitedLeaveBlock = LmServiceLocator.getLeaveBlockService().getLeaveBlock(leavePayout.getForfeitedLeaveBlockId());
441 forfeitedLeaveBlock.setRequestStatus(HrConstants.REQUEST_STATUS.APPROVED);
442 LmServiceLocator.getLeaveBlockService().updateLeaveBlock(forfeitedLeaveBlock, principalId);
443
444 if(ObjectUtils.isNotNull(timesheetDocumentId)) {
445 if(StringUtils.equals(accrualRule.getMaxBalanceActionFrequency(),HrConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE) ||
446 StringUtils.equals(accrualRule.getMaxBalanceActionFrequency(), HrConstants.MAX_BAL_ACTION_FREQ.YEAR_END)) {
447 ActionForward loseForward = new ActionForward(mapping.findForward("timesheetPayoutSuccess"));
448 loseForward.setPath(loseForward.getPath()+"?documentId="+timesheetDocumentId+"&action=R&methodToCall=approveTimesheet");
449 return loseForward;
450 }
451 //on demand handled in separate action forward.
452 }
453
454 } else {
455 btf.setLeaveCalendarDocumentId(timesheetDocumentId);
456 btf.setLeavePayout(leavePayout);
457 btf.setPayoutAmount(leavePayout.getPayoutAmount());
458 return forward;
459 }
460
461 }
462 // throw new RuntimeException("could not initialize balance transfer");
463 LOG.error("could not initialize balance transfer");
464 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, "couldnot.initialize.baltransfer");
465 return mapping.findForward("basic");
466
467 }
468 else {
469 LOG.error("unable to fetch the accrual category that triggerred this transfer");
470 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, "unable.fetch.acccat");
471 return mapping.findForward("basic");
472
473 // throw new RuntimeException("unable to fetch the accrual category that triggerred this transfer");
474 }
475 }
476 else {
477 LOG.error("no eligible transfers exist");
478 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, "error.eligible.transfer.notExist");
479 return mapping.findForward("basic");
480
481 // throw new RuntimeException("no eligible transfers exist");
482 }
483 }
484
485 public ActionForward closeLeavePayoutDoc(ActionMapping mapping, ActionForm form,
486 HttpServletRequest request, HttpServletResponse response)
487 throws Exception {
488 return mapping.findForward("closeLeavePayoutDoc");
489 }
490 }