001 /*
002 * Copyright 2011 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.kfs.fp.document.web.struts;
017
018 import java.io.ByteArrayOutputStream;
019 import java.text.MessageFormat;
020 import java.util.List;
021 import java.util.Properties;
022 import java.util.Set;
023
024 import javax.servlet.http.HttpServletRequest;
025 import javax.servlet.http.HttpServletResponse;
026
027 import org.apache.commons.lang.StringUtils;
028 import org.apache.struts.action.ActionForm;
029 import org.apache.struts.action.ActionForward;
030 import org.apache.struts.action.ActionMapping;
031 import org.kuali.kfs.fp.businessobject.DisbursementVoucherNonEmployeeExpense;
032 import org.kuali.kfs.fp.businessobject.DisbursementVoucherNonEmployeeTravel;
033 import org.kuali.kfs.fp.businessobject.DisbursementVoucherPreConferenceRegistrant;
034 import org.kuali.kfs.fp.businessobject.WireCharge;
035 import org.kuali.kfs.fp.document.DisbursementVoucherConstants;
036 import org.kuali.kfs.fp.document.DisbursementVoucherDocument;
037 import org.kuali.kfs.fp.document.DisbursementVoucherConstants.TabByReasonCode;
038 import org.kuali.kfs.fp.document.service.DisbursementVoucherCoverSheetService;
039 import org.kuali.kfs.fp.document.service.DisbursementVoucherPayeeService;
040 import org.kuali.kfs.fp.document.service.DisbursementVoucherTaxService;
041 import org.kuali.kfs.fp.document.service.DisbursementVoucherTravelService;
042 import org.kuali.kfs.sys.KFSConstants;
043 import org.kuali.kfs.sys.KFSKeyConstants;
044 import org.kuali.kfs.sys.KFSPropertyConstants;
045 import org.kuali.kfs.sys.context.SpringContext;
046 import org.kuali.kfs.sys.service.UniversityDateService;
047 import org.kuali.kfs.sys.web.struts.KualiAccountingDocumentActionBase;
048 import org.kuali.kfs.vnd.businessobject.VendorAddress;
049 import org.kuali.kfs.vnd.businessobject.VendorDetail;
050 import org.kuali.rice.kew.exception.WorkflowException;
051 import org.kuali.rice.kim.bo.Person;
052 import org.kuali.rice.kim.service.PersonService;
053 import org.kuali.rice.kns.document.authorization.TransactionalDocumentAuthorizer;
054 import org.kuali.rice.kns.document.authorization.TransactionalDocumentPresentationController;
055 import org.kuali.rice.kns.service.BusinessObjectService;
056 import org.kuali.rice.kns.service.DictionaryValidationService;
057 import org.kuali.rice.kns.service.DocumentService;
058 import org.kuali.rice.kns.service.KualiConfigurationService;
059 import org.kuali.rice.kns.util.GlobalVariables;
060 import org.kuali.rice.kns.util.KNSConstants;
061 import org.kuali.rice.kns.util.KualiDecimal;
062 import org.kuali.rice.kns.util.ObjectUtils;
063 import org.kuali.rice.kns.util.UrlFactory;
064 import org.kuali.rice.kns.util.WebUtils;
065 import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase;
066
067 /**
068 * This class handles Actions for the DisbursementVoucher.
069 */
070 public class DisbursementVoucherAction extends KualiAccountingDocumentActionBase {
071 protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DisbursementVoucherAction.class);
072
073 /**
074 * @see org.kuali.kfs.sys.web.struts.KualiAccountingDocumentActionBase#execute(org.apache.struts.action.ActionMapping,
075 * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
076 */
077 @Override
078 public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
079 ActionForward dest = super.execute(mapping, form, request, response);
080
081 DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
082 if (form != null) {
083 DisbursementVoucherDocument dvDoc = (DisbursementVoucherDocument) dvForm.getDocument();
084 if (dvDoc != null) {
085 DisbursementVoucherNonEmployeeTravel dvNet = dvDoc.getDvNonEmployeeTravel();
086 if (dvNet != null) {
087 // clear values derived from travelMileageAmount if that amount has been (manually) cleared
088 Integer amount = dvNet.getDvPersonalCarMileageAmount();
089 if ((amount == null) || (amount.intValue() == 0)) {
090 clearTravelMileageAmount(dvNet);
091 }
092
093 // clear values derived from perDiemRate if that amount has been (manually) cleared
094 KualiDecimal rate = dvNet.getDisbVchrPerdiemRate();
095 if ((rate == null) || rate.isZero()) {
096 clearTravelPerDiem(dvNet);
097 }
098 }
099 }
100 }
101
102 return dest;
103 }
104
105 /**
106 * @see org.kuali.rice.kns.web.struts.action.KualiDocumentActionBase#approve(org.apache.struts.action.ActionMapping,
107 * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
108 */
109 @Override
110 public ActionForward approve(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
111 DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
112 SpringContext.getBean(DisbursementVoucherPayeeService.class).checkPayeeAddressForChanges((DisbursementVoucherDocument) dvForm.getDocument());
113
114 return super.approve(mapping, form, request, response);
115 }
116
117 /**
118 * Do initialization for a new disbursement voucher
119 *
120 * @see org.kuali.rice.kns.web.struts.action.KualiDocumentActionBase#createDocument(org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase)
121 */
122 @Override
123 protected void createDocument(KualiDocumentFormBase kualiDocumentFormBase) throws WorkflowException {
124 super.createDocument(kualiDocumentFormBase);
125 ((DisbursementVoucherDocument) kualiDocumentFormBase.getDocument()).initiateDocument();
126
127 // set wire charge message in form
128 ((DisbursementVoucherForm) kualiDocumentFormBase).setWireChargeMessage(retrieveWireChargeMessage());
129 }
130
131 /**
132 * Calls service to generate the disbursement voucher cover sheet as a pdf.
133 */
134 public ActionForward printDisbursementVoucherCoverSheet(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
135 DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
136
137 // get directory of template
138 String directory = SpringContext.getBean(KualiConfigurationService.class).getPropertyString(KFSConstants.EXTERNALIZABLE_HELP_URL_KEY);
139
140 DisbursementVoucherDocument document = (DisbursementVoucherDocument) SpringContext.getBean(DocumentService.class).getByDocumentHeaderId(request.getParameter(KFSPropertyConstants.DOCUMENT_NUMBER));
141
142 // set workflow document back into form to prevent document authorizer "invalid (null)
143 // document.documentHeader.workflowDocument" since we are bypassing form submit and just linking directly to the action
144
145 dvForm.getDocument().getDocumentHeader().setWorkflowDocument(document.getDocumentHeader().getWorkflowDocument());
146
147 ByteArrayOutputStream baos = new ByteArrayOutputStream();
148 DisbursementVoucherCoverSheetService coverSheetService = SpringContext.getBean(DisbursementVoucherCoverSheetService.class);
149
150 coverSheetService.generateDisbursementVoucherCoverSheet(directory, DisbursementVoucherConstants.DV_COVER_SHEET_TEMPLATE_NM, document, baos);
151 String fileName = document.getDocumentNumber() + "_cover_sheet.pdf";
152 WebUtils.saveMimeOutputStreamAsFile(response, "application/pdf", baos, fileName);
153
154 return (null);
155 }
156
157 /**
158 * Calculates the travel per diem amount.
159 */
160 public ActionForward calculateTravelPerDiem(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
161 DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
162
163 try {
164 // call service to calculate per diem
165 DisbursementVoucherDocument dvDocument = (DisbursementVoucherDocument) dvForm.getDocument();
166 KualiDecimal perDiemAmount = SpringContext.getBean(DisbursementVoucherTravelService.class).calculatePerDiemAmount(dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemEndDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDisbVchrPerdiemRate());
167
168 dvDocument.getDvNonEmployeeTravel().setDisbVchrPerdiemCalculatedAmt(perDiemAmount);
169 dvDocument.getDvNonEmployeeTravel().setDisbVchrPerdiemActualAmount(perDiemAmount);
170 }
171 catch (RuntimeException e) {
172 String errorMessage = e.getMessage();
173
174 if (StringUtils.isBlank(errorMessage)) {
175 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.";
176 }
177
178 LOG.error("Error in calculating travel per diem: " + errorMessage);
179 GlobalVariables.getMessageMap().putError("DVNonEmployeeTravelErrors", KFSKeyConstants.ERROR_CUSTOM, errorMessage);
180 }
181
182 return mapping.findForward(KFSConstants.MAPPING_BASIC);
183 }
184
185 /**
186 * Clears the travel per diem amount
187 */
188 public ActionForward clearTravelPerDiem(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
189 DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
190 DisbursementVoucherDocument dvDocument = (DisbursementVoucherDocument) dvForm.getDocument();
191
192 DisbursementVoucherNonEmployeeTravel dvNet = dvDocument.getDvNonEmployeeTravel();
193 if (dvNet != null) {
194 clearTravelPerDiem(dvNet);
195 }
196
197 return mapping.findForward(KFSConstants.MAPPING_BASIC);
198 }
199
200 /**
201 * clear travel perdiem amounts
202 */
203 protected void clearTravelPerDiem(DisbursementVoucherNonEmployeeTravel dvNet) {
204 dvNet.setDisbVchrPerdiemCalculatedAmt(null);
205 dvNet.setDisbVchrPerdiemActualAmount(null);
206 }
207
208 /**
209 * Calculates the travel mileage amount.
210 */
211 public ActionForward calculateTravelMileageAmount(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
212 DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
213 DisbursementVoucherDocument dvDocument = (DisbursementVoucherDocument) dvForm.getDocument();
214
215 if (dvDocument.getDvNonEmployeeTravel().getDvPersonalCarMileageAmount() == null) {
216 LOG.error("Total Mileage must be given");
217 GlobalVariables.getMessageMap().putError("DVNonEmployeeTravelErrors", KFSKeyConstants.ERROR_REQUIRED, "Total Mileage");
218 }
219
220 if (dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp() == null) {
221 LOG.error("Travel Start Date must be given");
222 GlobalVariables.getMessageMap().putError("DVNonEmployeeTravelErrors", KFSKeyConstants.ERROR_REQUIRED, "Travel Start Date");
223 }
224
225 if (GlobalVariables.getMessageMap().isEmpty()) {
226 // call service to calculate mileage amount
227 KualiDecimal mileageAmount = SpringContext.getBean(DisbursementVoucherTravelService.class).calculateMileageAmount(dvDocument.getDvNonEmployeeTravel().getDvPersonalCarMileageAmount(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp());
228
229 dvDocument.getDvNonEmployeeTravel().setDisbVchrMileageCalculatedAmt(mileageAmount);
230 dvDocument.getDvNonEmployeeTravel().setDisbVchrPersonalCarAmount(mileageAmount);
231 }
232
233 return mapping.findForward(KFSConstants.MAPPING_BASIC);
234 }
235
236 /**
237 * Clears the travel mileage amount
238 */
239 public ActionForward clearTravelMileageAmount(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
240 DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
241 DisbursementVoucherDocument dvDocument = (DisbursementVoucherDocument) dvForm.getDocument();
242
243 DisbursementVoucherNonEmployeeTravel dvNet = dvDocument.getDvNonEmployeeTravel();
244 if (dvNet != null) {
245 clearTravelMileageAmount(dvNet);
246 }
247
248 return mapping.findForward(KFSConstants.MAPPING_BASIC);
249 }
250
251 /**
252 * reset the travel mileage amount as null
253 */
254 protected void clearTravelMileageAmount(DisbursementVoucherNonEmployeeTravel dvNet) {
255 dvNet.setDisbVchrMileageCalculatedAmt(null);
256 dvNet.setDisbVchrPersonalCarAmount(null);
257 }
258
259 /**
260 * Adds a new employee travel expense line.
261 */
262 public ActionForward addNonEmployeeExpenseLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
263 DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
264 DisbursementVoucherDocument dvDocument = (DisbursementVoucherDocument) dvForm.getDocument();
265
266 DisbursementVoucherNonEmployeeExpense newExpenseLine = dvForm.getNewNonEmployeeExpenseLine();
267
268 // validate line
269 GlobalVariables.getMessageMap().addToErrorPath(KFSPropertyConstants.NEW_NONEMPLOYEE_EXPENSE_LINE);
270 SpringContext.getBean(DictionaryValidationService.class).validateBusinessObject(newExpenseLine);
271
272 // Ensure all fields are filled in before attempting to add a new expense line
273 if (StringUtils.isBlank(newExpenseLine.getDisbVchrPrePaidExpenseCode())) {
274 GlobalVariables.getMessageMap().putError(KFSPropertyConstants.DISB_VCHR_EXPENSE_CODE, KFSKeyConstants.ERROR_DV_EXPENSE_CODE);
275 }
276 if (StringUtils.isBlank(newExpenseLine.getDisbVchrPrePaidExpenseCompanyName())) {
277 GlobalVariables.getMessageMap().putError(KFSPropertyConstants.DISB_VCHR_EXPENSE_COMPANY_NAME, KFSKeyConstants.ERROR_DV_EXPENSE_COMPANY_NAME);
278 }
279 if (ObjectUtils.isNull(newExpenseLine.getDisbVchrExpenseAmount())) {
280 GlobalVariables.getMessageMap().putError(KFSPropertyConstants.DISB_VCHR_EXPENSE_AMOUNT, KFSKeyConstants.ERROR_DV_EXPENSE_AMOUNT);
281 }
282
283 GlobalVariables.getMessageMap().removeFromErrorPath(KFSPropertyConstants.NEW_NONEMPLOYEE_EXPENSE_LINE);
284
285 if (GlobalVariables.getMessageMap().isEmpty()) {
286 dvDocument.getDvNonEmployeeTravel().addDvNonEmployeeExpenseLine(newExpenseLine);
287 dvForm.setNewNonEmployeeExpenseLine(new DisbursementVoucherNonEmployeeExpense());
288 }
289
290 return mapping.findForward(KFSConstants.MAPPING_BASIC);
291 }
292
293 /**
294 * Adds a new employee pre paid travel expense line.
295 */
296 public ActionForward addPrePaidNonEmployeeExpenseLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
297 DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
298 DisbursementVoucherDocument dvDocument = (DisbursementVoucherDocument) dvForm.getDocument();
299
300 DisbursementVoucherNonEmployeeExpense newExpenseLine = dvForm.getNewPrePaidNonEmployeeExpenseLine();
301
302 // validate line
303 GlobalVariables.getMessageMap().addToErrorPath(KFSPropertyConstants.NEW_PREPAID_EXPENSE_LINE);
304 SpringContext.getBean(DictionaryValidationService.class).validateBusinessObject(newExpenseLine);
305
306 // Ensure all fields are filled in before attempting to add a new expense line
307 if (StringUtils.isBlank(newExpenseLine.getDisbVchrPrePaidExpenseCode())) {
308 GlobalVariables.getMessageMap().putError(KFSPropertyConstants.DISB_VCHR_PRE_PAID_EXPENSE_CODE, KFSKeyConstants.ERROR_DV_PREPAID_EXPENSE_CODE);
309 }
310 if (StringUtils.isBlank(newExpenseLine.getDisbVchrPrePaidExpenseCompanyName())) {
311 GlobalVariables.getMessageMap().putError(KFSPropertyConstants.DISB_VCHR_PRE_PAID_EXPENSE_COMPANY_NAME, KFSKeyConstants.ERROR_DV_PREPAID_EXPENSE_COMPANY_NAME);
312 }
313 if (ObjectUtils.isNull(newExpenseLine.getDisbVchrExpenseAmount())) {
314 GlobalVariables.getMessageMap().putError(KFSPropertyConstants.DISB_VCHR_EXPENSE_AMOUNT, KFSKeyConstants.ERROR_DV_PREPAID_EXPENSE_AMOUNT);
315 }
316 GlobalVariables.getMessageMap().removeFromErrorPath(KFSPropertyConstants.NEW_PREPAID_EXPENSE_LINE);
317
318 if (GlobalVariables.getMessageMap().isEmpty()) {
319 dvDocument.getDvNonEmployeeTravel().addDvPrePaidEmployeeExpenseLine(newExpenseLine);
320 dvForm.setNewPrePaidNonEmployeeExpenseLine(new DisbursementVoucherNonEmployeeExpense());
321 }
322
323 return mapping.findForward(KFSConstants.MAPPING_BASIC);
324 }
325
326 /**
327 * Deletes a non employee travel expense line.
328 */
329 public ActionForward deleteNonEmployeeExpenseLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
330 DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
331 DisbursementVoucherDocument dvDocument = (DisbursementVoucherDocument) dvForm.getDocument();
332
333 int deleteIndex = getLineToDelete(request);
334 dvDocument.getDvNonEmployeeTravel().getDvNonEmployeeExpenses().remove(deleteIndex);
335
336 return mapping.findForward(KFSConstants.MAPPING_BASIC);
337 }
338
339 /**
340 * Deletes a pre paid travel expense line.
341 */
342 public ActionForward deletePrePaidEmployeeExpenseLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
343 DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
344 DisbursementVoucherDocument dvDocument = (DisbursementVoucherDocument) dvForm.getDocument();
345
346 int deleteIndex = getLineToDelete(request);
347 dvDocument.getDvNonEmployeeTravel().getDvPrePaidEmployeeExpenses().remove(deleteIndex);
348
349 return mapping.findForward(KFSConstants.MAPPING_BASIC);
350 }
351
352 /**
353 * Adds a new pre conference registrant line.
354 */
355 public ActionForward addPreConfRegistrantLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
356 DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
357 DisbursementVoucherDocument dvDocument = (DisbursementVoucherDocument) dvForm.getDocument();
358
359 DisbursementVoucherPreConferenceRegistrant newRegistrantLine = dvForm.getNewPreConferenceRegistrantLine();
360
361 // validate line
362 GlobalVariables.getMessageMap().addToErrorPath(KFSPropertyConstants.NEW_PRECONF_REGISTRANT_LINE);
363 SpringContext.getBean(DictionaryValidationService.class).validateBusinessObject(newRegistrantLine);
364 GlobalVariables.getMessageMap().removeFromErrorPath(KFSPropertyConstants.NEW_PRECONF_REGISTRANT_LINE);
365
366 if (GlobalVariables.getMessageMap().isEmpty()) {
367 dvDocument.addDvPrePaidRegistrantLine(newRegistrantLine);
368 dvForm.setNewPreConferenceRegistrantLine(new DisbursementVoucherPreConferenceRegistrant());
369 }
370
371 return mapping.findForward(KFSConstants.MAPPING_BASIC);
372 }
373
374 /**
375 * Deletes a pre conference registrant line.
376 */
377 public ActionForward deletePreConfRegistrantLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
378 DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
379 DisbursementVoucherDocument dvDocument = (DisbursementVoucherDocument) dvForm.getDocument();
380
381 int deleteIndex = getLineToDelete(request);
382 dvDocument.getDvPreConferenceDetail().getDvPreConferenceRegistrants().remove(deleteIndex);
383
384 return mapping.findForward(KFSConstants.MAPPING_BASIC);
385 }
386
387 /**
388 * Calls service to generate tax accounting lines and updates nra tax line string in action form.
389 */
390 public ActionForward generateNonResidentAlienTaxLines(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
391 DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
392 DisbursementVoucherDocument document = (DisbursementVoucherDocument) dvForm.getDocument();
393
394 DisbursementVoucherTaxService taxService = SpringContext.getBean(DisbursementVoucherTaxService.class);
395
396 /* call service to generate new tax lines */
397 GlobalVariables.getMessageMap().addToErrorPath("document");
398 taxService.processNonResidentAlienTax(document);
399 GlobalVariables.getMessageMap().removeFromErrorPath("document");
400
401 return mapping.findForward(KFSConstants.MAPPING_BASIC);
402 }
403
404 /**
405 * Calls service to clear tax accounting lines and updates nra tax line string in action form.
406 */
407 public ActionForward clearNonResidentAlienTaxLines(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
408 DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
409 DisbursementVoucherDocument document = (DisbursementVoucherDocument) dvForm.getDocument();
410
411 DisbursementVoucherTaxService taxService = SpringContext.getBean(DisbursementVoucherTaxService.class);
412
413 /* call service to clear previous lines */
414 taxService.clearNRATaxLines(document);
415
416 return mapping.findForward(KFSConstants.MAPPING_BASIC);
417 }
418
419 /**
420 * Builds the wire charge message for the current fiscal year.
421 *
422 * @return the wire charge message for the current fiscal year
423 */
424 protected String retrieveWireChargeMessage() {
425 String message = SpringContext.getBean(KualiConfigurationService.class).getPropertyString(KFSKeyConstants.MESSAGE_DV_WIRE_CHARGE);
426 WireCharge wireCharge = new WireCharge();
427 wireCharge.setUniversityFiscalYear(SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear());
428
429 wireCharge = (WireCharge) SpringContext.getBean(BusinessObjectService.class).retrieve(wireCharge);
430 Object[] args = { wireCharge.getDomesticChargeAmt(), wireCharge.getForeignChargeAmt() };
431
432 return MessageFormat.format(message, args);
433 }
434
435 /**
436 * @see org.kuali.rice.kns.web.struts.action.KualiAction#refresh(org.apache.struts.action.ActionMapping,
437 * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
438 */
439 @Override
440 public ActionForward refresh(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
441 DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
442
443 ActionForward actionAfterPayeeLookup = this.refreshAfterPayeeSelection(mapping, dvForm, request);
444 if (actionAfterPayeeLookup != null) {
445 return actionAfterPayeeLookup;
446 }
447
448 return super.refresh(mapping, form, request, response);
449 }
450
451 // do refresh after a payee is selected
452 protected ActionForward refreshAfterPayeeSelection(ActionMapping mapping, DisbursementVoucherForm dvForm, HttpServletRequest request) {
453 String refreshCaller = dvForm.getRefreshCaller();
454
455 DisbursementVoucherDocument document = (DisbursementVoucherDocument) dvForm.getDocument();
456
457 boolean isPayeeLookupable = KFSConstants.KUALI_DISBURSEMENT_PAYEE_LOOKUPABLE_IMPL.equals(refreshCaller);
458 boolean isAddressLookupable = KFSConstants.KUALI_VENDOR_ADDRESS_LOOKUPABLE_IMPL.equals(refreshCaller);
459
460 // if a cancel occurred on address lookup we need to reset the payee id and type, rest of fields will still have correct information
461 if (refreshCaller == null && hasFullEdit(document)) {
462 dvForm.setPayeeIdNumber(dvForm.getTempPayeeIdNumber());
463 dvForm.setHasMultipleAddresses(false);
464 document.getDvPayeeDetail().setDisbVchrPayeeIdNumber(dvForm.getTempPayeeIdNumber());
465 document.getDvPayeeDetail().setDisbursementVoucherPayeeTypeCode(dvForm.getOldPayeeType());
466
467 return null;
468 }
469
470 // do not execute the further refreshing logic if the refresh caller is not a lookupable
471 if (!isPayeeLookupable && !isAddressLookupable) {
472 return null;
473 }
474
475 // do not execute the further refreshing logic if a payee is not selected
476 String payeeIdNumber = document.getDvPayeeDetail().getDisbVchrPayeeIdNumber();
477 if (payeeIdNumber == null) {
478 return null;
479 }
480
481 dvForm.setPayeeIdNumber(payeeIdNumber);
482 dvForm.setHasMultipleAddresses(false);
483
484 // determine whether the selected vendor has multiple addresses. If so, redirect to the address selection screen
485 if (isPayeeLookupable && dvForm.isVendor()) {
486 VendorDetail refreshVendorDetail = new VendorDetail();
487 refreshVendorDetail.setVendorNumber(payeeIdNumber);
488 refreshVendorDetail = (VendorDetail) SpringContext.getBean(BusinessObjectService.class).retrieve(refreshVendorDetail);
489
490 VendorAddress defaultVendorAddress = null;
491 if (refreshVendorDetail != null) {
492 List<VendorAddress> vendorAddresses = refreshVendorDetail.getVendorAddresses();
493 boolean hasMultipleAddresses = vendorAddresses != null && vendorAddresses.size() > 1;
494 dvForm.setHasMultipleAddresses(hasMultipleAddresses);
495
496 if (vendorAddresses != null) {
497 defaultVendorAddress = vendorAddresses.get(0);
498 }
499 }
500
501 if (dvForm.hasMultipleAddresses()) {
502 return renderVendorAddressSelection(mapping, request, dvForm);
503 }
504 else if (defaultVendorAddress != null) {
505 setupPayeeAsVendor(dvForm, payeeIdNumber, defaultVendorAddress.getVendorAddressGeneratedIdentifier().toString());
506 }
507
508 return null;
509 }
510
511 if (isPayeeLookupable && dvForm.isEmployee()) {
512 this.setupPayeeAsEmployee(dvForm, payeeIdNumber);
513 }
514
515 String payeeAddressIdentifier = request.getParameter(KFSPropertyConstants.VENDOR_ADDRESS_GENERATED_ID);
516 if (isAddressLookupable && StringUtils.isNotBlank(payeeAddressIdentifier)) {
517 setupPayeeAsVendor(dvForm, payeeIdNumber, payeeAddressIdentifier);
518 }
519
520 String paymentReasonCode = document.getDvPayeeDetail().getDisbVchrPaymentReasonCode();
521 addPaymentCodeWarningMessage(dvForm, paymentReasonCode);
522
523 return null;
524 }
525
526 /**
527 * Determines if the current user has full edit permissions on the document, which would allow them to repopulate the payee
528 * @param document the document to check for full edit permissions on
529 * @return true if full edit is allowed on the document, false otherwise
530 */
531 protected boolean hasFullEdit(DisbursementVoucherDocument document) {
532 final Person user = GlobalVariables.getUserSession().getPerson();
533 final TransactionalDocumentPresentationController documentPresentationController = (TransactionalDocumentPresentationController)getDocumentHelperService().getDocumentPresentationController(document);
534 final TransactionalDocumentAuthorizer documentAuthorizer = (TransactionalDocumentAuthorizer)getDocumentHelperService().getDocumentAuthorizer(document);
535 Set<String> documentActions = documentPresentationController.getDocumentActions(document);
536 documentActions = documentAuthorizer.getDocumentActions(document, user, documentActions);
537
538 if (getDataDictionaryService().getDataDictionary().getDocumentEntry(document.getClass().getName()).getUsePessimisticLocking()) {
539 documentActions = getPessimisticLockService().getDocumentActions(document, user, documentActions);
540 }
541
542 Set<String> editModes = documentPresentationController.getEditModes(document);
543 editModes = documentAuthorizer.getEditModes(document, user, editModes);
544
545 return documentActions.contains(KNSConstants.KUALI_ACTION_CAN_EDIT) && editModes.contains("fullEntry");
546 }
547
548 /**
549 * Hook into performLookup to switch the payee lookup based on the payee type selected.
550 */
551 public ActionForward performLookup(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
552 DisbursementVoucherForm dvForm = (DisbursementVoucherForm) form;
553 DisbursementVoucherDocument document = (DisbursementVoucherDocument) dvForm.getDocument();
554
555 return super.performLookup(mapping, form, request, response);
556 }
557
558 /**
559 * render the vendor address lookup results if there are multiple addresses for the selected vendor
560 */
561 protected ActionForward renderVendorAddressSelection(ActionMapping mapping, HttpServletRequest request, DisbursementVoucherForm dvForm) {
562 Properties props = new Properties();
563
564 props.put(KNSConstants.SUPPRESS_ACTIONS, Boolean.toString(true));
565 props.put(KNSConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, VendorAddress.class.getName());
566 props.put(KNSConstants.LOOKUP_ANCHOR, KNSConstants.ANCHOR_TOP_OF_FORM);
567 props.put(KNSConstants.LOOKED_UP_COLLECTION_NAME, KFSPropertyConstants.VENDOR_ADDRESSES);
568
569 String conversionPatttern = "{0}" + KFSConstants.FIELD_CONVERSION_PAIR_SEPERATOR + "{0}";
570 StringBuilder filedConversion = new StringBuilder();
571 filedConversion.append(MessageFormat.format(conversionPatttern, KFSPropertyConstants.VENDOR_ADDRESS_GENERATED_ID)).append(KFSConstants.FIELD_CONVERSIONS_SEPERATOR);
572 filedConversion.append(MessageFormat.format(conversionPatttern, KFSPropertyConstants.VENDOR_HEADER_GENERATED_ID)).append(KFSConstants.FIELD_CONVERSIONS_SEPERATOR);
573 filedConversion.append(MessageFormat.format(conversionPatttern, KFSPropertyConstants.VENDOR_DETAIL_ASSIGNED_ID));
574 props.put(KNSConstants.CONVERSION_FIELDS_PARAMETER, filedConversion);
575
576 props.put(KFSPropertyConstants.VENDOR_HEADER_GENERATED_ID, dvForm.getVendorHeaderGeneratedIdentifier());
577 props.put(KFSPropertyConstants.VENDOR_DETAIL_ASSIGNED_ID, dvForm.getVendorDetailAssignedIdentifier());
578 props.put(KFSPropertyConstants.ACTIVE, KFSConstants.ACTIVE_INDICATOR);
579
580 props.put(KNSConstants.RETURN_LOCATION_PARAMETER, this.getReturnLocation(request, mapping));
581 props.put(KNSConstants.BACK_LOCATION, this.getReturnLocation(request, mapping));
582
583 props.put(KNSConstants.LOOKUP_AUTO_SEARCH, "Yes");
584 props.put(KNSConstants.DISPATCH_REQUEST_PARAMETER, KFSConstants.SEARCH_METHOD);
585
586 props.put(KNSConstants.DOC_FORM_KEY, GlobalVariables.getUserSession().addObject(dvForm));
587 props.put(KNSConstants.DOC_NUM, dvForm.getDocument().getDocumentNumber());
588
589 // TODO: how should this forward be handled
590 String url = UrlFactory.parameterizeUrl(getBasePath(request) + "/kr/" + KNSConstants.LOOKUP_ACTION, props);
591
592 dvForm.registerEditableProperty("methodToCall");
593
594 return new ActionForward(url, true);
595 }
596
597 /**
598 * setup the payee as an employee with the given id number
599 */
600 protected void setupPayeeAsEmployee(DisbursementVoucherForm dvForm, String payeeIdNumber) {
601 Person person = (Person) SpringContext.getBean(PersonService.class).getPersonByEmployeeId(payeeIdNumber);
602 if (person != null) {
603 ((DisbursementVoucherDocument) dvForm.getDocument()).templateEmployee(person);
604 dvForm.setTempPayeeIdNumber(payeeIdNumber);
605 dvForm.setOldPayeeType(DisbursementVoucherConstants.DV_PAYEE_TYPE_EMPLOYEE);
606
607 }
608 else {
609 LOG.error("Exception while attempting to retrieve universal user by universal user id " + payeeIdNumber);
610 }
611 }
612
613 /**
614 * setup the payee as a vendor with the given id number and address id
615 */
616 protected void setupPayeeAsVendor(DisbursementVoucherForm dvForm, String payeeIdNumber, String payeeAddressIdentifier) {
617 VendorDetail vendorDetail = new VendorDetail();
618 vendorDetail.setVendorNumber(payeeIdNumber);
619 vendorDetail = (VendorDetail) SpringContext.getBean(BusinessObjectService.class).retrieve(vendorDetail);
620
621 VendorAddress vendorAddress = new VendorAddress();
622 if (StringUtils.isNotBlank(payeeAddressIdentifier)) {
623 try {
624 vendorAddress.setVendorAddressGeneratedIdentifier(new Integer(payeeAddressIdentifier));
625 vendorAddress = (VendorAddress) SpringContext.getBean(BusinessObjectService.class).retrieve(vendorAddress);
626 dvForm.setTempPayeeIdNumber(payeeIdNumber);
627 dvForm.setOldPayeeType(DisbursementVoucherConstants.DV_PAYEE_TYPE_VENDOR);
628
629 }
630 catch (Exception e) {
631 LOG.error("Exception while attempting to retrieve vendor address for vendor address id " + payeeAddressIdentifier + ": " + e);
632 }
633 }
634
635 ((DisbursementVoucherDocument) dvForm.getDocument()).templateVendor(vendorDetail, vendorAddress);
636 }
637
638 /**
639 * add warning message based on the given reason code
640 */
641 protected void addPaymentCodeWarningMessage(DisbursementVoucherForm dvForm, String paymentReasonCode) {
642 // clear up the warning message and tab state carried from previous screen
643 for (String tabKey : TabByReasonCode.getAllTabKeys()) {
644 dvForm.getTabStates().remove(tabKey);
645 }
646
647 for (String propertyKey : TabByReasonCode.getAllDocumentPropertyKeys()) {
648 GlobalVariables.getMessageMap().removeAllWarningMessagesForProperty(propertyKey);
649 }
650
651 String reasonCodeProperty = KFSPropertyConstants.DOCUMENT + "." + KFSPropertyConstants.DV_PAYEE_DETAIL + "." + KFSPropertyConstants.DISB_VCHR_PAYMENT_REASON_CODE;
652 GlobalVariables.getMessageMap().removeAllWarningMessagesForProperty(reasonCodeProperty);
653
654 // add warning message and reset tab state as open if any
655 TabByReasonCode tab = TabByReasonCode.getTabByReasonCode(paymentReasonCode);
656 if (tab != null) {
657 dvForm.getTabStates().put(tab.tabKey, "OPEN");
658 GlobalVariables.getMessageMap().putWarning(reasonCodeProperty, tab.messageKey);
659 GlobalVariables.getMessageMap().putWarning(tab.getDocumentPropertyKey(), tab.messageKey);
660 }
661 }
662
663
664
665 }