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    package org.kuali.hr.lm.leavepayout.web;
017    
018    import java.sql.Date;
019    import java.util.ArrayList;
020    import java.util.List;
021    import java.util.Map;
022    
023    import org.apache.commons.lang.time.DateUtils;
024    import org.apache.commons.lang3.StringUtils;
025    import org.apache.struts.action.ActionForm;
026    import org.apache.struts.action.ActionForward;
027    import org.apache.struts.action.ActionMapping;
028    import org.apache.struts.action.ActionRedirect;
029    import org.kuali.hr.lm.LMConstants;
030    import org.kuali.hr.lm.accrual.AccrualCategoryRule;
031    import org.kuali.hr.lm.leavepayout.LeavePayout;
032    import org.kuali.hr.lm.leavepayout.validation.LeavePayoutValidationUtils;
033    import org.kuali.hr.lm.leavepayout.web.LeavePayoutForm;
034    import org.kuali.hr.lm.leaveSummary.LeaveSummary;
035    import org.kuali.hr.lm.leaveSummary.LeaveSummaryRow;
036    import org.kuali.hr.lm.leaveblock.LeaveBlock;
037    import org.kuali.hr.lm.leavecalendar.LeaveCalendarDocument;
038    import org.kuali.hr.lm.workflow.LeaveCalendarDocumentHeader;
039    import org.kuali.hr.time.base.web.TkAction;
040    import org.kuali.hr.time.calendar.CalendarEntries;
041    import org.kuali.hr.time.service.base.TkServiceLocator;
042    import org.kuali.hr.time.timesheet.TimesheetDocument;
043    import org.kuali.hr.time.util.TKUtils;
044    import org.kuali.hr.time.workflow.TimesheetDocumentHeader;
045    import org.kuali.rice.krad.util.GlobalVariables;
046    import org.kuali.rice.krad.util.ObjectUtils;
047    
048    import javax.servlet.http.HttpServletRequest;
049    import javax.servlet.http.HttpServletResponse;
050    
051    public class LeavePayoutAction extends TkAction {
052    
053            public ActionForward leavePayoutOnLeaveApproval(ActionMapping mapping, ActionForm form,
054                            HttpServletRequest request, HttpServletResponse response) throws Exception {
055    
056                    //if action was submit, execute the payout
057                    LeavePayoutForm lpf = (LeavePayoutForm) form;
058                    LeavePayout leavePayout = lpf.getLeavePayout();
059            
060                    boolean valid = LeavePayoutValidationUtils.validateTransfer(leavePayout);
061                    
062                    //if payout amount has changed, and the resulting change produces forfeiture
063                    //or changes the forfeiture amount, prompt for confirmation with the amount of
064                    //forfeiture that the entered amount would produce.
065    
066                    if(valid) {
067                            
068                            String accrualRuleId = leavePayout.getAccrualCategoryRule();
069                            
070                            String documentId = leavePayout.getLeaveCalendarDocumentId();
071                            TimesheetDocumentHeader tsdh = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeader(documentId);
072                            LeaveCalendarDocumentHeader lcdh = TkServiceLocator.getLeaveCalendarDocumentHeaderService().getDocumentHeader(documentId);
073                            CalendarEntries calendarEntry = null;
074                            String strutsActionForward = "";
075                            String methodToCall = "approveLeaveCalendar";
076                            if(ObjectUtils.isNull(tsdh) && ObjectUtils.isNull(lcdh)) {
077                                    throw new RuntimeException("No document found");
078                            }
079                            else if(ObjectUtils.isNotNull(tsdh)) {
080                                    //Throws runtime exception, separate action forwards for timesheet/leave calendar payouts.
081                                    TimesheetDocument tsd = TkServiceLocator.getTimesheetService().getTimesheetDocument(documentId);
082                                    calendarEntry = tsd.getCalendarEntry();
083                                    strutsActionForward = "timesheetTransferSuccess";
084                                    methodToCall = "approveTimesheet";
085                            }
086                            else {
087                                    LeaveCalendarDocument lcd = TkServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(documentId);
088                                    calendarEntry = lcd.getCalendarEntry();
089                                    strutsActionForward = "leaveCalendarTransferSuccess";
090                                    methodToCall = "approveLeaveCalendar";
091                            }
092                            
093                            if(ObjectUtils.isNull(calendarEntry)) {
094                                    throw new RuntimeException("Could not retreive calendar entry for document " + documentId);
095                            }
096                            
097                            AccrualCategoryRule accrualRule = TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(accrualRuleId);
098                            Date effectiveDate = TKUtils.getCurrentDate();
099                            if(TKUtils.getCurrentDate().after(calendarEntry.getEndPeriodDate()))
100                                    effectiveDate = new Date(DateUtils.addMinutes(calendarEntry.getEndPeriodDate(),-1).getTime());
101                            // if submitting a delinquent calendar, use the calendar's end period date for the effective date.
102                            // could adjust the end period date by subtracting a day so that the leave blocks appear on the month in question.
103                            
104                            LeaveSummary ls = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(leavePayout.getPrincipalId(), calendarEntry);
105                            LeaveSummaryRow payoutRow = ls.getLeaveSummaryRowForAccrualCategory(accrualRule.getLmAccrualCategoryId());
106                            LeavePayout defaultBT = TkServiceLocator.getLeavePayoutService().initializePayout(leavePayout.getPrincipalId(), accrualRuleId, payoutRow.getAccruedBalance(), effectiveDate);
107                            if(leavePayout.getPayoutAmount().compareTo(defaultBT.getPayoutAmount()) != 0) {
108                                    //employee changed the payout amount, recalculate forfeiture.
109                                    //Note: payout form has been validated.
110                                    leavePayout = defaultBT.adjust(leavePayout.getPayoutAmount());
111                                    // showing the adjusted balance payout via the execution of another forward
112                                    // would cause a loop that would break only if the original payout amount was re-established in the form.
113                                    // javascript must be written if the forfeited amount is to be updated on the form object.
114                                    // an alternative to javascript would be to render a "re-calculate" button attached to a dedicated action forward method.
115                                    // must re-set leaveCalendarDocumentId, as leavePayout is now just an adjustment of the default initialized BT with no leave calendar doc id.
116                                    leavePayout.setLeaveCalendarDocumentId(documentId);
117                            }
118    
119                            TkServiceLocator.getLeavePayoutService().submitToWorkflow(leavePayout);
120                            
121                            if(ObjectUtils.isNotNull(documentId)) {
122                                    if(StringUtils.equals(accrualRule.getMaxBalanceActionFrequency(),LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE) ||
123                                                    StringUtils.equals(accrualRule.getMaxBalanceActionFrequency(), LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END)) {
124                                            
125                                            ActionForward forward = new ActionForward(mapping.findForward(strutsActionForward));
126                                            forward.setPath(forward.getPath()+"?documentId="+documentId+"&action=R&methodToCall="+methodToCall);
127                                            return forward;
128                                    }
129                                    else
130                                            return mapping.findForward("closeLeavePayoutDoc");
131                            }
132                            else
133                                    return mapping.findForward("closeLeavePayoutDoc");
134                    }
135                    else //show user errors.
136                            return mapping.findForward("basic");
137            }
138            
139            public ActionForward cancel(ActionMapping mapping, ActionForm form,
140                            HttpServletRequest request, HttpServletResponse response)
141                            throws Exception {
142                    
143                    LeavePayoutForm lpf = (LeavePayoutForm) form;
144                    LeavePayout leavePayout = lpf.getLeavePayout();
145                    String accrualCategoryRuleId = leavePayout.getAccrualCategoryRule();
146                    AccrualCategoryRule accrualRule = TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(accrualCategoryRuleId);
147                    String actionFrequency = accrualRule.getMaxBalanceActionFrequency();
148                    
149                    if(StringUtils.equals(actionFrequency,LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND))
150                            return mapping.findForward("closeLeavePayoutDoc");
151                    else 
152                            if(StringUtils.equals(actionFrequency, LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE) ||
153                                            StringUtils.equals(actionFrequency, LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END)) {
154                                    
155                                    String documentId = leavePayout.getLeaveCalendarDocumentId();
156                                    TimesheetDocumentHeader tsdh = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeader(documentId);
157                                    LeaveCalendarDocumentHeader lcdh = TkServiceLocator.getLeaveCalendarDocumentHeaderService().getDocumentHeader(documentId);
158                                    String strutsActionForward = "";
159                                    if(ObjectUtils.isNull(tsdh) && ObjectUtils.isNull(lcdh)) {
160                                            strutsActionForward = "/";
161                                    }
162                                    else if(ObjectUtils.isNotNull(tsdh)) {
163                                            //Throws runtime exception, separate action forwards for timesheet/leave calendar transfers.
164                                            strutsActionForward = mapping.findForward("timesheetCancel").getPath() + "?documentId=" + leavePayout.getLeaveCalendarDocumentId();
165                                    }
166                                    else {
167                                            strutsActionForward = mapping.findForward("leaveCalendarCancel").getPath() + "?documentId=" + leavePayout.getLeaveCalendarDocumentId();
168                                    }
169    
170                                    ActionRedirect redirect = new ActionRedirect();
171                                    redirect.setPath(strutsActionForward);
172                                    return redirect;
173    
174                            }
175                            else
176                                    throw new RuntimeException("Action should only be reachable through triggers with frequency ON_DEMAND or LEAVE_APPROVE");
177            }
178            
179            //Entry point for LeavePayout.do for accrual category rule triggered payouts with action frequency On Demand.
180            //May be better suited in the LeaveCalendarAction class.
181            public ActionForward leavePayoutOnDemand(ActionMapping mapping, ActionForm form,
182                            HttpServletRequest request, HttpServletResponse response)
183                            throws Exception {
184                    GlobalVariables.getMessageMap().putWarning("document.payoutAmount","leavePayout.payoutAmount.adjust");
185    
186                    LeavePayoutForm lpf = (LeavePayoutForm) form;
187                    //the leave calendar document that triggered this balance payout.
188                    String documentId = request.getParameter("documentId");
189                    String accrualRuleId = request.getParameter("accrualRuleId");
190                    String timesheet = request.getParameter("timesheet");
191    
192                    boolean isTimesheet = false;
193                    if(StringUtils.equals(timesheet, "true")) {
194                            lpf.isTimesheet(true);
195                            isTimesheet = true;
196                    }
197                    if(ObjectUtils.isNotNull(accrualRuleId)) {
198                            AccrualCategoryRule aRule = TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(accrualRuleId);
199                            if(ObjectUtils.isNotNull(aRule)) {
200                                    //should somewhat safegaurd against url fabrication.
201                                    if(!StringUtils.equals(aRule.getMaxBalanceActionFrequency(),LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND))
202                                            throw new RuntimeException("attempted to execute on-demand balance payout for accrual category with action frequency " + aRule.getMaxBalanceActionFrequency());
203                                    else {
204                                            TimesheetDocument tsd = null;
205                                            LeaveCalendarDocument lcd = null;
206                                            String principalId = null;
207                                            CalendarEntries calendarEntry = null;
208                                            
209                                            if(isTimesheet) {
210                                                    tsd = TkServiceLocator.getTimesheetService().getTimesheetDocument(documentId);
211                                                    principalId = tsd.getPrincipalId();
212                                                    calendarEntry = tsd.getCalendarEntry();
213                                            }
214                                            else {
215                                                    lcd = TkServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(documentId);
216                                                    principalId = lcd.getPrincipalId();
217                                                    calendarEntry = lcd.getCalendarEntry();
218                                            }
219                                            LeaveSummary ls = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(principalId, calendarEntry);
220                                            
221                                            Date effectiveDate = TKUtils.getCurrentDate();
222                                            if(TKUtils.getCurrentDate().after(calendarEntry.getEndPeriodDate()))
223                                                    effectiveDate = new Date(DateUtils.addMinutes(calendarEntry.getEndPeriodDate(),-1).getTime());
224    
225                                            LeaveSummaryRow payoutRow = ls.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
226                                            LeavePayout leavePayout = TkServiceLocator.getLeavePayoutService().initializePayout(principalId, accrualRuleId, payoutRow.getAccruedBalance(), effectiveDate);
227                                            leavePayout.setLeaveCalendarDocumentId(documentId);
228                                            if(ObjectUtils.isNotNull(leavePayout)) {
229                                                    if(StringUtils.equals(aRule.getActionAtMaxBalance(),LMConstants.ACTION_AT_MAX_BAL.LOSE)) {      
230                                                            // this particular combination of action / action frequency does not particularly make sense
231                                                            // unless for some reason users still need to be prompted to submit the loss.
232                                                            // For now, we treat as though it is a valid use-case.
233                                                            //TkServiceLocator.getLeavePayoutService().submitToWorkflow(leavePayout);
234                                                            // May need to update to save the business object to KPME's tables for record keeping.
235                                                            leavePayout = TkServiceLocator.getLeavePayoutService().payout(leavePayout);
236                                                            // May need to update to save the business object to KPME's tables for record keeping.
237                                                            LeaveBlock forfeitedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(leavePayout.getForfeitedLeaveBlockId());
238                                                            forfeitedLeaveBlock.setRequestStatus(LMConstants.REQUEST_STATUS.APPROVED);
239                                                            TkServiceLocator.getLeaveBlockService().updateLeaveBlock(forfeitedLeaveBlock, principalId);
240                                                            return mapping.findForward("closeLeavePayoutDoc");
241                                                    }
242                                                    else {
243                                                            ActionForward forward = mapping.findForward("basic");
244                                                            lpf.setLeaveCalendarDocumentId(documentId);
245                                                            lpf.setLeavePayout(leavePayout);
246                                                            lpf.setPayoutAmount(leavePayout.getPayoutAmount());
247                                                            return forward;
248                                                    }
249                                            }
250                                            else
251                                                    throw new RuntimeException("could not initialize a balance payout");
252    
253                                    }
254                            }
255                            else
256                                    throw new RuntimeException("No rule for this accrual category could be found");
257                    }
258                    else
259                            throw new RuntimeException("No accrual category rule id has been sent in the request.");
260            }
261    
262            //Entry point for LeavePayout.do for accrual category rule triggered payouts with action frequency Leave Approve.
263            //TODO: Rename method to differentiate from ActionForward with same name in LeaveCalendarSubmit.
264            public ActionForward approveLeaveCalendar(ActionMapping mapping, ActionForm form,
265                            HttpServletRequest request, HttpServletResponse response)
266                                            throws Exception {
267                    
268                    GlobalVariables.getMessageMap().putWarning("document.newMaintainableObj.payoutAmount","leavePayout.payoutAmount.adjust");
269                    LeavePayoutForm lpf = (LeavePayoutForm) form;
270    
271                    int categoryCounter = 0;
272                    List<String> payoutableAccrualCategoryRules = new ArrayList<String>();
273                    String accrualRuleId = request.getParameter("accrualCategory0");
274                    while(ObjectUtils.isNotNull(accrualRuleId)) {
275                            //TODO: Get rid of this loop
276                            categoryCounter++;
277                            payoutableAccrualCategoryRules.add(accrualRuleId);
278                            accrualRuleId = request.getParameter("accrualCategory"+categoryCounter);
279                    }
280    
281                    //Bad.... User must be prompted for each payout that needs to be made.
282                    //For now, assuming not more than one accrual category is eligible for payout.
283                    if(!payoutableAccrualCategoryRules.isEmpty()) {
284                            //This is the leave calendar document that triggered this balance payout.
285                            String leaveCalendarDocumentId = request.getParameter("documentId");
286                            ActionForward forward = new ActionForward(mapping.findForward("basic"));
287                            LeaveCalendarDocument lcd = TkServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(leaveCalendarDocumentId);
288                            LeaveSummary leaveSummary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(lcd.getPrincipalId(), lcd.getCalendarEntry());
289                            
290                            Date effectiveDate = TKUtils.getCurrentDate();
291                            if(TKUtils.getCurrentDate().after(lcd.getCalendarEntry().getEndPeriodDate()))
292                                    effectiveDate = new Date(DateUtils.addMinutes(lcd.getCalendarEntry().getEndPeriodDate(),-1).getTime());
293                            
294                            accrualRuleId = payoutableAccrualCategoryRules.get(0);
295                            AccrualCategoryRule aRule = TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(accrualRuleId);
296                            LeaveSummaryRow payoutRow = leaveSummary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
297                            LeavePayout leavePayout = TkServiceLocator.getLeavePayoutService().initializePayout(lcd.getPrincipalId(), accrualRuleId, payoutRow.getAccruedBalance(), effectiveDate);
298                            leavePayout.setLeaveCalendarDocumentId(leaveCalendarDocumentId);
299    
300                            if(ObjectUtils.isNotNull(leavePayout)) {
301                                    AccrualCategoryRule accrualRule = TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(accrualRuleId);
302                                    if(StringUtils.equals(accrualRule.getActionAtMaxBalance(),LMConstants.ACTION_AT_MAX_BAL.LOSE)) {
303    
304                                            //TkServiceLocator.getLeavePayoutService().submitToWorkflow(leavePayout);
305                                            leavePayout = TkServiceLocator.getLeavePayoutService().payout(leavePayout);
306                                            // May need to update to save the business object to KPME's tables for record keeping.
307                                            LeaveBlock forfeitedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(leavePayout.getForfeitedLeaveBlockId());
308                                            forfeitedLeaveBlock.setRequestStatus(LMConstants.REQUEST_STATUS.APPROVED);
309                                            TkServiceLocator.getLeaveBlockService().updateLeaveBlock(forfeitedLeaveBlock, lcd.getPrincipalId());
310                                            
311                                            ActionRedirect redirect = new ActionRedirect();
312                                            if(ObjectUtils.isNotNull(leaveCalendarDocumentId)) {
313                                                    if(StringUtils.equals(accrualRule.getMaxBalanceActionFrequency(),LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE) ||
314                                                                    StringUtils.equals(accrualRule.getMaxBalanceActionFrequency(), LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END)) {
315                                                            ActionForward loseForward = new ActionForward(mapping.findForward("leaveCalendarTransferSuccess"));
316                                                            loseForward.setPath(loseForward.getPath()+"?documentId="+leaveCalendarDocumentId+"&action=R&methodToCall=approveLeaveCalendar");
317                                                            return loseForward;
318                                                    }
319                                                    //on demand handled in separate action forward.
320                                            }
321    
322                                    } else {
323                                            lpf.setLeaveCalendarDocumentId(leaveCalendarDocumentId);
324                                            lpf.setLeavePayout(leavePayout);
325                                            lpf.setPayoutAmount(leavePayout.getPayoutAmount());
326                                            return forward;
327                                    }
328    
329                            }
330                            throw new RuntimeException("could not initialize balance payout");
331    
332                    }
333                    else
334                            throw new RuntimeException("unable to fetch the accrual category that triggerred this payout");
335            }
336            
337            public ActionForward approveTimesheet(ActionMapping mapping, ActionForm form,
338                            HttpServletRequest request, HttpServletResponse response)
339                                            throws Exception {
340                    
341                    GlobalVariables.getMessageMap().putWarning("document.newMaintainableObj.payoutAmount","leavePayout.payoutAmount.adjust");
342                    LeavePayoutForm lpf = (LeavePayoutForm) form;
343    
344                    int categoryCounter = 0;
345                    List<String> payoutableAccrualCategoryRules = new ArrayList<String>();
346                    String accrualRuleId = request.getParameter("accrualCategory0");
347                    while(ObjectUtils.isNotNull(accrualRuleId)) {
348                            //TODO: Get rid of this loop
349                            categoryCounter++;
350                            payoutableAccrualCategoryRules.add(accrualRuleId);
351                            accrualRuleId = request.getParameter("accrualCategory"+categoryCounter);
352                    }
353    
354                    //Bad.... User must be prompted for each payout that needs to be made.
355                    //For now, assuming not more than one accrual category is eligible for payout.
356                    if(!payoutableAccrualCategoryRules.isEmpty()) {
357                            //This is the leave calendar document that triggered this balance payout.
358                            String timesheetDocumentId = request.getParameter("documentId");
359                            ActionForward forward = new ActionForward(mapping.findForward("basic"));
360                            TimesheetDocument tsd = TkServiceLocator.getTimesheetService().getTimesheetDocument(timesheetDocumentId);
361                            LeaveSummary leaveSummary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(tsd.getPrincipalId(), tsd.getCalendarEntry());
362                            
363                            Date effectiveDate = TKUtils.getCurrentDate();
364                            if(TKUtils.getCurrentDate().after(tsd.getCalendarEntry().getEndPeriodDate()))
365                                    effectiveDate = new Date(DateUtils.addMinutes(tsd.getCalendarEntry().getEndPeriodDate(),-1).getTime());
366                            
367                            accrualRuleId = payoutableAccrualCategoryRules.get(0);
368                            AccrualCategoryRule accrualRule = TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(accrualRuleId);
369                            LeaveSummaryRow payoutRow = leaveSummary.getLeaveSummaryRowForAccrualCategory(accrualRule.getLmAccrualCategoryId());
370                            LeavePayout leavePayout = TkServiceLocator.getLeavePayoutService().initializePayout(tsd.getPrincipalId(), accrualRuleId, payoutRow.getAccruedBalance(), effectiveDate);
371                            leavePayout.setLeaveCalendarDocumentId(timesheetDocumentId);
372    
373                            if(ObjectUtils.isNotNull(leavePayout)) {
374                                    if(StringUtils.equals(accrualRule.getActionAtMaxBalance(),LMConstants.ACTION_AT_MAX_BAL.LOSE)) {
375                                            // TODO: Redirect user to prompt stating excess leave will be forfeited and ask for confirmation.
376                                            // Do not submit the object to workflow for this max balance action.
377                                            leavePayout = TkServiceLocator.getLeavePayoutService().payout(leavePayout);
378                                            // May need to update to save the business object to KPME's tables for record keeping.
379                                            LeaveBlock forfeitedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(leavePayout.getForfeitedLeaveBlockId());
380                                            forfeitedLeaveBlock.setRequestStatus(LMConstants.REQUEST_STATUS.APPROVED);
381                                            TkServiceLocator.getLeaveBlockService().updateLeaveBlock(forfeitedLeaveBlock, tsd.getPrincipalId());
382                                            ActionRedirect redirect = new ActionRedirect();
383                                            if(ObjectUtils.isNotNull(timesheetDocumentId)) {
384                                                    if(StringUtils.equals(accrualRule.getMaxBalanceActionFrequency(),LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE) ||
385                                                                    StringUtils.equals(accrualRule.getMaxBalanceActionFrequency(), LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END)) {
386                                                            ActionForward loseForward = new ActionForward(mapping.findForward("timesheetTransferSuccess"));
387                                                            loseForward.setPath(loseForward.getPath()+"?documentId="+timesheetDocumentId+"&action=R&methodToCall=approveTimesheet");
388                                                            return loseForward;
389                                                    }
390                                                    //on demand handled in separate action forward.
391                                            }
392    
393                                    } else {
394                                            lpf.setLeaveCalendarDocumentId(timesheetDocumentId);
395                                            lpf.setLeavePayout(leavePayout);
396                                            lpf.setPayoutAmount(leavePayout.getPayoutAmount());
397                                            return forward;
398                                    }
399    
400                            }
401                            throw new RuntimeException("could not initialize balance payout");
402    
403                    }
404                    else
405                            throw new RuntimeException("unable to fetch the accrual category that triggerred this payout");
406            }
407            
408            public ActionForward closeLeavePayoutDoc(ActionMapping mapping, ActionForm form,
409                            HttpServletRequest request, HttpServletResponse response)
410                            throws Exception {
411                    return mapping.findForward("closeLeavePayoutDoc");
412            }
413    }