View Javadoc
1   /*
2    * Copyright 2005 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.ole.fp.document.web.struts;
17  
18  import java.io.ByteArrayOutputStream;
19  import java.text.MessageFormat;
20  import java.util.List;
21  import java.util.Properties;
22  import java.util.Set;
23  
24  import javax.servlet.http.HttpServletRequest;
25  import javax.servlet.http.HttpServletResponse;
26  
27  import org.apache.commons.lang.StringUtils;
28  import org.apache.struts.action.ActionForm;
29  import org.apache.struts.action.ActionForward;
30  import org.apache.struts.action.ActionMapping;
31  import org.kuali.ole.fp.businessobject.DisbursementVoucherNonEmployeeExpense;
32  import org.kuali.ole.fp.businessobject.DisbursementVoucherNonEmployeeTravel;
33  import org.kuali.ole.fp.businessobject.DisbursementVoucherPreConferenceRegistrant;
34  import org.kuali.ole.fp.businessobject.WireCharge;
35  import org.kuali.ole.fp.document.DisbursementVoucherConstants;
36  import org.kuali.ole.fp.document.DisbursementVoucherDocument;
37  import org.kuali.ole.fp.document.DisbursementVoucherConstants.TabByReasonCode;
38  import org.kuali.ole.fp.document.service.DisbursementVoucherCoverSheetService;
39  import org.kuali.ole.fp.document.service.DisbursementVoucherPayeeService;
40  import org.kuali.ole.fp.document.service.DisbursementVoucherTaxService;
41  import org.kuali.ole.fp.document.service.DisbursementVoucherTravelService;
42  import org.kuali.ole.sys.OLEConstants;
43  import org.kuali.ole.sys.OLEKeyConstants;
44  import org.kuali.ole.sys.OLEPropertyConstants;
45  import org.kuali.ole.sys.context.SpringContext;
46  import org.kuali.ole.sys.service.UniversityDateService;
47  import org.kuali.ole.sys.web.struts.KualiAccountingDocumentActionBase;
48  import org.kuali.ole.vnd.businessobject.VendorAddress;
49  import org.kuali.ole.vnd.businessobject.VendorDetail;
50  import org.kuali.rice.core.api.config.property.ConfigurationService;
51  import org.kuali.rice.core.api.util.type.KualiDecimal;
52  import org.kuali.rice.kew.api.exception.WorkflowException;
53  import org.kuali.rice.kim.api.identity.Person;
54  import org.kuali.rice.kim.api.identity.PersonService;
55  import org.kuali.rice.kns.document.authorization.TransactionalDocumentAuthorizer;
56  import org.kuali.rice.kns.document.authorization.TransactionalDocumentPresentationController;
57  import org.kuali.rice.kns.service.DictionaryValidationService;
58  import org.kuali.rice.kns.util.WebUtils;
59  import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase;
60  import org.kuali.rice.krad.service.BusinessObjectService;
61  import org.kuali.rice.krad.service.DocumentService;
62  import org.kuali.rice.krad.util.GlobalVariables;
63  import org.kuali.rice.krad.util.KRADConstants;
64  import org.kuali.rice.krad.util.ObjectUtils;
65  import org.kuali.rice.krad.util.UrlFactory;
66  
67  /**
68   * This class handles Actions for the DisbursementVoucher.
69   */
70  public class DisbursementVoucherAction extends KualiAccountingDocumentActionBase {
71      protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DisbursementVoucherAction.class);
72  
73      /**
74       * @see org.kuali.ole.sys.web.struts.KualiAccountingDocumentActionBase#loadDocument(org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase)
75       */
76      @Override
77      protected void loadDocument(KualiDocumentFormBase kualiDocumentFormBase) throws WorkflowException {
78          super.loadDocument(kualiDocumentFormBase);
79  
80          DisbursementVoucherForm dvForm = (DisbursementVoucherForm) kualiDocumentFormBase;
81          DisbursementVoucherDocument dvDoc = (DisbursementVoucherDocument) dvForm.getDocument();
82  
83          // do not execute the further refreshing logic if a payee is not selected
84          String payeeIdNumber = dvDoc.getDvPayeeDetail().getDisbVchrPayeeIdNumber();
85  
86          Person person = SpringContext.getBean(PersonService.class).getPersonByEmployeeId(payeeIdNumber);
87  
88          //OLEMI-8935: When an employee is inactive, the Payment Type field on DV documents should display the message "Is this payee an employee" = No
89          if (person != null && person.isActive()) {
90              dvDoc.getDvPayeeDetail().setDisbVchrPayeeEmployeeCode(true);
91          } else {
92              dvDoc.getDvPayeeDetail().setDisbVchrPayeeEmployeeCode(false);
93          }
94      }
95  
96      /**
97       * @see org.kuali.ole.sys.web.struts.KualiAccountingDocumentActionBase#execute(org.apache.struts.action.ActionMapping,
98       *      org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
99       */
100     @Override
101     public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
102         ActionForward dest = super.execute(mapping, form, request, response);
103 
104         DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
105         if (form != null) {
106             DisbursementVoucherDocument dvDoc = (DisbursementVoucherDocument) dvForm.getDocument();
107             if (dvDoc != null) {
108                 DisbursementVoucherNonEmployeeTravel dvNet = dvDoc.getDvNonEmployeeTravel();
109                 if (dvNet != null) {
110                     // clear values derived from travelMileageAmount if that amount has been (manually) cleared
111                     Integer amount = dvNet.getDvPersonalCarMileageAmount();
112                     if ((amount == null) || (amount.intValue() == 0)) {
113                         clearTravelMileageAmount(dvNet);
114                     }
115 
116                     // clear values derived from perDiemRate if that amount has been (manually) cleared
117                     KualiDecimal rate = dvNet.getDisbVchrPerdiemRate();
118                     if ((rate == null) || rate.isZero()) {
119                         clearTravelPerDiem(dvNet);
120                     }
121                 }
122             }
123         }
124 
125         return dest;
126     }
127 
128     /**
129      * @see org.kuali.rice.kns.web.struts.action.KualiDocumentActionBase#approve(org.apache.struts.action.ActionMapping,
130      *      org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
131      */
132     @Override
133     public ActionForward approve(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
134         DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
135         SpringContext.getBean(DisbursementVoucherPayeeService.class).checkPayeeAddressForChanges((DisbursementVoucherDocument) dvForm.getDocument());
136 
137         return super.approve(mapping, form, request, response);
138     }
139 
140     /**
141      * Do initialization for a new disbursement voucher
142      *
143      * @see org.kuali.rice.kns.web.struts.action.KualiDocumentActionBase#createDocument(org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase)
144      */
145     @Override
146     protected void createDocument(KualiDocumentFormBase kualiDocumentFormBase) throws WorkflowException {
147         super.createDocument(kualiDocumentFormBase);
148         ((DisbursementVoucherDocument) kualiDocumentFormBase.getDocument()).initiateDocument();
149 
150         // set wire charge message in form
151         ((DisbursementVoucherForm) kualiDocumentFormBase).setWireChargeMessage(retrieveWireChargeMessage());
152     }
153 
154     /**
155      * Calls service to generate the disbursement voucher cover sheet as a pdf.
156      */
157     public ActionForward printDisbursementVoucherCoverSheet(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
158         DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
159 
160         // get directory of template
161         String directory = SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(OLEConstants.EXTERNALIZABLE_HELP_URL_KEY);
162 
163         DisbursementVoucherDocument document = (DisbursementVoucherDocument) SpringContext.getBean(DocumentService.class).getByDocumentHeaderId(request.getParameter(OLEPropertyConstants.DOCUMENT_NUMBER));
164 
165         // set workflow document back into form to prevent document authorizer "invalid (null)
166         // document.documentHeader.workflowDocument" since we are bypassing form submit and just linking directly to the action
167 
168         dvForm.getDocument().getDocumentHeader().setWorkflowDocument(document.getDocumentHeader().getWorkflowDocument());
169 
170         ByteArrayOutputStream baos = new ByteArrayOutputStream();
171         DisbursementVoucherCoverSheetService coverSheetService = SpringContext.getBean(DisbursementVoucherCoverSheetService.class);
172 
173         coverSheetService.generateDisbursementVoucherCoverSheet(directory, DisbursementVoucherConstants.DV_COVER_SHEET_TEMPLATE_NM, document, baos);
174         String fileName = document.getDocumentNumber() + "_cover_sheet.pdf";
175         WebUtils.saveMimeOutputStreamAsFile(response, "application/pdf", baos, fileName);
176 
177         return (null);
178     }
179 
180     /**
181      * Calculates the travel per diem amount.
182      */
183     public ActionForward calculateTravelPerDiem(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
184         DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
185 
186         try {
187             // call service to calculate per diem
188             DisbursementVoucherDocument dvDocument = (DisbursementVoucherDocument) dvForm.getDocument();
189             KualiDecimal perDiemAmount = SpringContext.getBean(DisbursementVoucherTravelService.class).calculatePerDiemAmount(dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemEndDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDisbVchrPerdiemRate());
190 
191             dvDocument.getDvNonEmployeeTravel().setDisbVchrPerdiemCalculatedAmt(perDiemAmount);
192             dvDocument.getDvNonEmployeeTravel().setDisbVchrPerdiemActualAmount(perDiemAmount);
193         }
194         catch (RuntimeException e) {
195             String errorMessage = e.getMessage();
196 
197             if (StringUtils.isBlank(errorMessage)) {
198                 errorMessage = "The per diem amount could not be calculated.  Please ensure all required per diem fields are filled in before attempting to calculate the per diem amount.";
199             }
200 
201             LOG.error("Error in calculating travel per diem: " + errorMessage);
202             GlobalVariables.getMessageMap().putError("DVNonEmployeeTravelErrors", OLEKeyConstants.ERROR_CUSTOM, errorMessage);
203         }
204 
205         return mapping.findForward(OLEConstants.MAPPING_BASIC);
206     }
207 
208     /**
209      * Clears the travel per diem amount
210      */
211     public ActionForward clearTravelPerDiem(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
212         DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
213         DisbursementVoucherDocument dvDocument = (DisbursementVoucherDocument) dvForm.getDocument();
214 
215         DisbursementVoucherNonEmployeeTravel dvNet = dvDocument.getDvNonEmployeeTravel();
216         if (dvNet != null) {
217             clearTravelPerDiem(dvNet);
218         }
219 
220         return mapping.findForward(OLEConstants.MAPPING_BASIC);
221     }
222 
223     /**
224      * clear travel perdiem amounts
225      */
226     protected void clearTravelPerDiem(DisbursementVoucherNonEmployeeTravel dvNet) {
227         dvNet.setDisbVchrPerdiemCalculatedAmt(null);
228         dvNet.setDisbVchrPerdiemActualAmount(null);
229     }
230 
231     /**
232      * Calculates the travel mileage amount.
233      */
234     public ActionForward calculateTravelMileageAmount(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
235         DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
236         DisbursementVoucherDocument dvDocument = (DisbursementVoucherDocument) dvForm.getDocument();
237 
238         if (dvDocument.getDvNonEmployeeTravel().getDvPersonalCarMileageAmount() == null) {
239             LOG.error("Total Mileage must be given");
240             GlobalVariables.getMessageMap().putError("DVNonEmployeeTravelErrors", OLEKeyConstants.ERROR_REQUIRED, "Total Mileage");
241         }
242 
243         if (dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp() == null) {
244             LOG.error("Travel Start Date must be given");
245             GlobalVariables.getMessageMap().putError("DVNonEmployeeTravelErrors", OLEKeyConstants.ERROR_REQUIRED, "Travel Start Date");
246         }
247 
248         if (!GlobalVariables.getMessageMap().hasErrors()) {
249             // call service to calculate mileage amount
250             KualiDecimal mileageAmount = SpringContext.getBean(DisbursementVoucherTravelService.class).calculateMileageAmount(dvDocument.getDvNonEmployeeTravel().getDvPersonalCarMileageAmount(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp());
251 
252             dvDocument.getDvNonEmployeeTravel().setDisbVchrMileageCalculatedAmt(mileageAmount);
253             dvDocument.getDvNonEmployeeTravel().setDisbVchrPersonalCarAmount(mileageAmount);
254         }
255 
256         return mapping.findForward(OLEConstants.MAPPING_BASIC);
257     }
258 
259     /**
260      * Clears the travel mileage amount
261      */
262     public ActionForward clearTravelMileageAmount(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
263         DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
264         DisbursementVoucherDocument dvDocument = (DisbursementVoucherDocument) dvForm.getDocument();
265 
266         DisbursementVoucherNonEmployeeTravel dvNet = dvDocument.getDvNonEmployeeTravel();
267         if (dvNet != null) {
268             clearTravelMileageAmount(dvNet);
269         }
270 
271         return mapping.findForward(OLEConstants.MAPPING_BASIC);
272     }
273 
274     /**
275      * reset the travel mileage amount as null
276      */
277     protected void clearTravelMileageAmount(DisbursementVoucherNonEmployeeTravel dvNet) {
278         dvNet.setDisbVchrMileageCalculatedAmt(null);
279         dvNet.setDisbVchrPersonalCarAmount(null);
280     }
281 
282     /**
283      * Adds a new employee travel expense line.
284      */
285     public ActionForward addNonEmployeeExpenseLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
286         DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
287         DisbursementVoucherDocument dvDocument = (DisbursementVoucherDocument) dvForm.getDocument();
288 
289         DisbursementVoucherNonEmployeeExpense newExpenseLine = dvForm.getNewNonEmployeeExpenseLine();
290 
291         // validate line
292         GlobalVariables.getMessageMap().addToErrorPath(OLEPropertyConstants.NEW_NONEMPLOYEE_EXPENSE_LINE);
293         SpringContext.getBean(DictionaryValidationService.class).validateBusinessObject(newExpenseLine);
294 
295         // Ensure all fields are filled in before attempting to add a new expense line
296         if (StringUtils.isBlank(newExpenseLine.getDisbVchrPrePaidExpenseCode())) {
297             GlobalVariables.getMessageMap().putError(OLEPropertyConstants.DISB_VCHR_EXPENSE_CODE, OLEKeyConstants.ERROR_DV_EXPENSE_CODE);
298         }
299         if (StringUtils.isBlank(newExpenseLine.getDisbVchrPrePaidExpenseCompanyName())) {
300             GlobalVariables.getMessageMap().putError(OLEPropertyConstants.DISB_VCHR_EXPENSE_COMPANY_NAME, OLEKeyConstants.ERROR_DV_EXPENSE_COMPANY_NAME);
301         }
302         if (ObjectUtils.isNull(newExpenseLine.getDisbVchrExpenseAmount())) {
303             GlobalVariables.getMessageMap().putError(OLEPropertyConstants.DISB_VCHR_EXPENSE_AMOUNT, OLEKeyConstants.ERROR_DV_EXPENSE_AMOUNT);
304         }
305 
306         GlobalVariables.getMessageMap().removeFromErrorPath(OLEPropertyConstants.NEW_NONEMPLOYEE_EXPENSE_LINE);
307 
308         //OLEMI-9523
309         //no errors so go ahead and add the record to the list.  Need to set the document number
310         //and recalculate the next line number for the new record that is created after adding the
311         //current one.
312         if (!GlobalVariables.getMessageMap().hasErrors()) {
313             newExpenseLine.setDocumentNumber(dvDocument.getDocumentNumber());
314             dvDocument.getDvNonEmployeeTravel().addDvNonEmployeeExpenseLine(newExpenseLine);
315             DisbursementVoucherNonEmployeeExpense newNewNonEmployeeExpenseLine = new DisbursementVoucherNonEmployeeExpense();
316             newNewNonEmployeeExpenseLine.setFinancialDocumentLineNumber(newExpenseLine.getFinancialDocumentLineNumber() + 1);
317             dvForm.setNewNonEmployeeExpenseLine(newNewNonEmployeeExpenseLine);
318         }
319 
320         return mapping.findForward(OLEConstants.MAPPING_BASIC);
321     }
322 
323     /**
324      * Adds a new employee pre paid travel expense line.
325      */
326     public ActionForward addPrePaidNonEmployeeExpenseLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
327         DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
328         DisbursementVoucherDocument dvDocument = (DisbursementVoucherDocument) dvForm.getDocument();
329 
330         DisbursementVoucherNonEmployeeExpense newExpenseLine = dvForm.getNewPrePaidNonEmployeeExpenseLine();
331 
332         // validate line
333         GlobalVariables.getMessageMap().addToErrorPath(OLEPropertyConstants.NEW_PREPAID_EXPENSE_LINE);
334         SpringContext.getBean(DictionaryValidationService.class).validateBusinessObject(newExpenseLine);
335 
336         // Ensure all fields are filled in before attempting to add a new expense line
337         if (StringUtils.isBlank(newExpenseLine.getDisbVchrPrePaidExpenseCode())) {
338             GlobalVariables.getMessageMap().putError(OLEPropertyConstants.DISB_VCHR_PRE_PAID_EXPENSE_CODE, OLEKeyConstants.ERROR_DV_PREPAID_EXPENSE_CODE);
339         }
340         if (StringUtils.isBlank(newExpenseLine.getDisbVchrPrePaidExpenseCompanyName())) {
341             GlobalVariables.getMessageMap().putError(OLEPropertyConstants.DISB_VCHR_PRE_PAID_EXPENSE_COMPANY_NAME, OLEKeyConstants.ERROR_DV_PREPAID_EXPENSE_COMPANY_NAME);
342         }
343         if (ObjectUtils.isNull(newExpenseLine.getDisbVchrExpenseAmount())) {
344             GlobalVariables.getMessageMap().putError(OLEPropertyConstants.DISB_VCHR_EXPENSE_AMOUNT, OLEKeyConstants.ERROR_DV_PREPAID_EXPENSE_AMOUNT);
345         }
346         GlobalVariables.getMessageMap().removeFromErrorPath(OLEPropertyConstants.NEW_PREPAID_EXPENSE_LINE);
347 
348         //OLEMI-9523
349         //no errors so go ahead and add the record to the list.  Need to set the document number
350         //and recalculate the next line number for the new record that is created after adding the
351         //current one.
352         if (!GlobalVariables.getMessageMap().hasErrors()) {
353             newExpenseLine.setDocumentNumber(dvDocument.getDocumentNumber());
354             dvDocument.getDvNonEmployeeTravel().addDvPrePaidEmployeeExpenseLine(newExpenseLine);
355             DisbursementVoucherNonEmployeeExpense newNewNonEmployeeExpenseLine = new DisbursementVoucherNonEmployeeExpense();
356             newNewNonEmployeeExpenseLine.setFinancialDocumentLineNumber(newExpenseLine.getFinancialDocumentLineNumber() + 1);
357             dvForm.setNewPrePaidNonEmployeeExpenseLine(newNewNonEmployeeExpenseLine);
358         }
359 
360         return mapping.findForward(OLEConstants.MAPPING_BASIC);
361     }
362 
363     /**
364      * Deletes a non employee travel expense line.
365      */
366     public ActionForward deleteNonEmployeeExpenseLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
367         DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
368         DisbursementVoucherDocument dvDocument = (DisbursementVoucherDocument) dvForm.getDocument();
369 
370         int deleteIndex = getLineToDelete(request);
371         dvDocument.getDvNonEmployeeTravel().getDvNonEmployeeExpenses().remove(deleteIndex);
372 
373         return mapping.findForward(OLEConstants.MAPPING_BASIC);
374     }
375 
376     /**
377      * Deletes a pre paid travel expense line.
378      */
379     public ActionForward deletePrePaidEmployeeExpenseLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
380         DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
381         DisbursementVoucherDocument dvDocument = (DisbursementVoucherDocument) dvForm.getDocument();
382 
383         int deleteIndex = getLineToDelete(request);
384         dvDocument.getDvNonEmployeeTravel().getDvPrePaidEmployeeExpenses().remove(deleteIndex);
385 
386         return mapping.findForward(OLEConstants.MAPPING_BASIC);
387     }
388 
389     /**
390      * Adds a new pre conference registrant line.
391      */
392     public ActionForward addPreConfRegistrantLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
393         DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
394         DisbursementVoucherDocument dvDocument = (DisbursementVoucherDocument) dvForm.getDocument();
395 
396         DisbursementVoucherPreConferenceRegistrant newRegistrantLine = dvForm.getNewPreConferenceRegistrantLine();
397 
398         // validate line
399         GlobalVariables.getMessageMap().addToErrorPath(OLEPropertyConstants.NEW_PRECONF_REGISTRANT_LINE);
400         SpringContext.getBean(DictionaryValidationService.class).validateBusinessObject(newRegistrantLine);
401         GlobalVariables.getMessageMap().removeFromErrorPath(OLEPropertyConstants.NEW_PRECONF_REGISTRANT_LINE);
402 
403         if (!GlobalVariables.getMessageMap().hasErrors()) {
404             dvDocument.addDvPrePaidRegistrantLine(newRegistrantLine);
405             dvForm.setNewPreConferenceRegistrantLine(new DisbursementVoucherPreConferenceRegistrant());
406         }
407 
408         return mapping.findForward(OLEConstants.MAPPING_BASIC);
409     }
410 
411     /**
412      * Deletes a pre conference registrant line.
413      */
414     public ActionForward deletePreConfRegistrantLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
415         DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
416         DisbursementVoucherDocument dvDocument = (DisbursementVoucherDocument) dvForm.getDocument();
417 
418         int deleteIndex = getLineToDelete(request);
419         dvDocument.getDvPreConferenceDetail().getDvPreConferenceRegistrants().remove(deleteIndex);
420 
421         return mapping.findForward(OLEConstants.MAPPING_BASIC);
422     }
423 
424     /**
425      * Calls service to generate tax accounting lines and updates nra tax line string in action form.
426      */
427     public ActionForward generateNonResidentAlienTaxLines(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
428         DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
429         DisbursementVoucherDocument document = (DisbursementVoucherDocument) dvForm.getDocument();
430 
431         DisbursementVoucherTaxService taxService = SpringContext.getBean(DisbursementVoucherTaxService.class);
432 
433         /* call service to generate new tax lines */
434         GlobalVariables.getMessageMap().addToErrorPath("document");
435         taxService.processNonResidentAlienTax(document);
436         GlobalVariables.getMessageMap().removeFromErrorPath("document");
437 
438         return mapping.findForward(OLEConstants.MAPPING_BASIC);
439     }
440 
441     /**
442      * Calls service to clear tax accounting lines and updates nra tax line string in action form.
443      */
444     public ActionForward clearNonResidentAlienTaxLines(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
445         DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
446         DisbursementVoucherDocument document = (DisbursementVoucherDocument) dvForm.getDocument();
447 
448         DisbursementVoucherTaxService taxService = SpringContext.getBean(DisbursementVoucherTaxService.class);
449 
450         /* call service to clear previous lines */
451         taxService.clearNRATaxLines(document);
452 
453         return mapping.findForward(OLEConstants.MAPPING_BASIC);
454     }
455 
456     /**
457      * Calls service to clear tax info.
458      */
459     public ActionForward clearNonResidentAlienTaxInfo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
460         DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
461         DisbursementVoucherDocument document = (DisbursementVoucherDocument) dvForm.getDocument();
462 
463         DisbursementVoucherTaxService taxService = SpringContext.getBean(DisbursementVoucherTaxService.class);
464 
465         /* call service to clear previous lines */
466         taxService.clearNRATaxInfo(document);
467 
468         return mapping.findForward(OLEConstants.MAPPING_BASIC);
469     }
470 
471     /**
472      * Builds the wire charge message for the current fiscal year.
473      *
474      * @return the wire charge message for the current fiscal year
475      */
476     protected String retrieveWireChargeMessage() {
477         String message = SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(OLEKeyConstants.MESSAGE_DV_WIRE_CHARGE);
478         WireCharge wireCharge = new WireCharge();
479         wireCharge.setUniversityFiscalYear(SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear());
480 
481         wireCharge = (WireCharge) SpringContext.getBean(BusinessObjectService.class).retrieve(wireCharge);
482         Object[] args = { wireCharge.getDomesticChargeAmt(), wireCharge.getForeignChargeAmt() };
483 
484         return MessageFormat.format(message, args);
485     }
486 
487     /**
488      * @see org.kuali.rice.kns.web.struts.action.KualiAction#refresh(org.apache.struts.action.ActionMapping,
489      *      org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
490      */
491     @Override
492     public ActionForward refresh(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
493         DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
494 
495         ActionForward actionAfterPayeeLookup = this.refreshAfterPayeeSelection(mapping, dvForm, request);
496         if (actionAfterPayeeLookup != null) {
497             return actionAfterPayeeLookup;
498         }
499 
500         return super.refresh(mapping, form, request, response);
501     }
502 
503     // do refresh after a payee is selected
504     protected ActionForward refreshAfterPayeeSelection(ActionMapping mapping, DisbursementVoucherForm dvForm, HttpServletRequest request) {
505         String refreshCaller = dvForm.getRefreshCaller();
506 
507         DisbursementVoucherDocument document = (DisbursementVoucherDocument) dvForm.getDocument();
508 
509         boolean isPayeeLookupable = OLEConstants.KUALI_DISBURSEMENT_PAYEE_LOOKUPABLE_IMPL.equals(refreshCaller);
510         boolean isAddressLookupable = OLEConstants.KUALI_VENDOR_ADDRESS_LOOKUPABLE_IMPL.equals(refreshCaller);
511 
512         // if a cancel occurred on address lookup we need to reset the payee id and type, rest of fields will still have correct information
513         if (refreshCaller == null && hasFullEdit(document)) {
514             dvForm.setPayeeIdNumber(dvForm.getTempPayeeIdNumber());
515             dvForm.setHasMultipleAddresses(false);
516             document.getDvPayeeDetail().setDisbVchrPayeeIdNumber(dvForm.getTempPayeeIdNumber());
517             document.getDvPayeeDetail().setDisbursementVoucherPayeeTypeCode(dvForm.getOldPayeeType());
518 
519             return null;
520         }
521 
522         // do not execute the further refreshing logic if the refresh caller is not a lookupable
523         if (!isPayeeLookupable && !isAddressLookupable) {
524             return null;
525         }
526 
527         // do not execute the further refreshing logic if a payee is not selected
528         String payeeIdNumber = document.getDvPayeeDetail().getDisbVchrPayeeIdNumber();
529         if (payeeIdNumber == null) {
530             return null;
531         }
532 
533         dvForm.setPayeeIdNumber(payeeIdNumber);
534         dvForm.setHasMultipleAddresses(false);
535 
536         // determine whether the selected vendor has multiple addresses. If so, redirect to the address selection screen
537         if (isPayeeLookupable && dvForm.isVendor()) {
538             VendorDetail refreshVendorDetail = new VendorDetail();
539             refreshVendorDetail.setVendorNumber(payeeIdNumber);
540             refreshVendorDetail = (VendorDetail) SpringContext.getBean(BusinessObjectService.class).retrieve(refreshVendorDetail);
541 
542             VendorAddress defaultVendorAddress = null;
543             if (refreshVendorDetail != null) {
544                 List<VendorAddress> vendorAddresses = refreshVendorDetail.getVendorAddresses();
545                 boolean hasMultipleAddresses = vendorAddresses != null && vendorAddresses.size() > 1;
546                 dvForm.setHasMultipleAddresses(hasMultipleAddresses);
547 
548                 if (vendorAddresses != null) {
549                     defaultVendorAddress = vendorAddresses.get(0);
550                 }
551             }
552 
553             if (dvForm.hasMultipleAddresses()) {
554                 return renderVendorAddressSelection(mapping, request, dvForm);
555             }
556             else if (defaultVendorAddress != null) {
557                 setupPayeeAsVendor(dvForm, payeeIdNumber, defaultVendorAddress.getVendorAddressGeneratedIdentifier().toString());
558             }
559 
560             return null;
561         }
562 
563         if (isPayeeLookupable && dvForm.isEmployee()) {
564             this.setupPayeeAsEmployee(dvForm, payeeIdNumber);
565         }
566 
567         String payeeAddressIdentifier = request.getParameter(OLEPropertyConstants.VENDOR_ADDRESS_GENERATED_ID);
568         if (isAddressLookupable && StringUtils.isNotBlank(payeeAddressIdentifier)) {
569             setupPayeeAsVendor(dvForm, payeeIdNumber, payeeAddressIdentifier);
570         }
571 
572         String paymentReasonCode = document.getDvPayeeDetail().getDisbVchrPaymentReasonCode();
573       //Commented for the jira issue OLE-3415
574         //addPaymentCodeWarningMessage(dvForm, paymentReasonCode);
575 
576         return null;
577     }
578 
579     /**
580      * Determines if the current user has full edit permissions on the document, which would allow them to repopulate the payee
581      * @param document the document to check for full edit permissions on
582      * @return true if full edit is allowed on the document, false otherwise
583      */
584     protected boolean hasFullEdit(DisbursementVoucherDocument document) {
585         final Person user = GlobalVariables.getUserSession().getPerson();
586         final TransactionalDocumentPresentationController documentPresentationController = (TransactionalDocumentPresentationController)getDocumentHelperService().getDocumentPresentationController(document);
587         final TransactionalDocumentAuthorizer documentAuthorizer = (TransactionalDocumentAuthorizer)getDocumentHelperService().getDocumentAuthorizer(document);
588         Set<String> documentActions =  documentPresentationController.getDocumentActions(document);
589         documentActions = documentAuthorizer.getDocumentActions(document, user, documentActions);
590 
591         if (getDataDictionaryService().getDataDictionary().getDocumentEntry(document.getClass().getName()).getUsePessimisticLocking()) {
592             documentActions = getPessimisticLockService().getDocumentActions(document, user, documentActions);
593         }
594 
595         Set<String> editModes = documentPresentationController.getEditModes(document);
596         editModes = documentAuthorizer.getEditModes(document, user, editModes);
597 
598         return documentActions.contains(KRADConstants.KUALI_ACTION_CAN_EDIT) && editModes.contains("fullEntry");
599     }
600 
601     /**
602      * Hook into performLookup to switch the payee lookup based on the payee type selected.
603      */
604     @Override
605     public ActionForward performLookup(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
606         DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
607         DisbursementVoucherDocument document = (DisbursementVoucherDocument) dvForm.getDocument();
608 
609         return super.performLookup(mapping, form, request, response);
610     }
611 
612     /**
613      * render the vendor address lookup results if there are multiple addresses for the selected vendor
614      */
615     protected ActionForward renderVendorAddressSelection(ActionMapping mapping, HttpServletRequest request, DisbursementVoucherForm dvForm) {
616         Properties props = new Properties();
617 
618         props.put(KRADConstants.SUPPRESS_ACTIONS, Boolean.toString(true));
619         props.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, VendorAddress.class.getName());
620         props.put(KRADConstants.LOOKUP_ANCHOR, KRADConstants.ANCHOR_TOP_OF_FORM);
621         props.put(KRADConstants.LOOKED_UP_COLLECTION_NAME, OLEPropertyConstants.VENDOR_ADDRESSES);
622 
623         String conversionPatttern = "{0}" + OLEConstants.FIELD_CONVERSION_PAIR_SEPERATOR + "{0}";
624         StringBuilder filedConversion = new StringBuilder();
625         filedConversion.append(MessageFormat.format(conversionPatttern, OLEPropertyConstants.VENDOR_ADDRESS_GENERATED_ID)).append(OLEConstants.FIELD_CONVERSIONS_SEPERATOR);
626         filedConversion.append(MessageFormat.format(conversionPatttern, OLEPropertyConstants.VENDOR_HEADER_GENERATED_ID)).append(OLEConstants.FIELD_CONVERSIONS_SEPERATOR);
627         filedConversion.append(MessageFormat.format(conversionPatttern, OLEPropertyConstants.VENDOR_DETAIL_ASSIGNED_ID));
628         props.put(KRADConstants.CONVERSION_FIELDS_PARAMETER, filedConversion);
629 
630         props.put(OLEPropertyConstants.VENDOR_HEADER_GENERATED_ID, dvForm.getVendorHeaderGeneratedIdentifier());
631         props.put(OLEPropertyConstants.VENDOR_DETAIL_ASSIGNED_ID, dvForm.getVendorDetailAssignedIdentifier());
632         props.put(OLEPropertyConstants.ACTIVE, OLEConstants.ACTIVE_INDICATOR);
633 
634         props.put(KRADConstants.RETURN_LOCATION_PARAMETER, this.getReturnLocation(request, mapping));
635         props.put(KRADConstants.BACK_LOCATION, this.getReturnLocation(request, mapping));
636 
637         props.put(KRADConstants.LOOKUP_AUTO_SEARCH, "Yes");
638         props.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, OLEConstants.SEARCH_METHOD);
639 
640         props.put(KRADConstants.DOC_FORM_KEY, GlobalVariables.getUserSession().addObjectWithGeneratedKey(dvForm));
641         props.put(KRADConstants.DOC_NUM, dvForm.getDocument().getDocumentNumber());
642 
643         // TODO: how should this forward be handled
644         String url = UrlFactory.parameterizeUrl(getApplicationBaseUrl() + "/kr/" + KRADConstants.LOOKUP_ACTION, props);
645 
646         dvForm.registerEditableProperty("methodToCall");
647 
648         return new ActionForward(url, true);
649     }
650 
651     /**
652      * setup the payee as an employee with the given id number
653      */
654     protected void setupPayeeAsEmployee(DisbursementVoucherForm dvForm, String payeeIdNumber) {
655         Person person = SpringContext.getBean(PersonService.class).getPersonByEmployeeId(payeeIdNumber);
656         if (person != null) {
657             ((DisbursementVoucherDocument) dvForm.getDocument()).templateEmployee(person);
658             dvForm.setTempPayeeIdNumber(payeeIdNumber);
659             dvForm.setOldPayeeType(DisbursementVoucherConstants.DV_PAYEE_TYPE_EMPLOYEE);
660 
661         }
662         else {
663             LOG.error("Exception while attempting to retrieve universal user by universal user id " + payeeIdNumber);
664         }
665     }
666 
667     /**
668      * setup the payee as a vendor with the given id number and address id
669      */
670     protected void setupPayeeAsVendor(DisbursementVoucherForm dvForm, String payeeIdNumber, String payeeAddressIdentifier) {
671         VendorDetail vendorDetail = new VendorDetail();
672         vendorDetail.setVendorNumber(payeeIdNumber);
673         vendorDetail = (VendorDetail) SpringContext.getBean(BusinessObjectService.class).retrieve(vendorDetail);
674 
675         VendorAddress vendorAddress = new VendorAddress();
676         if (StringUtils.isNotBlank(payeeAddressIdentifier)) {
677             try {
678                 vendorAddress.setVendorAddressGeneratedIdentifier(new Integer(payeeAddressIdentifier));
679                 vendorAddress = (VendorAddress) SpringContext.getBean(BusinessObjectService.class).retrieve(vendorAddress);
680                 dvForm.setTempPayeeIdNumber(payeeIdNumber);
681                 dvForm.setOldPayeeType(DisbursementVoucherConstants.DV_PAYEE_TYPE_VENDOR);
682 
683             }
684             catch (Exception e) {
685                 LOG.error("Exception while attempting to retrieve vendor address for vendor address id " + payeeAddressIdentifier + ": " + e);
686             }
687         }
688 
689         ((DisbursementVoucherDocument) dvForm.getDocument()).templateVendor(vendorDetail, vendorAddress);
690     }
691 
692     /**
693      * add warning message based on the given reason code
694      */
695     protected void addPaymentCodeWarningMessage(DisbursementVoucherForm dvForm, String paymentReasonCode) {
696         // clear up the warning message and tab state carried from previous screen
697         for (String tabKey : TabByReasonCode.getAllTabKeys()) {
698             dvForm.getTabStates().remove(tabKey);
699         }
700 
701         for (String propertyKey : TabByReasonCode.getAllDocumentPropertyKeys()) {
702             GlobalVariables.getMessageMap().removeAllWarningMessagesForProperty(propertyKey);
703         }
704 
705         String reasonCodeProperty = OLEPropertyConstants.DOCUMENT + "." + OLEPropertyConstants.DV_PAYEE_DETAIL + "." + OLEPropertyConstants.DISB_VCHR_PAYMENT_REASON_CODE;
706         GlobalVariables.getMessageMap().removeAllWarningMessagesForProperty(reasonCodeProperty);
707 
708         // add warning message and reset tab state as open if any
709         TabByReasonCode tab = TabByReasonCode.getTabByReasonCode(paymentReasonCode);
710         if (tab != null) {
711             dvForm.getTabStates().put(tab.tabKey, "OPEN");
712             GlobalVariables.getMessageMap().putWarning(reasonCodeProperty, tab.messageKey);
713             GlobalVariables.getMessageMap().putWarning(tab.getDocumentPropertyKey(), tab.messageKey);
714         }
715     }
716 }