View Javadoc

1   /**
2    * Copyright 2004-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.hr.lm.leavepayout.web;
17  
18  import java.sql.Date;
19  import java.util.ArrayList;
20  import java.util.List;
21  import java.util.Map;
22  
23  import org.apache.commons.lang.time.DateUtils;
24  import org.apache.commons.lang3.StringUtils;
25  import org.apache.struts.action.ActionForm;
26  import org.apache.struts.action.ActionForward;
27  import org.apache.struts.action.ActionMapping;
28  import org.apache.struts.action.ActionRedirect;
29  import org.kuali.hr.lm.LMConstants;
30  import org.kuali.hr.lm.accrual.AccrualCategoryRule;
31  import org.kuali.hr.lm.leavepayout.LeavePayout;
32  import org.kuali.hr.lm.leavepayout.validation.LeavePayoutValidationUtils;
33  import org.kuali.hr.lm.leavepayout.web.LeavePayoutForm;
34  import org.kuali.hr.lm.leaveSummary.LeaveSummary;
35  import org.kuali.hr.lm.leaveSummary.LeaveSummaryRow;
36  import org.kuali.hr.lm.leaveblock.LeaveBlock;
37  import org.kuali.hr.lm.leavecalendar.LeaveCalendarDocument;
38  import org.kuali.hr.lm.workflow.LeaveCalendarDocumentHeader;
39  import org.kuali.hr.time.base.web.TkAction;
40  import org.kuali.hr.time.calendar.CalendarEntries;
41  import org.kuali.hr.time.service.base.TkServiceLocator;
42  import org.kuali.hr.time.timesheet.TimesheetDocument;
43  import org.kuali.hr.time.util.TKUtils;
44  import org.kuali.hr.time.workflow.TimesheetDocumentHeader;
45  import org.kuali.rice.krad.util.GlobalVariables;
46  import org.kuali.rice.krad.util.ObjectUtils;
47  
48  import javax.servlet.http.HttpServletRequest;
49  import javax.servlet.http.HttpServletResponse;
50  
51  public class LeavePayoutAction extends TkAction {
52  
53  	public ActionForward leavePayoutOnLeaveApproval(ActionMapping mapping, ActionForm form,
54  			HttpServletRequest request, HttpServletResponse response) throws Exception {
55  
56  		//if action was submit, execute the payout
57  		LeavePayoutForm lpf = (LeavePayoutForm) form;
58  		LeavePayout leavePayout = lpf.getLeavePayout();
59  	
60  		boolean valid = LeavePayoutValidationUtils.validateTransfer(leavePayout);
61  		
62  		//if payout amount has changed, and the resulting change produces forfeiture
63  		//or changes the forfeiture amount, prompt for confirmation with the amount of
64  		//forfeiture that the entered amount would produce.
65  
66  		if(valid) {
67  			
68  			String accrualRuleId = leavePayout.getAccrualCategoryRule();
69  			
70  			String documentId = leavePayout.getLeaveCalendarDocumentId();
71  			TimesheetDocumentHeader tsdh = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeader(documentId);
72  			LeaveCalendarDocumentHeader lcdh = TkServiceLocator.getLeaveCalendarDocumentHeaderService().getDocumentHeader(documentId);
73  			CalendarEntries calendarEntry = null;
74  			String strutsActionForward = "";
75  			String methodToCall = "approveLeaveCalendar";
76  			if(ObjectUtils.isNull(tsdh) && ObjectUtils.isNull(lcdh)) {
77  				throw new RuntimeException("No document found");
78  			}
79  			else if(ObjectUtils.isNotNull(tsdh)) {
80  				//Throws runtime exception, separate action forwards for timesheet/leave calendar payouts.
81  				TimesheetDocument tsd = TkServiceLocator.getTimesheetService().getTimesheetDocument(documentId);
82  				calendarEntry = tsd.getCalendarEntry();
83  				strutsActionForward = "timesheetTransferSuccess";
84  				methodToCall = "approveTimesheet";
85  			}
86  			else {
87  				LeaveCalendarDocument lcd = TkServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(documentId);
88  				calendarEntry = lcd.getCalendarEntry();
89  				strutsActionForward = "leaveCalendarTransferSuccess";
90  				methodToCall = "approveLeaveCalendar";
91  			}
92  			
93  			if(ObjectUtils.isNull(calendarEntry)) {
94  				throw new RuntimeException("Could not retreive calendar entry for document " + documentId);
95  			}
96  			
97  			AccrualCategoryRule accrualRule = TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(accrualRuleId);
98  			Date effectiveDate = TKUtils.getCurrentDate();
99  			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 }