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 017 package org.kuali.kfs.fp.document; 018 019 import static org.kuali.kfs.sys.KFSConstants.GL_CREDIT_CODE; 020 import static org.kuali.kfs.sys.KFSConstants.GL_DEBIT_CODE; 021 022 import java.sql.Date; 023 import java.sql.Timestamp; 024 import java.text.MessageFormat; 025 import java.util.ArrayList; 026 import java.util.Arrays; 027 import java.util.Calendar; 028 import java.util.List; 029 030 import org.apache.commons.lang.StringUtils; 031 import org.apache.log4j.Logger; 032 import org.kuali.kfs.coa.businessobject.ObjectCode; 033 import org.kuali.kfs.coa.service.ObjectTypeService; 034 import org.kuali.kfs.fp.businessobject.DisbursementVoucherDocumentationLocation; 035 import org.kuali.kfs.fp.businessobject.DisbursementVoucherNonEmployeeTravel; 036 import org.kuali.kfs.fp.businessobject.DisbursementVoucherNonResidentAlienTax; 037 import org.kuali.kfs.fp.businessobject.DisbursementVoucherPayeeDetail; 038 import org.kuali.kfs.fp.businessobject.DisbursementVoucherPreConferenceDetail; 039 import org.kuali.kfs.fp.businessobject.DisbursementVoucherPreConferenceRegistrant; 040 import org.kuali.kfs.fp.businessobject.DisbursementVoucherWireTransfer; 041 import org.kuali.kfs.fp.businessobject.WireCharge; 042 import org.kuali.kfs.fp.businessobject.options.DisbursementVoucherDocumentationLocationValuesFinder; 043 import org.kuali.kfs.fp.businessobject.options.PaymentMethodValuesFinder; 044 import org.kuali.kfs.fp.document.service.DisbursementVoucherPayeeService; 045 import org.kuali.kfs.fp.document.service.DisbursementVoucherPaymentReasonService; 046 import org.kuali.kfs.fp.document.service.DisbursementVoucherTaxService; 047 import org.kuali.kfs.sys.KFSConstants; 048 import org.kuali.kfs.sys.KFSKeyConstants; 049 import org.kuali.kfs.sys.KFSPropertyConstants; 050 import org.kuali.kfs.sys.KFSConstants.AdHocPaymentIndicator; 051 import org.kuali.kfs.sys.businessobject.AccountingLine; 052 import org.kuali.kfs.sys.businessobject.Bank; 053 import org.kuali.kfs.sys.businessobject.ChartOrgHolder; 054 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntry; 055 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper; 056 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail; 057 import org.kuali.kfs.sys.context.SpringContext; 058 import org.kuali.kfs.sys.document.AccountingDocumentBase; 059 import org.kuali.kfs.sys.document.AmountTotaling; 060 import org.kuali.kfs.sys.document.service.AccountingDocumentRuleHelperService; 061 import org.kuali.kfs.sys.document.service.DebitDeterminerService; 062 import org.kuali.kfs.sys.document.validation.impl.AccountingDocumentRuleBaseConstants.GENERAL_LEDGER_PENDING_ENTRY_CODE; 063 import org.kuali.kfs.sys.service.BankService; 064 import org.kuali.kfs.sys.service.FlexibleOffsetAccountService; 065 import org.kuali.kfs.sys.service.GeneralLedgerPendingEntryService; 066 import org.kuali.kfs.sys.service.HomeOriginationService; 067 import org.kuali.kfs.sys.service.OptionsService; 068 import org.kuali.kfs.sys.service.UniversityDateService; 069 import org.kuali.kfs.vnd.VendorConstants; 070 import org.kuali.kfs.vnd.businessobject.VendorAddress; 071 import org.kuali.kfs.vnd.businessobject.VendorDetail; 072 import org.kuali.kfs.vnd.document.service.VendorService; 073 import org.kuali.rice.kew.exception.WorkflowException; 074 import org.kuali.rice.kim.bo.Person; 075 import org.kuali.rice.kim.bo.entity.KimEntityAddress; 076 import org.kuali.rice.kim.bo.entity.KimEntityEntityType; 077 import org.kuali.rice.kim.bo.entity.dto.KimEntityEntityTypeInfo; 078 import org.kuali.rice.kim.bo.entity.dto.KimEntityInfo; 079 import org.kuali.rice.kim.service.IdentityManagementService; 080 import org.kuali.rice.kim.service.PersonService; 081 import org.kuali.rice.kim.util.KimConstants; 082 import org.kuali.rice.kns.bo.DocumentHeader; 083 import org.kuali.rice.kns.document.Copyable; 084 import org.kuali.rice.kns.service.BusinessObjectService; 085 import org.kuali.rice.kns.service.DateTimeService; 086 import org.kuali.rice.kns.service.KualiConfigurationService; 087 import org.kuali.rice.kns.service.ParameterEvaluator; 088 import org.kuali.rice.kns.service.ParameterService; 089 import org.kuali.rice.kns.util.GlobalVariables; 090 import org.kuali.rice.kns.util.KNSConstants; 091 import org.kuali.rice.kns.util.KualiDecimal; 092 import org.kuali.rice.kns.util.ObjectUtils; 093 094 /** 095 * This is the business object that represents the DisbursementVoucher document in Kuali. 096 */ 097 public class DisbursementVoucherDocument extends AccountingDocumentBase implements Copyable, AmountTotaling { 098 protected static Logger LOG = Logger.getLogger(DisbursementVoucherDocument.class); 099 100 protected static final String PAYEE_IS_PURCHASE_ORDER_VENDOR_SPLIT = "PayeeIsPurchaseOrderVendor"; 101 protected static final String PURCHASE_ORDER_VENDOR_TYPE = "PO"; 102 protected static final String DOCUMENT_REQUIRES_TAX_REVIEW_SPLIT = "RequiresTaxReview"; 103 protected static final String DOCUMENT_REQUIRES_TRAVEL_REVIEW_SPLIT = "RequiresTravelReview"; 104 105 protected static final String PAYMENT_REASONS_REQUIRING_TAX_REVIEW_PARAMETER_NAME = "PAYMENT_REASONS_REQUIRING_TAX_REVIEW"; 106 protected static final String USE_DEFAULT_EMPLOYEE_ADDRESS_PARAMETER_NAME = "USE_DEFAULT_EMPLOYEE_ADDRESS_IND"; 107 protected static final String DEFAULT_EMPLOYEE_ADDRESS_TYPE_PARAMETER_NAME = "DEFAULT_EMPLOYEE_ADDRESS_TYPE"; 108 109 protected static final String TAX_CONTROL_BACKUP_HOLDING = "B"; 110 protected static final String TAX_CONTROL_HOLD_PAYMENTS = "H"; 111 112 protected static transient PersonService<Person> personService; 113 protected static transient ParameterService parameterService; 114 protected static transient VendorService vendorService; 115 protected static transient BusinessObjectService businessObjectService; 116 protected static transient DateTimeService dateTimeService; 117 protected static transient DisbursementVoucherPaymentReasonService dvPymentReasonService; 118 protected static transient IdentityManagementService identityManagementService; 119 120 protected Integer finDocNextRegistrantLineNbr; 121 protected String disbVchrContactPersonName; 122 protected String disbVchrContactPhoneNumber; 123 protected String disbVchrContactEmailId; 124 protected Date disbursementVoucherDueDate; 125 protected boolean disbVchrAttachmentCode; 126 protected boolean disbVchrSpecialHandlingCode; 127 protected KualiDecimal disbVchrCheckTotalAmount; 128 protected boolean disbVchrForeignCurrencyInd; 129 protected String disbursementVoucherDocumentationLocationCode; 130 protected String disbVchrCheckStubText; 131 protected boolean dvCheckStubOverflowCode; 132 protected String campusCode; 133 protected String disbVchrPayeeTaxControlCode; 134 protected boolean disbVchrPayeeChangedInd; 135 protected String disbursementVoucherCheckNbr; 136 protected Timestamp disbursementVoucherCheckDate; 137 protected boolean disbVchrPayeeW9CompleteCode; 138 protected String disbVchrPaymentMethodCode; 139 protected boolean exceptionIndicator; 140 protected boolean disbExcptAttachedIndicator; 141 protected Date extractDate; 142 protected Date paidDate; 143 protected Date cancelDate; 144 protected String disbVchrBankCode; 145 protected String disbVchrPdpBankCode; 146 147 protected boolean payeeAssigned = false; 148 protected boolean editW9W8BENbox = false; 149 150 151 protected DocumentHeader financialDocument; 152 protected DisbursementVoucherDocumentationLocation disbVchrDocumentationLoc; 153 protected DisbursementVoucherNonEmployeeTravel dvNonEmployeeTravel; 154 protected DisbursementVoucherNonResidentAlienTax dvNonResidentAlienTax; 155 protected DisbursementVoucherPayeeDetail dvPayeeDetail; 156 protected DisbursementVoucherPreConferenceDetail dvPreConferenceDetail; 157 protected DisbursementVoucherWireTransfer dvWireTransfer; 158 159 protected Bank bank; 160 161 /** 162 * Default no-arg constructor. 163 */ 164 public DisbursementVoucherDocument() { 165 super(); 166 exceptionIndicator = false; 167 finDocNextRegistrantLineNbr = new Integer(1); 168 dvNonEmployeeTravel = new DisbursementVoucherNonEmployeeTravel(); 169 dvNonResidentAlienTax = new DisbursementVoucherNonResidentAlienTax(); 170 dvPayeeDetail = new DisbursementVoucherPayeeDetail(); 171 dvPreConferenceDetail = new DisbursementVoucherPreConferenceDetail(); 172 dvWireTransfer = new DisbursementVoucherWireTransfer(); 173 disbVchrCheckTotalAmount = KualiDecimal.ZERO; 174 bank = new Bank(); 175 } 176 177 178 /** 179 * @see org.kuali.kfs.sys.document.AccountingDocumentBase#getPendingLedgerEntriesForSufficientFundsChecking() 180 */ 181 @Override 182 public List<GeneralLedgerPendingEntry> getPendingLedgerEntriesForSufficientFundsChecking() { 183 List<GeneralLedgerPendingEntry> ples = new ArrayList<GeneralLedgerPendingEntry>(); 184 185 KualiConfigurationService kualiConfigurationService = SpringContext.getBean(KualiConfigurationService.class); 186 FlexibleOffsetAccountService flexibleOffsetAccountService = SpringContext.getBean(FlexibleOffsetAccountService.class); 187 188 ObjectTypeService objectTypeService = (ObjectTypeService) SpringContext.getBean(ObjectTypeService.class); 189 190 for (GeneralLedgerPendingEntry ple : this.getGeneralLedgerPendingEntries()) { 191 List<String> expenseObjectTypes = objectTypeService.getExpenseObjectTypes(ple.getUniversityFiscalYear()); 192 if (expenseObjectTypes.contains(ple.getFinancialObjectTypeCode())) { 193 // is an expense object type, keep checking 194 ple.refreshNonUpdateableReferences(); 195 if (ple.getAccount().isPendingAcctSufficientFundsIndicator() && ple.getAccount().getAccountSufficientFundsCode().equals(KFSConstants.SF_TYPE_CASH_AT_ACCOUNT)) { 196 // is a cash account 197 if (flexibleOffsetAccountService.getByPrimaryIdIfEnabled(ple.getChartOfAccountsCode(), ple.getAccountNumber(), ple.getChart().getFinancialCashObjectCode()) == null && flexibleOffsetAccountService.getByPrimaryIdIfEnabled(ple.getChartOfAccountsCode(), ple.getAccountNumber(), ple.getChart().getFinAccountsPayableObjectCode()) == null) { 198 // does not have a flexible offset for cash or liability, set the object code to cash and add to list of 199 // PLEs to check for SF 200 201 ple = new GeneralLedgerPendingEntry(ple); 202 ple.setFinancialObjectCode(ple.getChart().getFinancialCashObjectCode()); 203 ple.setTransactionDebitCreditCode(ple.getTransactionDebitCreditCode().equals(KFSConstants.GL_DEBIT_CODE) ? KFSConstants.GL_CREDIT_CODE : KFSConstants.GL_DEBIT_CODE); 204 ples.add(ple); 205 } 206 207 } 208 else { 209 // is not a cash account, process as normal 210 ples.add(ple); 211 } 212 } 213 } 214 215 return ples; 216 } 217 218 219 /** 220 * Gets the finDocNextRegistrantLineNbr attribute. 221 * 222 * @return Returns the finDocNextRegistrantLineNbr 223 */ 224 public Integer getFinDocNextRegistrantLineNbr() { 225 return finDocNextRegistrantLineNbr; 226 } 227 228 229 /** 230 * Sets the finDocNextRegistrantLineNbr attribute. 231 * 232 * @param finDocNextRegistrantLineNbr The finDocNextRegistrantLineNbr to set. 233 */ 234 public void setFinDocNextRegistrantLineNbr(Integer finDocNextRegistrantLineNbr) { 235 this.finDocNextRegistrantLineNbr = finDocNextRegistrantLineNbr; 236 } 237 238 /** 239 * Gets the disbVchrContactPersonName attribute. 240 * 241 * @return Returns the disbVchrContactPersonName 242 */ 243 public String getDisbVchrContactPersonName() { 244 return disbVchrContactPersonName; 245 } 246 247 248 /** 249 * Sets the disbVchrContactPersonName attribute. 250 * 251 * @param disbVchrContactPersonName The disbVchrContactPersonName to set. 252 */ 253 public void setDisbVchrContactPersonName(String disbVchrContactPersonName) { 254 this.disbVchrContactPersonName = disbVchrContactPersonName; 255 } 256 257 /** 258 * Gets the disbVchrContactPhoneNumber attribute. 259 * 260 * @return Returns the disbVchrContactPhoneNumber 261 */ 262 public String getDisbVchrContactPhoneNumber() { 263 return disbVchrContactPhoneNumber; 264 } 265 266 267 /** 268 * Sets the disbVchrContactPhoneNumber attribute. 269 * 270 * @param disbVchrContactPhoneNumber The disbVchrContactPhoneNumber to set. 271 */ 272 public void setDisbVchrContactPhoneNumber(String disbVchrContactPhoneNumber) { 273 this.disbVchrContactPhoneNumber = disbVchrContactPhoneNumber; 274 } 275 276 /** 277 * Gets the disbVchrContactEmailId attribute. 278 * 279 * @return Returns the disbVchrContactEmailId 280 */ 281 public String getDisbVchrContactEmailId() { 282 return disbVchrContactEmailId; 283 } 284 285 286 /** 287 * Sets the disbVchrContactEmailId attribute. 288 * 289 * @param disbVchrContactEmailId The disbVchrContactEmailId to set. 290 */ 291 public void setDisbVchrContactEmailId(String disbVchrContactEmailId) { 292 this.disbVchrContactEmailId = disbVchrContactEmailId; 293 } 294 295 /** 296 * Gets the disbursementVoucherDueDate attribute. 297 * 298 * @return Returns the disbursementVoucherDueDate 299 */ 300 public Date getDisbursementVoucherDueDate() { 301 return disbursementVoucherDueDate; 302 } 303 304 305 /** 306 * Sets the disbursementVoucherDueDate attribute. 307 * 308 * @param disbursementVoucherDueDate The disbursementVoucherDueDate to set. 309 */ 310 public void setDisbursementVoucherDueDate(Date disbursementVoucherDueDate) { 311 this.disbursementVoucherDueDate = disbursementVoucherDueDate; 312 } 313 314 /** 315 * Gets the disbVchrAttachmentCode attribute. 316 * 317 * @return Returns the disbVchrAttachmentCode 318 */ 319 public boolean isDisbVchrAttachmentCode() { 320 return disbVchrAttachmentCode; 321 } 322 323 324 /** 325 * Sets the disbVchrAttachmentCode attribute. 326 * 327 * @param disbVchrAttachmentCode The disbVchrAttachmentCode to set. 328 */ 329 public void setDisbVchrAttachmentCode(boolean disbVchrAttachmentCode) { 330 this.disbVchrAttachmentCode = disbVchrAttachmentCode; 331 } 332 333 /** 334 * Gets the disbVchrSpecialHandlingCode attribute. 335 * 336 * @return Returns the disbVchrSpecialHandlingCode 337 */ 338 public boolean isDisbVchrSpecialHandlingCode() { 339 return disbVchrSpecialHandlingCode; 340 } 341 342 343 /** 344 * Sets the disbVchrSpecialHandlingCode attribute. 345 * 346 * @param disbVchrSpecialHandlingCode The disbVchrSpecialHandlingCode to set. 347 */ 348 public void setDisbVchrSpecialHandlingCode(boolean disbVchrSpecialHandlingCode) { 349 this.disbVchrSpecialHandlingCode = disbVchrSpecialHandlingCode; 350 } 351 352 /** 353 * Gets the disbVchrCheckTotalAmount attribute. 354 * 355 * @return Returns the disbVchrCheckTotalAmount 356 */ 357 public KualiDecimal getDisbVchrCheckTotalAmount() { 358 return disbVchrCheckTotalAmount; 359 } 360 361 362 /** 363 * Sets the disbVchrCheckTotalAmount attribute. 364 * 365 * @param disbVchrCheckTotalAmount The disbVchrCheckTotalAmount to set. 366 */ 367 public void setDisbVchrCheckTotalAmount(KualiDecimal disbVchrCheckTotalAmount) { 368 if (disbVchrCheckTotalAmount != null) { 369 this.disbVchrCheckTotalAmount = disbVchrCheckTotalAmount; 370 } 371 } 372 373 /** 374 * Gets the disbVchrForeignCurrencyInd attribute. 375 * 376 * @return Returns the disbVchrForeignCurrencyInd 377 */ 378 public boolean isDisbVchrForeignCurrencyInd() { 379 return disbVchrForeignCurrencyInd; 380 } 381 382 383 /** 384 * Sets the disbVchrForeignCurrencyInd attribute. 385 * 386 * @param disbVchrForeignCurrencyInd The disbVchrForeignCurrencyInd to set. 387 */ 388 public void setDisbVchrForeignCurrencyInd(boolean disbVchrForeignCurrencyInd) { 389 this.disbVchrForeignCurrencyInd = disbVchrForeignCurrencyInd; 390 } 391 392 /** 393 * Gets the disbursementVoucherDocumentationLocationCode attribute. 394 * 395 * @return Returns the disbursementVoucherDocumentationLocationCode 396 */ 397 public String getDisbursementVoucherDocumentationLocationCode() { 398 return disbursementVoucherDocumentationLocationCode; 399 } 400 401 402 /** 403 * Sets the disbursementVoucherDocumentationLocationCode attribute. 404 * 405 * @param disbursementVoucherDocumentationLocationCode The disbursementVoucherDocumentationLocationCode to set. 406 */ 407 public void setDisbursementVoucherDocumentationLocationCode(String disbursementVoucherDocumentationLocationCode) { 408 this.disbursementVoucherDocumentationLocationCode = disbursementVoucherDocumentationLocationCode; 409 } 410 411 /** 412 * Gets the disbVchrCheckStubText attribute. 413 * 414 * @return Returns the disbVchrCheckStubText 415 */ 416 public String getDisbVchrCheckStubText() { 417 return disbVchrCheckStubText; 418 } 419 420 421 /** 422 * Sets the disbVchrCheckStubText attribute. 423 * 424 * @param disbVchrCheckStubText The disbVchrCheckStubText to set. 425 */ 426 public void setDisbVchrCheckStubText(String disbVchrCheckStubText) { 427 this.disbVchrCheckStubText = disbVchrCheckStubText; 428 } 429 430 /** 431 * Gets the dvCheckStubOverflowCode attribute. 432 * 433 * @return Returns the dvCheckStubOverflowCode 434 */ 435 public boolean getDvCheckStubOverflowCode() { 436 return dvCheckStubOverflowCode; 437 } 438 439 440 /** 441 * Sets the dvCheckStubOverflowCode attribute. 442 * 443 * @param dvCheckStubOverflowCode The dvCheckStubOverflowCode to set. 444 */ 445 public void setDvCheckStubOverflowCode(boolean dvCheckStubOverflowCode) { 446 this.dvCheckStubOverflowCode = dvCheckStubOverflowCode; 447 } 448 449 /** 450 * Gets the campusCode attribute. 451 * 452 * @return Returns the campusCode 453 */ 454 public String getCampusCode() { 455 return campusCode; 456 } 457 458 459 /** 460 * Sets the campusCode attribute. 461 * 462 * @param campusCode The campusCode to set. 463 */ 464 public void setCampusCode(String campusCode) { 465 this.campusCode = campusCode; 466 } 467 468 /** 469 * Gets the disbVchrPayeeTaxControlCode attribute. 470 * 471 * @return Returns the disbVchrPayeeTaxControlCode 472 */ 473 public String getDisbVchrPayeeTaxControlCode() { 474 return disbVchrPayeeTaxControlCode; 475 } 476 477 478 /** 479 * Sets the disbVchrPayeeTaxControlCode attribute. 480 * 481 * @param disbVchrPayeeTaxControlCode The disbVchrPayeeTaxControlCode to set. 482 */ 483 public void setDisbVchrPayeeTaxControlCode(String disbVchrPayeeTaxControlCode) { 484 this.disbVchrPayeeTaxControlCode = disbVchrPayeeTaxControlCode; 485 } 486 487 /** 488 * Gets the disbVchrPayeeChangedInd attribute. 489 * 490 * @return Returns the disbVchrPayeeChangedInd 491 */ 492 public boolean isDisbVchrPayeeChangedInd() { 493 return disbVchrPayeeChangedInd; 494 } 495 496 497 /** 498 * Sets the disbVchrPayeeChangedInd attribute. 499 * 500 * @param disbVchrPayeeChangedInd The disbVchrPayeeChangedInd to set. 501 */ 502 public void setDisbVchrPayeeChangedInd(boolean disbVchrPayeeChangedInd) { 503 this.disbVchrPayeeChangedInd = disbVchrPayeeChangedInd; 504 } 505 506 /** 507 * Gets the disbursementVoucherCheckNbr attribute. 508 * 509 * @return Returns the disbursementVoucherCheckNbr 510 */ 511 public String getDisbursementVoucherCheckNbr() { 512 return disbursementVoucherCheckNbr; 513 } 514 515 516 /** 517 * Sets the disbursementVoucherCheckNbr attribute. 518 * 519 * @param disbursementVoucherCheckNbr The disbursementVoucherCheckNbr to set. 520 */ 521 public void setDisbursementVoucherCheckNbr(String disbursementVoucherCheckNbr) { 522 this.disbursementVoucherCheckNbr = disbursementVoucherCheckNbr; 523 } 524 525 /** 526 * Gets the disbursementVoucherCheckDate attribute. 527 * 528 * @return Returns the disbursementVoucherCheckDate 529 */ 530 public Timestamp getDisbursementVoucherCheckDate() { 531 return disbursementVoucherCheckDate; 532 } 533 534 535 /** 536 * Sets the disbursementVoucherCheckDate attribute. 537 * 538 * @param disbursementVoucherCheckDate The disbursementVoucherCheckDate to set. 539 */ 540 public void setDisbursementVoucherCheckDate(Timestamp disbursementVoucherCheckDate) { 541 this.disbursementVoucherCheckDate = disbursementVoucherCheckDate; 542 } 543 544 /** 545 * Gets the disbVchrPayeeW9CompleteCode attribute. 546 * 547 * @return Returns the disbVchrPayeeW9CompleteCode 548 */ 549 public boolean getDisbVchrPayeeW9CompleteCode() { 550 return disbVchrPayeeW9CompleteCode; 551 } 552 553 554 /** 555 * Sets the disbVchrPayeeW9CompleteCode attribute. 556 * 557 * @param disbVchrPayeeW9CompleteCode The disbVchrPayeeW9CompleteCode to set. 558 */ 559 public void setDisbVchrPayeeW9CompleteCode(boolean disbVchrPayeeW9CompleteCode) { 560 this.disbVchrPayeeW9CompleteCode = disbVchrPayeeW9CompleteCode; 561 } 562 563 /** 564 * Gets the disbVchrPaymentMethodCode attribute. 565 * 566 * @return Returns the disbVchrPaymentMethodCode 567 */ 568 public String getDisbVchrPaymentMethodCode() { 569 return disbVchrPaymentMethodCode; 570 } 571 572 573 /** 574 * Sets the disbVchrPaymentMethodCode attribute. 575 * 576 * @param disbVchrPaymentMethodCode The disbVchrPaymentMethodCode to set. 577 */ 578 public void setDisbVchrPaymentMethodCode(String disbVchrPaymentMethodCode) { 579 this.disbVchrPaymentMethodCode = disbVchrPaymentMethodCode; 580 } 581 582 /** 583 * Gets the financialDocument attribute. 584 * 585 * @return Returns the financialDocument 586 */ 587 public DocumentHeader getFinancialDocument() { 588 return financialDocument; 589 } 590 591 592 /** 593 * Sets the financialDocument attribute. 594 * 595 * @param financialDocument The financialDocument to set. 596 * @deprecated 597 */ 598 public void setFinancialDocument(DocumentHeader financialDocument) { 599 this.financialDocument = financialDocument; 600 } 601 602 /** 603 * Gets the disbVchrDocumentationLoc attribute. 604 * 605 * @return Returns the disbVchrDocumentationLoc 606 */ 607 public DisbursementVoucherDocumentationLocation getDisbVchrDocumentationLoc() { 608 return disbVchrDocumentationLoc; 609 } 610 611 612 /** 613 * Sets the disbVchrDocumentationLoc attribute. 614 * 615 * @param disbVchrDocumentationLoc The disbVchrDocumentationLoc to set. 616 * @deprecated 617 */ 618 public void setDisbVchrDocumentationLoc(DisbursementVoucherDocumentationLocation disbVchrDocumentationLoc) { 619 this.disbVchrDocumentationLoc = disbVchrDocumentationLoc; 620 } 621 622 623 /** 624 * @return Returns the dvNonEmployeeTravel. 625 */ 626 public DisbursementVoucherNonEmployeeTravel getDvNonEmployeeTravel() { 627 return dvNonEmployeeTravel; 628 } 629 630 /** 631 * @param dvNonEmployeeTravel The dvNonEmployeeTravel to set. 632 */ 633 public void setDvNonEmployeeTravel(DisbursementVoucherNonEmployeeTravel dvNonEmployeeTravel) { 634 this.dvNonEmployeeTravel = dvNonEmployeeTravel; 635 } 636 637 /** 638 * @return Returns the dvNonResidentAlienTax. 639 */ 640 public DisbursementVoucherNonResidentAlienTax getDvNonResidentAlienTax() { 641 return dvNonResidentAlienTax; 642 } 643 644 /** 645 * @param dvNonResidentAlienTax The dvNonResidentAlienTax to set. 646 */ 647 public void setDvNonResidentAlienTax(DisbursementVoucherNonResidentAlienTax dvNonResidentAlienTax) { 648 this.dvNonResidentAlienTax = dvNonResidentAlienTax; 649 } 650 651 /** 652 * @return Returns the dvPayeeDetail. 653 */ 654 public DisbursementVoucherPayeeDetail getDvPayeeDetail() { 655 return dvPayeeDetail; 656 } 657 658 /** 659 * @param dvPayeeDetail The dvPayeeDetail to set. 660 */ 661 public void setDvPayeeDetail(DisbursementVoucherPayeeDetail dvPayeeDetail) { 662 this.dvPayeeDetail = dvPayeeDetail; 663 } 664 665 /** 666 * @return Returns the dvPreConferenceDetail. 667 */ 668 public DisbursementVoucherPreConferenceDetail getDvPreConferenceDetail() { 669 return dvPreConferenceDetail; 670 } 671 672 /** 673 * @param dvPreConferenceDetail The dvPreConferenceDetail to set. 674 */ 675 public void setDvPreConferenceDetail(DisbursementVoucherPreConferenceDetail dvPreConferenceDetail) { 676 this.dvPreConferenceDetail = dvPreConferenceDetail; 677 } 678 679 /** 680 * @return Returns the dvWireTransfer. 681 */ 682 public DisbursementVoucherWireTransfer getDvWireTransfer() { 683 return dvWireTransfer; 684 } 685 686 /** 687 * @param dvWireTransfer The dvWireTransfer to set. 688 */ 689 public void setDvWireTransfer(DisbursementVoucherWireTransfer dvWireTransfer) { 690 this.dvWireTransfer = dvWireTransfer; 691 } 692 693 /** 694 * @return Returns the exceptionIndicator. 695 */ 696 public boolean isExceptionIndicator() { 697 return exceptionIndicator; 698 } 699 700 /** 701 * @param exceptionIndicator The exceptionIndicator to set. 702 */ 703 public void setExceptionIndicator(boolean exceptionIndicator) { 704 this.exceptionIndicator = exceptionIndicator; 705 } 706 707 /** 708 * Gets the cancelDate attribute. 709 * 710 * @return Returns the cancelDate. 711 */ 712 public Date getCancelDate() { 713 return cancelDate; 714 } 715 716 /** 717 * Sets the cancelDate attribute value. 718 * 719 * @param cancelDate The cancelDate to set. 720 */ 721 public void setCancelDate(Date cancelDate) { 722 this.cancelDate = cancelDate; 723 } 724 725 /** 726 * Gets the extractDate attribute. 727 * 728 * @return Returns the extractDate. 729 */ 730 public Date getExtractDate() { 731 return extractDate; 732 } 733 734 /** 735 * Sets the extractDate attribute value. 736 * 737 * @param extractDate The extractDate to set. 738 */ 739 public void setExtractDate(Date extractDate) { 740 this.extractDate = extractDate; 741 } 742 743 /** 744 * Gets the paidDate attribute. 745 * 746 * @return Returns the paidDate. 747 */ 748 public Date getPaidDate() { 749 return paidDate; 750 } 751 752 /** 753 * Sets the paidDate attribute value. 754 * 755 * @param paidDate The paidDate to set. 756 */ 757 public void setPaidDate(Date paidDate) { 758 this.paidDate = paidDate; 759 } 760 761 /** 762 * Based on which pdp dates are present (extract, paid, canceled), determines a String for the status 763 * 764 * @return a String representation of the status 765 */ 766 public String getDisbursementVoucherPdpStatus() { 767 if (cancelDate != null) { 768 return "Canceled"; 769 } 770 else if (paidDate != null) { 771 return "Paid"; 772 } 773 else if (extractDate != null) { 774 return "Extracted"; 775 } 776 else { 777 return "Pre-Extraction"; 778 } 779 } 780 781 /** 782 * Pretends to set the PDP status for this document 783 * 784 * @param status the status to pretend to set 785 */ 786 public void setDisbursementVoucherPdpStatus(String status) { 787 // don't do nothing, 'cause this ain't a real field 788 } 789 790 /** 791 * Adds a dv pre-paid registrant line 792 * 793 * @param line 794 */ 795 public void addDvPrePaidRegistrantLine(DisbursementVoucherPreConferenceRegistrant line) { 796 line.setFinancialDocumentLineNumber(getFinDocNextRegistrantLineNbr()); 797 this.getDvPreConferenceDetail().getDvPreConferenceRegistrants().add(line); 798 this.finDocNextRegistrantLineNbr = new Integer(getFinDocNextRegistrantLineNbr().intValue() + 1); 799 } 800 801 /** 802 * Returns the name associated with the payment method code 803 * 804 * @return String 805 */ 806 public String getDisbVchrPaymentMethodName() { 807 return new PaymentMethodValuesFinder().getKeyLabel(disbVchrPaymentMethodCode); 808 } 809 810 /** 811 * This method... 812 * 813 * @param method 814 * @deprecated This method should not be used. There is no protected attribute to store this value. The associated getter 815 * retrieves the value remotely. 816 */ 817 public void setDisbVchrPaymentMethodName(String method) { 818 } 819 820 /** 821 * Returns the name associated with the documentation location name 822 * 823 * @return String 824 */ 825 public String getDisbursementVoucherDocumentationLocationName() { 826 return new DisbursementVoucherDocumentationLocationValuesFinder().getKeyLabel(disbursementVoucherDocumentationLocationCode); 827 } 828 829 /** 830 * This method... 831 * 832 * @param name 833 * @deprecated This method should not be used. There is no protected attribute to store this value. The associated getter 834 * retrieves the value remotely. 835 */ 836 public void setDisbursementVoucherDocumentationLocationName(String name) { 837 } 838 839 840 /** 841 * Gets the disbVchrBankCode attribute. 842 * 843 * @return Returns the disbVchrBankCode. 844 */ 845 public String getDisbVchrBankCode() { 846 return disbVchrBankCode; 847 } 848 849 850 /** 851 * Sets the disbVchrBankCode attribute value. 852 * 853 * @param disbVchrBankCode The disbVchrBankCode to set. 854 */ 855 public void setDisbVchrBankCode(String disbVchrBankCode) { 856 this.disbVchrBankCode = disbVchrBankCode; 857 } 858 859 /** 860 * Gets the bank attribute. 861 * 862 * @return Returns the bank. 863 */ 864 public Bank getBank() { 865 return bank; 866 } 867 868 869 /** 870 * Sets the bank attribute value. 871 * 872 * @param bank The bank to set. 873 */ 874 public void setBank(Bank bank) { 875 this.bank = bank; 876 } 877 878 879 /** 880 * Convenience method to set dv payee detail fields based on a given vendor. 881 * 882 * @param vendor 883 */ 884 public void templateVendor(VendorDetail vendor, VendorAddress vendorAddress) { 885 if (vendor == null) { 886 return; 887 } 888 889 this.getDvPayeeDetail().setDisbursementVoucherPayeeTypeCode(DisbursementVoucherConstants.DV_PAYEE_TYPE_VENDOR); 890 this.getDvPayeeDetail().setDisbVchrPayeeIdNumber(vendor.getVendorNumber()); 891 this.getDvPayeeDetail().setDisbVchrPayeePersonName(vendor.getVendorName()); 892 893 this.getDvPayeeDetail().setDisbVchrAlienPaymentCode(vendor.getVendorHeader().getVendorForeignIndicator()); 894 895 if (ObjectUtils.isNull(vendorAddress) || ObjectUtils.isNull(vendorAddress.getVendorAddressGeneratedIdentifier())) { 896 for (VendorAddress addr : vendor.getVendorAddresses()) { 897 if (addr.isVendorDefaultAddressIndicator()) { 898 vendorAddress = addr; 899 break; 900 } 901 } 902 } 903 904 if (ObjectUtils.isNotNull(vendorAddress) && ObjectUtils.isNotNull(vendorAddress.getVendorAddressGeneratedIdentifier())) { 905 this.getDvPayeeDetail().setDisbVchrVendorAddressIdNumber(vendorAddress.getVendorAddressGeneratedIdentifier().toString()); 906 this.getDvPayeeDetail().setDisbVchrPayeeLine1Addr(vendorAddress.getVendorLine1Address()); 907 this.getDvPayeeDetail().setDisbVchrPayeeLine2Addr(vendorAddress.getVendorLine2Address()); 908 this.getDvPayeeDetail().setDisbVchrPayeeCityName(vendorAddress.getVendorCityName()); 909 this.getDvPayeeDetail().setDisbVchrPayeeStateCode(vendorAddress.getVendorStateCode()); 910 this.getDvPayeeDetail().setDisbVchrPayeeZipCode(vendorAddress.getVendorZipCode()); 911 this.getDvPayeeDetail().setDisbVchrPayeeCountryCode(vendorAddress.getVendorCountryCode()); 912 } 913 else { 914 this.getDvPayeeDetail().setDisbVchrVendorAddressIdNumber(""); 915 this.getDvPayeeDetail().setDisbVchrPayeeLine1Addr(""); 916 this.getDvPayeeDetail().setDisbVchrPayeeLine2Addr(""); 917 this.getDvPayeeDetail().setDisbVchrPayeeCityName(""); 918 this.getDvPayeeDetail().setDisbVchrPayeeStateCode(""); 919 this.getDvPayeeDetail().setDisbVchrPayeeZipCode(""); 920 this.getDvPayeeDetail().setDisbVchrPayeeCountryCode(""); 921 } 922 923 this.getDvPayeeDetail().setDisbVchrAlienPaymentCode(vendor.getVendorHeader().getVendorForeignIndicator()); 924 this.getDvPayeeDetail().setDvPayeeSubjectPaymentCode(VendorConstants.VendorTypes.SUBJECT_PAYMENT.equals(vendor.getVendorHeader().getVendorTypeCode())); 925 this.getDvPayeeDetail().setDisbVchrEmployeePaidOutsidePayrollCode(getVendorService().isVendorInstitutionEmployee(vendor.getVendorHeaderGeneratedIdentifier())); 926 927 this.getDvPayeeDetail().setHasMultipleVendorAddresses(1 < vendor.getVendorAddresses().size()); 928 929 boolean w9AndW8Checked = false; 930 if ( (ObjectUtils.isNotNull(vendor.getVendorHeader().getVendorW9ReceivedIndicator()) && vendor.getVendorHeader().getVendorW9ReceivedIndicator() == true) || 931 (ObjectUtils.isNotNull(vendor.getVendorHeader().getVendorW8BenReceivedIndicator()) && vendor.getVendorHeader().getVendorW8BenReceivedIndicator() == true) ) { 932 933 w9AndW8Checked = true; 934 } 935 936 // this.disbVchrPayeeW9CompleteCode = vendor.getVendorHeader().getVendorW8BenReceivedIndicator() == null ? false : vendor.getVendorHeader().getVendorW8BenReceivedIndicator(); 937 this.disbVchrPayeeW9CompleteCode = w9AndW8Checked; 938 939 Date vendorFederalWithholdingTaxBeginDate = vendor.getVendorHeader().getVendorFederalWithholdingTaxBeginningDate(); 940 Date vendorFederalWithholdingTaxEndDate = vendor.getVendorHeader().getVendorFederalWithholdingTaxEndDate(); 941 java.util.Date today = getDateTimeService().getCurrentDate(); 942 if ((vendorFederalWithholdingTaxBeginDate != null && vendorFederalWithholdingTaxBeginDate.before(today)) && (vendorFederalWithholdingTaxEndDate == null || vendorFederalWithholdingTaxEndDate.after(today))) { 943 this.disbVchrPayeeTaxControlCode = DisbursementVoucherConstants.TAX_CONTROL_CODE_BEGIN_WITHHOLDING; 944 } 945 946 // if vendor is foreign, default alien payment code to true 947 if (getVendorService().isVendorForeign(vendor.getVendorHeaderGeneratedIdentifier())) { 948 getDvPayeeDetail().setDisbVchrAlienPaymentCode(true); 949 } 950 } 951 952 /** 953 * Convenience method to set dv payee detail fields based on a given Employee. 954 * 955 * @param employee 956 */ 957 public void templateEmployee(Person employee) { 958 if (employee == null) { 959 return; 960 } 961 962 this.getDvPayeeDetail().setDisbursementVoucherPayeeTypeCode(DisbursementVoucherConstants.DV_PAYEE_TYPE_EMPLOYEE); 963 this.getDvPayeeDetail().setDisbVchrPayeeIdNumber(employee.getEmployeeId()); 964 this.getDvPayeeDetail().setDisbVchrPayeePersonName(employee.getName()); 965 966 final ParameterService parameterService = this.getParameterService(); 967 968 if (parameterService.parameterExists(DisbursementVoucherDocument.class, DisbursementVoucherDocument.USE_DEFAULT_EMPLOYEE_ADDRESS_PARAMETER_NAME) && parameterService.getIndicatorParameter(DisbursementVoucherDocument.class, DisbursementVoucherDocument.USE_DEFAULT_EMPLOYEE_ADDRESS_PARAMETER_NAME)) { 969 this.getDvPayeeDetail().setDisbVchrPayeeLine1Addr(employee.getAddressLine1Unmasked()); 970 this.getDvPayeeDetail().setDisbVchrPayeeLine2Addr(employee.getAddressLine2Unmasked()); 971 this.getDvPayeeDetail().setDisbVchrPayeeCityName(employee.getAddressCityNameUnmasked()); 972 this.getDvPayeeDetail().setDisbVchrPayeeStateCode(employee.getAddressStateCodeUnmasked()); 973 this.getDvPayeeDetail().setDisbVchrPayeeZipCode(employee.getAddressPostalCodeUnmasked()); 974 this.getDvPayeeDetail().setDisbVchrPayeeCountryCode(employee.getAddressCountryCodeUnmasked()); 975 } else { 976 final KimEntityAddress address = getNonDefaultAddress(employee); 977 if (address != null) { 978 this.getDvPayeeDetail().setDisbVchrPayeeLine1Addr(address.getLine1Unmasked()); 979 this.getDvPayeeDetail().setDisbVchrPayeeLine2Addr(address.getLine2Unmasked()); 980 this.getDvPayeeDetail().setDisbVchrPayeeCityName(address.getCityNameUnmasked()); 981 this.getDvPayeeDetail().setDisbVchrPayeeStateCode(address.getStateCodeUnmasked()); 982 this.getDvPayeeDetail().setDisbVchrPayeeZipCode(address.getPostalCodeUnmasked()); 983 this.getDvPayeeDetail().setDisbVchrPayeeCountryCode(address.getCountryCodeUnmasked()); 984 } 985 else { 986 this.getDvPayeeDetail().setDisbVchrPayeeLine1Addr(""); 987 this.getDvPayeeDetail().setDisbVchrPayeeLine2Addr(""); 988 this.getDvPayeeDetail().setDisbVchrPayeeCityName(""); 989 this.getDvPayeeDetail().setDisbVchrPayeeStateCode(""); 990 this.getDvPayeeDetail().setDisbVchrPayeeZipCode(""); 991 this.getDvPayeeDetail().setDisbVchrPayeeCountryCode(""); 992 } 993 } 994 995 this.getDvPayeeDetail().setDisbVchrPayeeEmployeeCode(true); 996 // I'm assuming that if a tax id type code other than 'TAX' is present, then the employee must be foreign 997 for ( String externalIdentifierTypeCode : employee.getExternalIdentifiers().keySet() ) { 998 if (KimConstants.PersonExternalIdentifierTypes.TAX.equals(externalIdentifierTypeCode)) { 999 this.getDvPayeeDetail().setDisbVchrAlienPaymentCode(false); 1000 } 1001 } 1002 // Determine if employee is a research subject 1003 ParameterEvaluator researchPaymentReasonCodeEvaluator = getParameterService().getParameterEvaluator(DisbursementVoucherDocument.class, DisbursementVoucherConstants.RESEARCH_PAYMENT_REASONS_PARM_NM, this.getDvPayeeDetail().getDisbVchrPaymentReasonCode()); 1004 if (researchPaymentReasonCodeEvaluator.evaluationSucceeds()) { 1005 if (getParameterService().parameterExists(DisbursementVoucherDocument.class, DisbursementVoucherConstants.RESEARCH_NON_VENDOR_PAY_LIMIT_AMOUNT_PARM_NM)) { 1006 String researchPayLimit = getParameterService().getParameterValue(DisbursementVoucherDocument.class, DisbursementVoucherConstants.RESEARCH_NON_VENDOR_PAY_LIMIT_AMOUNT_PARM_NM); 1007 if (StringUtils.isNotBlank(researchPayLimit)) { 1008 KualiDecimal payLimit = new KualiDecimal(researchPayLimit); 1009 1010 if (getDisbVchrCheckTotalAmount().isLessThan(payLimit)) { 1011 this.getDvPayeeDetail().setDvPayeeSubjectPaymentCode(true); 1012 } 1013 } 1014 } 1015 } 1016 1017 this.disbVchrPayeeTaxControlCode = ""; 1018 this.disbVchrPayeeW9CompleteCode = true; 1019 } 1020 1021 /** 1022 * Finds the address for the given employee, matching the type in the KFS-FP / Disbursement Voucher/ DEFAULT_EMPLOYEE_ADDRESS_TYPE parameter, 1023 * to use as the address for the employee 1024 * @param employee the employee to find a non-default address for 1025 * @return the non-default address, or null if not found 1026 */ 1027 protected KimEntityAddress getNonDefaultAddress(Person employee) { 1028 final String addressType = parameterService.getParameterValue(DisbursementVoucherDocument.class, DisbursementVoucherDocument.DEFAULT_EMPLOYEE_ADDRESS_TYPE_PARAMETER_NAME); 1029 final KimEntityInfo entityInfo = getIdentityManagementService().getEntityInfoByPrincipalId(employee.getPrincipalId()); 1030 if (entityInfo != null) { 1031 final KimEntityEntityType entityEntityType = getPersonEntityEntityType(entityInfo); 1032 if (entityEntityType != null) { 1033 final List<? extends KimEntityAddress> addresses = entityEntityType.getAddresses(); 1034 1035 return findAddressByType(addresses, addressType); 1036 } 1037 } 1038 return null; 1039 } 1040 1041 /** 1042 * Someday this method will be in Rice. But...'til it is...lazy loop through the entity entity types in the given 1043 * KimEntityInfo and return the one who has the type of "PERSON" 1044 * @param entityInfo the entity info to loop through entity entity types of 1045 * @return a found entity entity type or null if a PERSON entity entity type is not associated with the given KimEntityInfo record 1046 */ 1047 protected KimEntityEntityType getPersonEntityEntityType(KimEntityInfo entityInfo) { 1048 final List<KimEntityEntityTypeInfo> entityEntityTypes = entityInfo.getEntityTypes(); 1049 int count = 0; 1050 KimEntityEntityType foundInfo = null; 1051 1052 while (count < entityEntityTypes.size() && foundInfo == null) { 1053 if (entityEntityTypes.get(count).getEntityTypeCode().equals(KimConstants.EntityTypes.PERSON)) { 1054 foundInfo = entityEntityTypes.get(count); 1055 } 1056 count += 1; 1057 } 1058 1059 return foundInfo; 1060 } 1061 1062 /** 1063 * Given a List of KimEntityAddress and an address type, finds the address in the List with the given type (or null if no matching KimEntityAddress is found) 1064 * @param addresses the List of KimEntityAddress records to search 1065 * @param addressType the address type of the address to return 1066 * @return the found KimEntityAddress, or null if not found 1067 */ 1068 protected KimEntityAddress findAddressByType(List<? extends KimEntityAddress> addresses, String addressType) { 1069 KimEntityAddress foundAddress = null; 1070 int count = 0; 1071 1072 while (count < addresses.size() && foundAddress == null) { 1073 final KimEntityAddress currentAddress = addresses.get(count); 1074 if (currentAddress.getAddressTypeCode().equals(addressType)) { 1075 foundAddress = currentAddress; 1076 } 1077 count += 1; 1078 } 1079 1080 return foundAddress; 1081 } 1082 1083 /** 1084 * @see org.kuali.rice.kns.document.Document#prepareForSave() 1085 */ 1086 @Override 1087 public void prepareForSave() { 1088 if (this instanceof AmountTotaling) { 1089 getDocumentHeader().setFinancialDocumentTotalAmount(((AmountTotaling) this).getTotalDollarAmount()); 1090 } 1091 1092 if (dvWireTransfer != null) { 1093 dvWireTransfer.setDocumentNumber(this.documentNumber); 1094 } 1095 1096 if (dvNonResidentAlienTax != null) { 1097 dvNonResidentAlienTax.setDocumentNumber(this.documentNumber); 1098 } 1099 1100 dvPayeeDetail.setDocumentNumber(this.documentNumber); 1101 1102 if (dvNonEmployeeTravel != null) { 1103 dvNonEmployeeTravel.setDocumentNumber(this.documentNumber); 1104 dvNonEmployeeTravel.setTotalTravelAmount(dvNonEmployeeTravel.getTotalTravelAmount()); 1105 } 1106 1107 if (dvPreConferenceDetail != null) { 1108 dvPreConferenceDetail.setDocumentNumber(this.documentNumber); 1109 dvPreConferenceDetail.setDisbVchrConferenceTotalAmt(dvPreConferenceDetail.getDisbVchrConferenceTotalAmt()); 1110 } 1111 1112 if (shouldClearSpecialHandling()) { 1113 clearSpecialHandling(); 1114 } 1115 } 1116 1117 /** 1118 * Determines if the special handling fields should be cleared, based on whether the special handling has been turned off and whether the current node is CAMPUS 1119 * @return true if special handling should be cleared, false otherwise 1120 */ 1121 protected boolean shouldClearSpecialHandling() { 1122 if (!isDisbVchrSpecialHandlingCode()) { 1123 // are we at the campus route node? 1124 try { 1125 List<String> currentNodes = Arrays.asList(getDocumentHeader().getWorkflowDocument().getNodeNames()); 1126 return (currentNodes.contains(DisbursementVoucherConstants.RouteLevelNames.CAMPUS)); 1127 } 1128 catch (WorkflowException we) { 1129 throw new RuntimeException("Workflow Exception while attempting to check route levels", we); 1130 } 1131 } 1132 return false; 1133 } 1134 1135 /** 1136 * Clears all set special handling fields 1137 */ 1138 protected void clearSpecialHandling() { 1139 DisbursementVoucherPayeeDetail payeeDetail = getDvPayeeDetail(); 1140 1141 if (!StringUtils.isBlank(payeeDetail.getDisbVchrSpecialHandlingPersonName())) { 1142 payeeDetail.setDisbVchrSpecialHandlingPersonName(null); 1143 } 1144 if (!StringUtils.isBlank(payeeDetail.getDisbVchrSpecialHandlingLine1Addr())) { 1145 payeeDetail.setDisbVchrSpecialHandlingLine1Addr(null); 1146 } 1147 if (!StringUtils.isBlank(payeeDetail.getDisbVchrSpecialHandlingLine2Addr())) { 1148 payeeDetail.setDisbVchrSpecialHandlingLine2Addr(null); 1149 } 1150 if (!StringUtils.isBlank(payeeDetail.getDisbVchrSpecialHandlingCityName())) { 1151 payeeDetail.setDisbVchrSpecialHandlingCityName(null); 1152 } 1153 if (!StringUtils.isBlank(payeeDetail.getDisbVchrSpecialHandlingStateCode())) { 1154 payeeDetail.setDisbVchrSpecialHandlingStateCode(null); 1155 } 1156 if (!StringUtils.isBlank(payeeDetail.getDisbVchrSpecialHandlingZipCode())) { 1157 payeeDetail.setDisbVchrSpecialHandlingZipCode(null); 1158 } 1159 if (!StringUtils.isBlank(payeeDetail.getDisbVchrSpecialHandlingCountryCode())) { 1160 payeeDetail.setDisbVchrSpecialHandlingCountryCode(null); 1161 } 1162 } 1163 1164 /** 1165 * This method is overridden to populate some local variables that are not persisted to the database. These values need to be 1166 * computed and saved to the DV Payee Detail BO so they can be serialized to XML for routing. Some of the routing rules rely on 1167 * these variables. 1168 * 1169 * @see org.kuali.rice.kns.document.DocumentBase#populateDocumentForRouting() 1170 */ 1171 @Override 1172 public void populateDocumentForRouting() { 1173 DisbursementVoucherPayeeDetail payeeDetail = getDvPayeeDetail(); 1174 1175 if (payeeDetail.isVendor()) { 1176 payeeDetail.setDisbVchrPayeeEmployeeCode(getVendorService().isVendorInstitutionEmployee(payeeDetail.getDisbVchrVendorHeaderIdNumberAsInteger())); 1177 payeeDetail.setDvPayeeSubjectPaymentCode(getVendorService().isSubjectPaymentVendor(payeeDetail.getDisbVchrVendorHeaderIdNumberAsInteger())); 1178 } 1179 else if (payeeDetail.isEmployee()) { 1180 1181 // Determine if employee is a research subject 1182 ParameterEvaluator researchPaymentReasonCodeEvaluator = getParameterService().getParameterEvaluator(DisbursementVoucherDocument.class, DisbursementVoucherConstants.RESEARCH_PAYMENT_REASONS_PARM_NM, payeeDetail.getDisbVchrPaymentReasonCode()); 1183 if (researchPaymentReasonCodeEvaluator.evaluationSucceeds()) { 1184 if (getParameterService().parameterExists(DisbursementVoucherDocument.class, DisbursementVoucherConstants.RESEARCH_NON_VENDOR_PAY_LIMIT_AMOUNT_PARM_NM)) { 1185 String researchPayLimit = getParameterService().getParameterValue(DisbursementVoucherDocument.class, DisbursementVoucherConstants.RESEARCH_NON_VENDOR_PAY_LIMIT_AMOUNT_PARM_NM); 1186 if (StringUtils.isNotBlank(researchPayLimit)) { 1187 KualiDecimal payLimit = new KualiDecimal(researchPayLimit); 1188 1189 if (getDisbVchrCheckTotalAmount().isLessThan(payLimit)) { 1190 payeeDetail.setDvPayeeSubjectPaymentCode(true); 1191 } 1192 } 1193 } 1194 } 1195 } 1196 1197 super.populateDocumentForRouting(); // Call last, serializes to XML 1198 } 1199 1200 /** 1201 * Clears information that might have been entered for sub tables, but because of changes to the document is longer needed and 1202 * should not be persisted. 1203 */ 1204 protected void cleanDocumentData() { 1205 // TODO: warren: this method ain't called!!! maybe this should be called by prepare for save above 1206 if (!DisbursementVoucherConstants.PAYMENT_METHOD_WIRE.equals(this.getDisbVchrPaymentMethodCode()) && !DisbursementVoucherConstants.PAYMENT_METHOD_DRAFT.equals(this.getDisbVchrPaymentMethodCode())) { 1207 getBusinessObjectService().delete(dvWireTransfer); 1208 dvWireTransfer = null; 1209 } 1210 1211 if (!dvPayeeDetail.isDisbVchrAlienPaymentCode()) { 1212 getBusinessObjectService().delete(dvNonResidentAlienTax); 1213 dvNonResidentAlienTax = null; 1214 } 1215 1216 DisbursementVoucherPaymentReasonService paymentReasonService = SpringContext.getBean(DisbursementVoucherPaymentReasonService.class); 1217 String paymentReasonCode = this.getDvPayeeDetail().getDisbVchrPaymentReasonCode(); 1218 if (!paymentReasonService.isNonEmployeeTravelPaymentReason(paymentReasonCode)) { 1219 getBusinessObjectService().delete(dvNonEmployeeTravel); 1220 dvNonEmployeeTravel = null; 1221 } 1222 1223 if (!paymentReasonService.isPrepaidTravelPaymentReason(paymentReasonCode)) { 1224 getBusinessObjectService().delete(dvPreConferenceDetail); 1225 dvPreConferenceDetail = null; 1226 } 1227 } 1228 1229 /** 1230 * @see org.kuali.kfs.sys.document.AccountingDocumentBase#toCopy() 1231 */ 1232 @Override 1233 public void toCopy() throws WorkflowException { 1234 super.toCopy(); 1235 initiateDocument(); 1236 1237 // clear fields 1238 setDisbVchrContactPhoneNumber(StringUtils.EMPTY); 1239 setDisbVchrContactEmailId(StringUtils.EMPTY); 1240 getDvPayeeDetail().setDisbVchrPayeePersonName(StringUtils.EMPTY); 1241 1242 getDvPayeeDetail().setDisbVchrPayeeLine1Addr(StringUtils.EMPTY); 1243 getDvPayeeDetail().setDisbVchrPayeeLine2Addr(StringUtils.EMPTY); 1244 getDvPayeeDetail().setDisbVchrPayeeCityName(StringUtils.EMPTY); 1245 getDvPayeeDetail().setDisbVchrPayeeStateCode(StringUtils.EMPTY); 1246 getDvPayeeDetail().setDisbVchrPayeeZipCode(StringUtils.EMPTY); 1247 getDvPayeeDetail().setDisbVchrPayeeCountryCode(StringUtils.EMPTY); 1248 1249 setDisbVchrPayeeTaxControlCode(StringUtils.EMPTY); 1250 1251 // clear nra 1252 SpringContext.getBean(DisbursementVoucherTaxService.class).clearNRATaxLines(this); 1253 setDvNonResidentAlienTax(new DisbursementVoucherNonResidentAlienTax()); 1254 1255 // clear waive wire 1256 getDvWireTransfer().setDisbursementVoucherWireTransferFeeWaiverIndicator(false); 1257 1258 // check vendor id number to see if still valid, if so retrieve their last information and set in the detail inform. 1259 if (!StringUtils.isBlank(getDvPayeeDetail().getDisbVchrPayeeIdNumber())) { 1260 VendorDetail vendorDetail = getVendorService().getVendorDetail(dvPayeeDetail.getDisbVchrVendorHeaderIdNumberAsInteger(), dvPayeeDetail.getDisbVchrVendorDetailAssignedIdNumberAsInteger()); 1261 VendorAddress vendorAddress = new VendorAddress(); 1262 vendorAddress.setVendorAddressGeneratedIdentifier(dvPayeeDetail.getDisbVchrVendorAddressIdNumberAsInteger()); 1263 vendorAddress = (VendorAddress) getBusinessObjectService().retrieve(vendorAddress); 1264 1265 if (vendorDetail == null) { 1266 getDvPayeeDetail().setDisbVchrPayeeIdNumber(StringUtils.EMPTY); 1267 GlobalVariables.getMessageList().add(KFSKeyConstants.WARNING_DV_PAYEE_NONEXISTANT_CLEARED); 1268 } 1269 else { 1270 templateVendor(vendorDetail, vendorAddress); 1271 } 1272 } 1273 1274 // this copied DV has not been extracted 1275 this.extractDate = null; 1276 this.paidDate = null; 1277 this.cancelDate = null; 1278 getDocumentHeader().setFinancialDocumentStatusCode(KFSConstants.DocumentStatusCodes.INITIATED); 1279 } 1280 1281 /** 1282 * generic, shared logic used to initiate a dv document 1283 */ 1284 public void initiateDocument() { 1285 Person currentUser = GlobalVariables.getUserSession().getPerson(); 1286 setDisbVchrContactPersonName(currentUser.getName()); 1287 setDisbVchrContactPhoneNumber(currentUser.getPhoneNumber()); 1288 setDisbVchrContactEmailId(currentUser.getEmailAddress()); 1289 ChartOrgHolder chartOrg = SpringContext.getBean(org.kuali.kfs.sys.service.FinancialSystemUserService.class).getPrimaryOrganization(currentUser, KFSConstants.ParameterNamespaces.FINANCIAL); 1290 1291 // Does a valid campus code exist for this person? If so, simply grab 1292 // the campus code via the business object service. 1293 if (chartOrg != null && chartOrg.getOrganization() != null) { 1294 setCampusCode(chartOrg.getOrganization().getOrganizationPhysicalCampusCode()); 1295 } 1296 // A valid campus code was not found; therefore, use the default affiliated 1297 // campus code. 1298 else { 1299 String affiliatedCampusCode = currentUser.getCampusCode(); 1300 setCampusCode(affiliatedCampusCode); 1301 } 1302 1303 // due date 1304 Calendar calendar = getDateTimeService().getCurrentCalendar(); 1305 calendar.add(Calendar.DAY_OF_MONTH, 1); 1306 setDisbursementVoucherDueDate(new Date(calendar.getTimeInMillis())); 1307 1308 // default doc location 1309 if (StringUtils.isBlank(getDisbursementVoucherDocumentationLocationCode())) { 1310 setDisbursementVoucherDocumentationLocationCode(getParameterService().getParameterValue(DisbursementVoucherDocument.class, DisbursementVoucherConstants.DEFAULT_DOC_LOCATION_PARM_NM)); 1311 } 1312 1313 // default bank code 1314 Bank defaultBank = SpringContext.getBean(BankService.class).getDefaultBankByDocType(this.getClass()); 1315 if (defaultBank != null) { 1316 this.disbVchrBankCode = defaultBank.getBankCode(); 1317 this.bank = defaultBank; 1318 } 1319 } 1320 1321 /** 1322 * @see org.kuali.rice.kns.document.DocumentBase#buildListOfDeletionAwareLists() 1323 */ 1324 @SuppressWarnings("unchecked") 1325 @Override 1326 public List buildListOfDeletionAwareLists() { 1327 List managedLists = super.buildListOfDeletionAwareLists(); 1328 1329 if (dvNonEmployeeTravel != null) { 1330 managedLists.add(dvNonEmployeeTravel.getDvNonEmployeeExpenses()); 1331 managedLists.add(dvNonEmployeeTravel.getDvPrePaidEmployeeExpenses()); 1332 } 1333 1334 if (dvPreConferenceDetail != null) { 1335 managedLists.add(dvPreConferenceDetail.getDvPreConferenceRegistrants()); 1336 } 1337 1338 return managedLists; 1339 } 1340 1341 /** 1342 * Returns check total. 1343 * 1344 * @see org.kuali.kfs.sys.document.AccountingDocumentBase#getTotalDollarAmount() 1345 * @return KualiDecimal 1346 */ 1347 @Override 1348 public KualiDecimal getTotalDollarAmount() { 1349 return this.getDisbVchrCheckTotalAmount(); 1350 } 1351 1352 /** 1353 * Returns true if accounting line debit 1354 * 1355 * @param financialDocument submitted accounting document 1356 * @param accountingLine accounting line in accounting document 1357 * @return true if document is debit 1358 * @see IsDebitUtils#isDebitConsideringNothingPositiveOnly(FinancialDocumentRuleBase, FinancialDocument, AccountingLine) 1359 * @see org.kuali.rice.kns.rule.AccountingLineRule#isDebit(org.kuali.rice.kns.document.FinancialDocument, 1360 * org.kuali.rice.kns.bo.AccountingLine) 1361 */ 1362 public boolean isDebit(GeneralLedgerPendingEntrySourceDetail postable) { 1363 // disallow error corrections 1364 DebitDeterminerService isDebitUtils = SpringContext.getBean(DebitDeterminerService.class); 1365 isDebitUtils.disallowErrorCorrectionDocumentCheck(this); 1366 1367 if (getDvNonResidentAlienTax() != null && getDvNonResidentAlienTax().getFinancialDocumentAccountingLineText() != null && getDvNonResidentAlienTax().getFinancialDocumentAccountingLineText().contains(((AccountingLine) postable).getSequenceNumber().toString())) { 1368 return postable.getAmount().isPositive(); 1369 } 1370 1371 return isDebitUtils.isDebitConsideringNothingPositiveOnly(this, (AccountingLine) postable); 1372 } 1373 1374 /** 1375 * Override to change the doc type based on payment method. This is needed to pick up different offset definitions. 1376 * 1377 * @param financialDocument submitted accounting document 1378 * @param accountingLine accounting line in submitted accounting document 1379 * @param explicitEntry explicit GLPE 1380 * @see org.kuali.module.financial.rules.FinancialDocumentRuleBase#customizeExplicitGeneralLedgerPendingEntry(org.kuali.rice.kns.document.FinancialDocument, 1381 * org.kuali.rice.kns.bo.AccountingLine, org.kuali.module.gl.bo.GeneralLedgerPendingEntry) 1382 */ 1383 @Override 1384 public void customizeExplicitGeneralLedgerPendingEntry(GeneralLedgerPendingEntrySourceDetail accountingLine, GeneralLedgerPendingEntry explicitEntry) { 1385 1386 /* change document type based on payment method to pick up different offsets */ 1387 if (DisbursementVoucherConstants.PAYMENT_METHOD_CHECK.equals(getDisbVchrPaymentMethodCode())) { 1388 LOG.debug("changing doc type on pending entry " + explicitEntry.getTransactionLedgerEntrySequenceNumber() + " to " + DisbursementVoucherConstants.DOCUMENT_TYPE_CHECKACH); 1389 explicitEntry.setFinancialDocumentTypeCode(DisbursementVoucherConstants.DOCUMENT_TYPE_CHECKACH); 1390 } 1391 else { 1392 LOG.debug("changing doc type on pending entry " + explicitEntry.getTransactionLedgerEntrySequenceNumber() + " to " + DisbursementVoucherConstants.DOCUMENT_TYPE_CHECKACH); 1393 explicitEntry.setFinancialDocumentTypeCode(DisbursementVoucherConstants.DOCUMENT_TYPE_WTFD); 1394 } 1395 } 1396 1397 /** 1398 * Return true if GLPE's are generated successfully (i.e. there are either 0 GLPE's or 1 GLPE in disbursement voucher document) 1399 * 1400 * @param financialDocument submitted financial document 1401 * @param sequenceHelper helper class to keep track of GLPE sequence 1402 * @return true if GLPE's are generated successfully 1403 * @see org.kuali.rice.kns.rule.GenerateGeneralLedgerDocumentPendingEntriesRule#processGenerateDocumentGeneralLedgerPendingEntries(org.kuali.rice.kns.document.FinancialDocument,org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper) 1404 */ 1405 @Override 1406 public boolean generateDocumentGeneralLedgerPendingEntries(GeneralLedgerPendingEntrySequenceHelper sequenceHelper) { 1407 if (getGeneralLedgerPendingEntries() == null || getGeneralLedgerPendingEntries().size() < 2) { 1408 LOG.warn("No gl entries for accounting lines."); 1409 return true; 1410 } 1411 1412 /* 1413 * only generate additional charge entries for payment method wire charge, and if the fee has not been waived 1414 */ 1415 if (DisbursementVoucherConstants.PAYMENT_METHOD_WIRE.equals(getDisbVchrPaymentMethodCode()) && !getDvWireTransfer().isDisbursementVoucherWireTransferFeeWaiverIndicator()) { 1416 LOG.debug("generating wire charge gl pending entries."); 1417 1418 // retrieve wire charge 1419 WireCharge wireCharge = retrieveWireCharge(); 1420 1421 // generate debits 1422 GeneralLedgerPendingEntry chargeEntry = processWireChargeDebitEntries(sequenceHelper, wireCharge); 1423 1424 // generate credits 1425 processWireChargeCreditEntries(sequenceHelper, wireCharge, chargeEntry); 1426 } 1427 1428 // for wire or drafts generate bank offset entry (if enabled), for ACH and checks offset will be generated by PDP 1429 if (DisbursementVoucherConstants.PAYMENT_METHOD_WIRE.equals(getDisbVchrPaymentMethodCode()) || DisbursementVoucherConstants.PAYMENT_METHOD_DRAFT.equals(getDisbVchrPaymentMethodCode())) { 1430 generateDocumentBankOffsetEntries(sequenceHelper); 1431 } 1432 1433 return true; 1434 } 1435 1436 /** 1437 * Builds an explicit and offset for the wire charge debit. The account associated with the first accounting is used for the 1438 * debit. The explicit and offset entries for the first accounting line and copied and customized for the wire charge. 1439 * 1440 * @param dvDocument submitted disbursement voucher document 1441 * @param sequenceHelper helper class to keep track of GLPE sequence 1442 * @param wireCharge wireCharge object from current fiscal year 1443 * @return GeneralLedgerPendingEntry generated wire charge debit 1444 */ 1445 protected GeneralLedgerPendingEntry processWireChargeDebitEntries(GeneralLedgerPendingEntrySequenceHelper sequenceHelper, WireCharge wireCharge) { 1446 LOG.info("processWireChargeDebitEntries started"); 1447 1448 // grab the explicit entry for the first accounting line and adjust for wire charge entry 1449 GeneralLedgerPendingEntry explicitEntry = new GeneralLedgerPendingEntry(getGeneralLedgerPendingEntry(0)); 1450 explicitEntry.setTransactionLedgerEntrySequenceNumber(new Integer(sequenceHelper.getSequenceCounter())); 1451 explicitEntry.setFinancialObjectCode(wireCharge.getExpenseFinancialObjectCode()); 1452 explicitEntry.setFinancialSubObjectCode(GENERAL_LEDGER_PENDING_ENTRY_CODE.getBlankFinancialSubObjectCode()); 1453 explicitEntry.setTransactionDebitCreditCode(GL_DEBIT_CODE); 1454 1455 String objectTypeCode = SpringContext.getBean(OptionsService.class).getCurrentYearOptions().getFinObjTypeExpenditureexpCd(); 1456 explicitEntry.setFinancialObjectTypeCode(objectTypeCode); 1457 1458 String originationCode = SpringContext.getBean(HomeOriginationService.class).getHomeOrigination().getFinSystemHomeOriginationCode(); 1459 explicitEntry.setFinancialSystemOriginationCode(originationCode); 1460 1461 if (KFSConstants.COUNTRY_CODE_UNITED_STATES.equals(getDvWireTransfer().getDisbVchrBankCountryCode())) { 1462 explicitEntry.setTransactionLedgerEntryAmount(wireCharge.getDomesticChargeAmt()); 1463 } 1464 else { 1465 explicitEntry.setTransactionLedgerEntryAmount(wireCharge.getForeignChargeAmt()); 1466 } 1467 1468 explicitEntry.setTransactionLedgerEntryDescription("Automatic debit for wire transfer fee"); 1469 1470 addPendingEntry(explicitEntry); 1471 sequenceHelper.increment(); 1472 1473 // handle the offset entry 1474 GeneralLedgerPendingEntry offsetEntry = new GeneralLedgerPendingEntry(explicitEntry); 1475 GeneralLedgerPendingEntryService glpeService = SpringContext.getBean(GeneralLedgerPendingEntryService.class); 1476 glpeService.populateOffsetGeneralLedgerPendingEntry(getPostingYear(), explicitEntry, sequenceHelper, offsetEntry); 1477 1478 addPendingEntry(offsetEntry); 1479 sequenceHelper.increment(); 1480 1481 return explicitEntry; 1482 } 1483 1484 /** 1485 * Builds an explicit and offset for the wire charge credit. The account and income object code found in the wire charge table 1486 * is used for the entry. 1487 * 1488 * @param dvDocument submitted disbursement voucher document 1489 * @param sequenceHelper helper class to keep track of GLPE sequence 1490 * @param chargeEntry GLPE charge 1491 * @param wireCharge wireCharge object from current fiscal year 1492 */ 1493 protected void processWireChargeCreditEntries(GeneralLedgerPendingEntrySequenceHelper sequenceHelper, WireCharge wireCharge, GeneralLedgerPendingEntry chargeEntry) { 1494 LOG.info("processWireChargeCreditEntries started"); 1495 1496 // copy the charge entry and adjust for credit 1497 GeneralLedgerPendingEntry explicitEntry = new GeneralLedgerPendingEntry(chargeEntry); 1498 explicitEntry.setTransactionLedgerEntrySequenceNumber(new Integer(sequenceHelper.getSequenceCounter())); 1499 explicitEntry.setChartOfAccountsCode(wireCharge.getChartOfAccountsCode()); 1500 explicitEntry.setAccountNumber(wireCharge.getAccountNumber()); 1501 explicitEntry.setFinancialObjectCode(wireCharge.getIncomeFinancialObjectCode()); 1502 1503 // retrieve object type 1504 ObjectCode objectCode = wireCharge.getIncomeFinancialObject(); 1505 explicitEntry.setFinancialObjectTypeCode(objectCode.getFinancialObjectTypeCode()); 1506 1507 explicitEntry.setTransactionDebitCreditCode(GL_CREDIT_CODE); 1508 1509 explicitEntry.setFinancialSubObjectCode(GENERAL_LEDGER_PENDING_ENTRY_CODE.getBlankFinancialSubObjectCode()); 1510 explicitEntry.setSubAccountNumber(GENERAL_LEDGER_PENDING_ENTRY_CODE.getBlankSubAccountNumber()); 1511 explicitEntry.setProjectCode(GENERAL_LEDGER_PENDING_ENTRY_CODE.getBlankProjectCode()); 1512 1513 explicitEntry.setTransactionLedgerEntryDescription("Automatic credit for wire transfer fee"); 1514 1515 addPendingEntry(explicitEntry); 1516 sequenceHelper.increment(); 1517 1518 // handle the offset entry 1519 GeneralLedgerPendingEntry offsetEntry = new GeneralLedgerPendingEntry(explicitEntry); 1520 GeneralLedgerPendingEntryService glpeService = SpringContext.getBean(GeneralLedgerPendingEntryService.class); 1521 glpeService.populateOffsetGeneralLedgerPendingEntry(getPostingYear(), explicitEntry, sequenceHelper, offsetEntry); 1522 1523 addPendingEntry(offsetEntry); 1524 sequenceHelper.increment(); 1525 } 1526 1527 /** 1528 * If bank specification is enabled generates bank offsetting entries for the document amount 1529 * 1530 * @param sequenceHelper helper class to keep track of GLPE sequence 1531 * @param paymentMethodCode the payment method of this DV 1532 */ 1533 public boolean generateDocumentBankOffsetEntries(GeneralLedgerPendingEntrySequenceHelper sequenceHelper) { 1534 boolean success = true; 1535 1536 if (!SpringContext.getBean(BankService.class).isBankSpecificationEnabled()) { 1537 return success; 1538 } 1539 1540 this.refreshReferenceObject(KFSPropertyConstants.BANK); 1541 1542 GeneralLedgerPendingEntryService glpeService = SpringContext.getBean(GeneralLedgerPendingEntryService.class); 1543 1544 final KualiDecimal bankOffsetAmount = glpeService.getOffsetToCashAmount(this).negated(); 1545 GeneralLedgerPendingEntry bankOffsetEntry = new GeneralLedgerPendingEntry(); 1546 success &= glpeService.populateBankOffsetGeneralLedgerPendingEntry(getBank(), bankOffsetAmount, this, getPostingYear(), sequenceHelper, bankOffsetEntry, KNSConstants.DOCUMENT_PROPERTY_NAME + "." + KFSPropertyConstants.DISB_VCHR_BANK_CODE); 1547 1548 if (success) { 1549 AccountingDocumentRuleHelperService accountingDocumentRuleUtil = SpringContext.getBean(AccountingDocumentRuleHelperService.class); 1550 bankOffsetEntry.setTransactionLedgerEntryDescription(accountingDocumentRuleUtil.formatProperty(KFSKeyConstants.Bank.DESCRIPTION_GLPE_BANK_OFFSET)); 1551 bankOffsetEntry.setFinancialDocumentTypeCode(DisbursementVoucherConstants.DOCUMENT_TYPE_WTFD); 1552 addPendingEntry(bankOffsetEntry); 1553 sequenceHelper.increment(); 1554 1555 GeneralLedgerPendingEntry offsetEntry = new GeneralLedgerPendingEntry(bankOffsetEntry); 1556 success &= glpeService.populateOffsetGeneralLedgerPendingEntry(getPostingYear(), bankOffsetEntry, sequenceHelper, offsetEntry); 1557 bankOffsetEntry.setFinancialDocumentTypeCode(DisbursementVoucherConstants.DOCUMENT_TYPE_WTFD); 1558 addPendingEntry(offsetEntry); 1559 sequenceHelper.increment(); 1560 } 1561 1562 return success; 1563 } 1564 1565 /** 1566 * Retrieves the wire transfer information for the current fiscal year. 1567 * 1568 * @return <code>WireCharge</code> 1569 */ 1570 protected WireCharge retrieveWireCharge() { 1571 WireCharge wireCharge = new WireCharge(); 1572 wireCharge.setUniversityFiscalYear(SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear()); 1573 1574 wireCharge = (WireCharge) getBusinessObjectService().retrieve(wireCharge); 1575 if (wireCharge == null) { 1576 LOG.error("Wire charge information not found for current fiscal year."); 1577 throw new RuntimeException("Wire charge information not found for current fiscal year."); 1578 } 1579 1580 return wireCharge; 1581 } 1582 1583 1584 /** 1585 * Gets the payeeAssigned attribute. This method returns a flag that is used to indicate if the payee type and value has been 1586 * set on the DV. This value is used to determine the correct page that should be loaded by the DV flow. 1587 * 1588 * @return Returns the payeeAssigned. 1589 */ 1590 public boolean isPayeeAssigned() { 1591 // If value is false, check state of document. We should assume payee is assigned if document has been saved. 1592 // Otherwise, value will be set during creation process. 1593 if (!payeeAssigned) { 1594 payeeAssigned = !this.getDocumentHeader().getWorkflowDocument().stateIsInitiated(); 1595 } 1596 return payeeAssigned; 1597 } 1598 1599 1600 /** 1601 * Sets the payeeAssigned attribute value. 1602 * 1603 * @param payeeAssigned The payeeAssigned to set. 1604 */ 1605 public void setPayeeAssigned(boolean payeeAssigned) { 1606 this.payeeAssigned = payeeAssigned; 1607 } 1608 1609 /** 1610 * Gets the editW9W8BENbox attribute. This method returns a flag that is used to indicate if the W9/W8BEN check box can be edited 1611 * by the initiator on the DV. 1612 * 1613 * @return Returns the editW9W8BENbox. 1614 */ 1615 public boolean isEditW9W8BENbox() { 1616 String initiatorPrincipalID = this.getDocumentHeader().getWorkflowDocument().getRouteHeader().getInitiatorPrincipalId(); 1617 if (GlobalVariables.getUserSession().getPrincipalId().equals(initiatorPrincipalID)) { 1618 editW9W8BENbox = true; 1619 } 1620 return editW9W8BENbox; 1621 } 1622 1623 /** 1624 * Sets the editW9W8BENbox attribute value. 1625 * 1626 * @param editW9W8BENbox The editW9W8BENbox to set. 1627 */ 1628 public void setEditW9W8BENbox(boolean editW9W8BENbox) { 1629 this.editW9W8BENbox = editW9W8BENbox; 1630 } 1631 1632 /** 1633 * Gets the disbVchrPdpBankCode attribute. 1634 * 1635 * @return Returns the disbVchrPdpBankCode. 1636 */ 1637 public String getDisbVchrPdpBankCode() { 1638 return disbVchrPdpBankCode; 1639 } 1640 1641 /** 1642 * Sets the disbVchrPdpBankCode attribute value. 1643 * 1644 * @param disbVchrPdpBankCode The disbVchrPDPBankCode to set. 1645 */ 1646 public void setDisbVchrPdpBankCode(String disbVchrPdpBankCode) { 1647 this.disbVchrPdpBankCode = disbVchrPdpBankCode; 1648 } 1649 1650 /** 1651 * @see org.kuali.rice.kns.document.DocumentBase#getDocumentTitle() 1652 */ 1653 @Override 1654 public String getDocumentTitle() { 1655 String documentTitle = super.getDocumentTitle(); 1656 return this.buildDocumentTitle(documentTitle); 1657 } 1658 1659 /** 1660 * build document title based on the properties of current document 1661 * 1662 * @param the default document title 1663 * @return the combine information of the given title and additional payment indicators 1664 */ 1665 protected String buildDocumentTitle(String title) { 1666 DisbursementVoucherPayeeDetail payee = getDvPayeeDetail(); 1667 if(payee == null) { 1668 return title; 1669 } 1670 1671 Object[] indicators = new String[3]; 1672 indicators[0] = payee.isEmployee() ? AdHocPaymentIndicator.EMPLOYEE_PAYEE : AdHocPaymentIndicator.OTHER; 1673 indicators[1] = payee.isDisbVchrAlienPaymentCode() ? AdHocPaymentIndicator.ALIEN_PAYEE : AdHocPaymentIndicator.OTHER; 1674 1675 DisbursementVoucherPaymentReasonService paymentReasonService = SpringContext.getBean(DisbursementVoucherPaymentReasonService.class); 1676 boolean isTaxReviewRequired = paymentReasonService.isTaxReviewRequired(payee.getDisbVchrPaymentReasonCode()); 1677 indicators[2] = isTaxReviewRequired ? AdHocPaymentIndicator.PAYMENT_REASON_REQUIRING_TAX_REVIEW : AdHocPaymentIndicator.OTHER; 1678 1679 for(Object indicator : indicators) { 1680 if(!AdHocPaymentIndicator.OTHER.equals(indicator)) { 1681 String titlePattern = title + " [{0}:{1}:{2}]"; 1682 return MessageFormat.format(titlePattern, indicators); 1683 } 1684 } 1685 1686 return title; 1687 } 1688 1689 1690 /** 1691 * Provides answers to the following splits: PayeeIsPurchaseOrderVendor RequiresTaxReview RequiresTravelReview 1692 * 1693 * @see org.kuali.kfs.sys.document.FinancialSystemTransactionalDocumentBase#answerSplitNodeQuestion(java.lang.String) 1694 */ 1695 @Override 1696 public boolean answerSplitNodeQuestion(String nodeName) throws UnsupportedOperationException { 1697 if (nodeName.equals(DisbursementVoucherDocument.PAYEE_IS_PURCHASE_ORDER_VENDOR_SPLIT)) 1698 return isPayeePurchaseOrderVendor(); 1699 if (nodeName.equals(DisbursementVoucherDocument.DOCUMENT_REQUIRES_TAX_REVIEW_SPLIT)) 1700 return isTaxReviewRequired(); 1701 if (nodeName.equals(DisbursementVoucherDocument.DOCUMENT_REQUIRES_TRAVEL_REVIEW_SPLIT)) 1702 return isTravelReviewRequired(); 1703 throw new UnsupportedOperationException("Cannot answer split question for this node you call \""+nodeName+"\""); 1704 } 1705 1706 /** 1707 * @return true if the payee is a purchase order vendor and therefore should receive vendor review, false otherwise 1708 */ 1709 protected boolean isPayeePurchaseOrderVendor() { 1710 if (!this.getDvPayeeDetail().getDisbursementVoucherPayeeTypeCode().equals(DisbursementVoucherConstants.DV_PAYEE_TYPE_VENDOR)) { 1711 return false; 1712 } 1713 1714 VendorDetail vendor = getVendorService().getByVendorNumber(this.getDvPayeeDetail().getDisbVchrPayeeIdNumber()); 1715 if (vendor == null) { 1716 return false; 1717 } 1718 1719 vendor.refreshReferenceObject("vendorHeader"); 1720 return vendor.getVendorHeader().getVendorTypeCode().equals(DisbursementVoucherDocument.PURCHASE_ORDER_VENDOR_TYPE); 1721 } 1722 1723 /** 1724 * Tax review is required under the following circumstances: the payee was an employee the payee was a non-resident alien vendor 1725 * the tax control code = "B" or "H" the payment reason code was "D" the payment reason code was "M" and the campus was listed 1726 * in the CAMPUSES_TAXED_FOR_MOVING_REIMBURSEMENTS_PARAMETER_NAME parameter 1727 * 1728 * @return true if any of the above conditions exist and this document should receive tax review, false otherwise 1729 */ 1730 protected boolean isTaxReviewRequired() { 1731 if (isPayeePurchaseOrderVendorHasWithholding()) { 1732 return true; 1733 } 1734 1735 boolean isEmployee = this.getDvPayeeDetail().isDisbVchrPayeeEmployeeCode(); 1736 if (isEmployee) { 1737 return true; 1738 } 1739 1740 String payeeTypeCode = this.getDvPayeeDetail().getDisbursementVoucherPayeeTypeCode(); 1741 if (payeeTypeCode.equals(DisbursementVoucherConstants.DV_PAYEE_TYPE_EMPLOYEE)) { 1742 return true; 1743 } 1744 1745 if (payeeTypeCode.equals(DisbursementVoucherConstants.DV_PAYEE_TYPE_VENDOR) && this.getVendorService().isVendorForeign(getDvPayeeDetail().getDisbVchrVendorHeaderIdNumberAsInteger())) { 1746 return true; 1747 } 1748 1749 String taxControlCode = this.getDisbVchrPayeeTaxControlCode(); 1750 if (StringUtils.equals(taxControlCode, DisbursementVoucherDocument.TAX_CONTROL_BACKUP_HOLDING) || StringUtils.equals(taxControlCode,DisbursementVoucherDocument.TAX_CONTROL_HOLD_PAYMENTS)) { 1751 return true; 1752 } 1753 1754 String paymentReasonCode = this.getDvPayeeDetail().getDisbVchrPaymentReasonCode(); 1755 if (this.getDvPymentReasonService().isDecedentCompensationPaymentReason(paymentReasonCode)) { 1756 return true; 1757 } 1758 1759 if (this.getDvPymentReasonService().isMovingPaymentReason(paymentReasonCode) && taxedCampusForMovingReimbursements()) { 1760 return true; 1761 } 1762 1763 if (this.getParameterService().getParameterEvaluator(this.getClass(), DisbursementVoucherDocument.PAYMENT_REASONS_REQUIRING_TAX_REVIEW_PARAMETER_NAME, paymentReasonCode).evaluationSucceeds()) { 1764 return true; 1765 } 1766 1767 return false; 1768 } 1769 1770 /** 1771 * @return true if the payee is a vendor and has withholding dates therefore should receive tax review, false otherwise 1772 */ 1773 protected boolean isPayeePurchaseOrderVendorHasWithholding() { 1774 if (!this.getDvPayeeDetail().getDisbursementVoucherPayeeTypeCode().equals(DisbursementVoucherConstants.DV_PAYEE_TYPE_VENDOR)) { 1775 return false; 1776 } 1777 1778 VendorDetail vendor = getVendorService().getByVendorNumber(this.getDvPayeeDetail().getDisbVchrPayeeIdNumber()); 1779 if (vendor == null) { 1780 return false; 1781 } 1782 1783 vendor.refreshReferenceObject("vendorHeader"); 1784 return (vendor.getVendorHeader().getVendorFederalWithholdingTaxBeginningDate()!= null || vendor.getVendorHeader().getVendorFederalWithholdingTaxEndDate()!= null); 1785 } 1786 1787 1788 /** 1789 * Determines if the campus this DV is related to is taxed (and should get tax review routing) for moving reimbursements 1790 * 1791 * @return true if the campus is taxed for moving reimbursements, false otherwise 1792 */ 1793 protected boolean taxedCampusForMovingReimbursements() { 1794 return this.getParameterService().getParameterEvaluator(this.getClass(), DisbursementVoucherConstants.CAMPUSES_TAXED_FOR_MOVING_REIMBURSEMENTS_PARM_NM, this.getCampusCode()).evaluationSucceeds(); 1795 } 1796 1797 /** 1798 * Travel review is required under the following circumstances: payment reason code is "P" or "N" 1799 * 1800 * @return 1801 */ 1802 public boolean isTravelReviewRequired() { 1803 String paymentReasonCode = this.getDvPayeeDetail().getDisbVchrPaymentReasonCode(); 1804 1805 return this.getDvPymentReasonService().isPrepaidTravelPaymentReason(paymentReasonCode) || this.getDvPymentReasonService().isNonEmployeeTravelPaymentReason(paymentReasonCode); 1806 } 1807 1808 protected PersonService<Person> getPersonService() { 1809 if ( personService == null ) { 1810 personService = SpringContext.getBean(PersonService.class); 1811 } 1812 return personService; 1813 } 1814 1815 1816 protected ParameterService getParameterService() { 1817 if ( parameterService == null ) { 1818 parameterService = SpringContext.getBean(ParameterService.class); 1819 } 1820 return parameterService; 1821 } 1822 1823 1824 protected VendorService getVendorService() { 1825 if ( vendorService == null ) { 1826 vendorService = SpringContext.getBean(VendorService.class); 1827 } 1828 return vendorService; 1829 } 1830 1831 1832 protected BusinessObjectService getBusinessObjectService() { 1833 if ( businessObjectService == null ) { 1834 businessObjectService = SpringContext.getBean(BusinessObjectService.class); 1835 } 1836 return businessObjectService; 1837 } 1838 1839 /** 1840 * Gets the dvPymentReasonService attribute. 1841 * 1842 * @return Returns the dvPymentReasonService. 1843 */ 1844 public DisbursementVoucherPaymentReasonService getDvPymentReasonService() { 1845 if (dvPymentReasonService == null) { 1846 dvPymentReasonService = SpringContext.getBean(DisbursementVoucherPaymentReasonService.class); 1847 } 1848 return dvPymentReasonService; 1849 } 1850 1851 1852 /** 1853 * Gets the identityManagementService attribute. 1854 * @return Returns the identityManagementService. 1855 */ 1856 public static IdentityManagementService getIdentityManagementService() { 1857 if (identityManagementService == null) { 1858 identityManagementService = SpringContext.getBean(IdentityManagementService.class); 1859 } 1860 return identityManagementService; 1861 } 1862 1863 /** 1864 * Sets the identityManagementService attribute value. 1865 * @param identityManagementService The identityManagementService to set. 1866 */ 1867 public static void setIdentityManagementService(IdentityManagementService identityManagementService) { 1868 DisbursementVoucherDocument.identityManagementService = identityManagementService; 1869 } 1870 /** 1871 * @return Returns the disbExcptAttachedIndicator. 1872 */ 1873 public boolean isDisbExcptAttachedIndicator() { 1874 return disbExcptAttachedIndicator; 1875 } 1876 1877 /** 1878 * @param disbExcptAttachedIndicator The disbExcptAttachedIndicator to set. 1879 */ 1880 public void setDisbExcptAttachedIndicator(boolean disbExcptAttachedIndicator) { 1881 this.disbExcptAttachedIndicator = disbExcptAttachedIndicator; 1882 } 1883 }