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 }