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 }