001/* 002 * Copyright 2007 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 */ 016package org.kuali.ole.fp.batch.service.impl; 017 018import java.sql.Timestamp; 019import java.util.ArrayList; 020import java.util.Collection; 021import java.util.Date; 022import java.util.HashSet; 023import java.util.Iterator; 024import java.util.List; 025import java.util.Set; 026 027import org.apache.commons.lang.StringUtils; 028import org.apache.commons.lang.WordUtils; 029import org.kuali.ole.fp.batch.DvToPdpExtractStep; 030import org.kuali.ole.fp.batch.service.DisbursementVoucherExtractService; 031import org.kuali.ole.fp.businessobject.DisbursementVoucherPayeeDetail; 032import org.kuali.ole.fp.dataaccess.DisbursementVoucherDao; 033import org.kuali.ole.fp.document.DisbursementVoucherConstants; 034import org.kuali.ole.fp.document.DisbursementVoucherDocument; 035import org.kuali.ole.pdp.PdpConstants; 036import org.kuali.ole.pdp.PdpParameterConstants; 037import org.kuali.ole.pdp.businessobject.Batch; 038import org.kuali.ole.pdp.businessobject.CustomerProfile; 039import org.kuali.ole.pdp.businessobject.PaymentAccountDetail; 040import org.kuali.ole.pdp.businessobject.PaymentDetail; 041import org.kuali.ole.pdp.businessobject.PaymentGroup; 042import org.kuali.ole.pdp.businessobject.PaymentNoteText; 043import org.kuali.ole.pdp.service.CustomerProfileService; 044import org.kuali.ole.pdp.service.PaymentFileService; 045import org.kuali.ole.pdp.service.PaymentGroupService; 046import org.kuali.ole.pdp.service.PdpEmailService; 047import org.kuali.ole.select.document.OleDisbursementVoucherDocument; 048import org.kuali.ole.select.document.service.OleSelectDocumentService; 049import org.kuali.ole.sys.OLEConstants; 050import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntry; 051import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper; 052import org.kuali.ole.sys.businessobject.SourceAccountingLine; 053import org.kuali.ole.sys.context.SpringContext; 054import org.kuali.ole.sys.document.service.FinancialSystemDocumentService; 055import org.kuali.ole.sys.document.validation.event.AccountingDocumentSaveWithNoLedgerEntryGenerationEvent; 056import org.kuali.ole.sys.service.GeneralLedgerPendingEntryService; 057import org.kuali.ole.sys.service.impl.OleParameterConstants; 058import org.kuali.ole.vnd.businessobject.VendorDetail; 059import org.kuali.ole.vnd.document.service.VendorService; 060import org.kuali.rice.core.api.datetime.DateTimeService; 061import org.kuali.rice.core.api.parameter.ParameterEvaluator; 062import org.kuali.rice.core.api.parameter.ParameterEvaluatorService; 063import org.kuali.rice.core.api.util.type.KualiDecimal; 064import org.kuali.rice.core.api.util.type.KualiInteger; 065import org.kuali.rice.coreservice.framework.parameter.ParameterService; 066import org.kuali.rice.kew.api.exception.WorkflowException; 067import org.kuali.rice.kim.api.identity.Person; 068import org.kuali.rice.kim.api.identity.PersonService; 069import org.kuali.rice.krad.service.BusinessObjectService; 070import org.kuali.rice.krad.service.DocumentService; 071import org.kuali.rice.krad.util.ObjectUtils; 072import org.springframework.transaction.annotation.Transactional; 073 074/** 075 * This is the default implementation of the DisbursementVoucherExtractService interface. 076 */ 077@Transactional 078public class DisbursementVoucherExtractServiceImpl implements DisbursementVoucherExtractService { 079 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DisbursementVoucherExtractServiceImpl.class); 080 081 private PersonService personService; 082 private ParameterService parameterService; 083 private DisbursementVoucherDao disbursementVoucherDao; 084 private DateTimeService dateTimeService; 085 private CustomerProfileService customerProfileService; 086 private PaymentFileService paymentFileService; 087 private PaymentGroupService paymentGroupService; 088 private BusinessObjectService businessObjectService; 089 private PdpEmailService paymentFileEmailService; 090 private int maxNoteLines; 091 private OleSelectDocumentService oleSelectDocumentService; 092 093 // This should only be set to true when testing this system. Setting this to true will run the code but 094 // won't set the doc status to extracted 095 boolean testMode = false; 096 097 /** 098 * This method extracts all payments from a disbursement voucher with a status code of "A" and uploads them as a batch for 099 * processing. 100 * 101 * @return Always returns true if the method completes. 102 * @see org.kuali.ole.fp.batch.service.DisbursementVoucherExtractService#extractPayments() 103 */ 104 @Override 105 public boolean extractPayments() { 106 LOG.debug("extractPayments() started"); 107 108 Date processRunDate = dateTimeService.getCurrentDate(); 109 110 String noteLines = parameterService.getParameterValueAsString(OleParameterConstants.PRE_DISBURSEMENT_ALL.class, PdpParameterConstants.MAX_NOTE_LINES); 111 112 try { 113 maxNoteLines = Integer.parseInt(noteLines); 114 } 115 catch (NumberFormatException nfe) { 116 throw new IllegalArgumentException("Invalid Max Notes Lines parameter"); 117 } 118 119 Person uuser = getPersonService().getPersonByPrincipalName(getOleSelectDocumentService().getSelectParameterValue(OLEConstants.SYSTEM_USER)); 120 if (uuser == null) { 121 if (LOG.isDebugEnabled()) { 122 LOG.debug("extractPayments() Unable to find user " + getOleSelectDocumentService().getSelectParameterValue(OLEConstants.SYSTEM_USER)); 123 } 124 throw new IllegalArgumentException("Unable to find user " + getOleSelectDocumentService().getSelectParameterValue(OLEConstants.SYSTEM_USER)); 125 } 126 127 // Get a list of campuses that have documents with an 'A' (approved) status. 128 Set<String> campusList = getCampusListByDocumentStatusCode(DisbursementVoucherConstants.DocumentStatusCodes.APPROVED); 129 130 // Process each campus one at a time 131 for (String campusCode : campusList) { 132 extractPaymentsForCampus(campusCode, uuser, processRunDate); 133 } 134 135 return true; 136 } 137 138 /** 139 * Pulls all disbursement vouchers with status of "A" and marked for immediate payment from the database and builds payment records for them 140 * @see org.kuali.ole.fp.batch.service.DisbursementVoucherExtractService#extractImmediatePayments() 141 */ 142 @Override 143 public void extractImmediatePayments() { 144 LOG.debug("extractImmediatePayments() started"); 145 146 Date processRunDate = dateTimeService.getCurrentDate(); 147 148 String noteLines = parameterService.getParameterValueAsString(OleParameterConstants.PRE_DISBURSEMENT_ALL.class, PdpParameterConstants.MAX_NOTE_LINES); 149 150 try { 151 maxNoteLines = Integer.parseInt(noteLines); 152 } 153 catch (NumberFormatException nfe) { 154 throw new IllegalArgumentException("Invalid Max Notes Lines parameter"); 155 } 156 157 Person uuser = getPersonService().getPersonByPrincipalName(getOleSelectDocumentService().getSelectParameterValue(OLEConstants.SYSTEM_USER)); 158 if (uuser == null) { 159 LOG.debug("extractPayments() Unable to find user " + getOleSelectDocumentService().getSelectParameterValue(OLEConstants.SYSTEM_USER)); 160 throw new IllegalArgumentException("Unable to find user " + getOleSelectDocumentService().getSelectParameterValue(OLEConstants.SYSTEM_USER)); 161 } 162 163 // Get a list of campuses that have documents with an 'A' (approved) status. 164 Set<String> campusList = getImmediatesCampusListByDocumentStatusCode(DisbursementVoucherConstants.DocumentStatusCodes.APPROVED); 165 166 // Process each campus one at a time 167 for (String campusCode : campusList) { 168 extractImmediatePaymentsForCampus(campusCode, uuser, processRunDate); 169 } 170 } 171 172 /** 173 * This method extracts all outstanding payments from all the disbursement vouchers in approved status for a given campus and 174 * adds these payments to a batch file that is uploaded for processing. 175 * 176 * @param campusCode The id code of the campus the payments will be retrieved for. 177 * @param user The user object used when creating the batch file to upload with outstanding payments. 178 * @param processRunDate This is the date that the batch file is created, often this value will be today's date. 179 */ 180 protected void extractPaymentsForCampus(String campusCode, Person user, Date processRunDate) { 181 if (LOG.isDebugEnabled()) { 182 LOG.debug("extractPaymentsForCampus() started for campus: " + campusCode); 183 } 184 185 Batch batch = createBatch(campusCode, user, processRunDate); 186 Integer count = 0; 187 KualiDecimal totalAmount = KualiDecimal.ZERO; 188 189 Collection<DisbursementVoucherDocument> dvd = getListByDocumentStatusCodeCampus(DisbursementVoucherConstants.DocumentStatusCodes.APPROVED, campusCode, false); 190 for (DisbursementVoucherDocument document : dvd) { 191 addPayment(document, batch, processRunDate, false); 192 count++; 193 totalAmount = totalAmount.add(document.getDisbVchrCheckTotalAmount()); 194 } 195 196 batch.setPaymentCount(new KualiInteger(count)); 197 batch.setPaymentTotalAmount(totalAmount); 198 199 businessObjectService.save(batch); 200 paymentFileEmailService.sendLoadEmail(batch); 201 } 202 203 /** 204 * Builds payment batch for Disbursement Vouchers marked as immediate 205 * @param campusCode the campus code the disbursement vouchers should be associated with 206 * @param user the user responsible building the payment batch (typically the System User, kfs) 207 * @param processRunDate the time that the job to build immediate payments is run 208 */ 209 protected void extractImmediatePaymentsForCampus(String campusCode, Person user, Date processRunDate) { 210 LOG.debug("extractImmediatesPaymentsForCampus() started for campus: " + campusCode); 211 212 Batch batch = createBatch(campusCode, user, processRunDate); 213 Integer count = 0; 214 KualiDecimal totalAmount = KualiDecimal.ZERO; 215 216 Collection<DisbursementVoucherDocument> dvd = getListByDocumentStatusCodeCampus(DisbursementVoucherConstants.DocumentStatusCodes.APPROVED, campusCode, true); 217 for (DisbursementVoucherDocument document : dvd) { 218 addPayment(document, batch, processRunDate, false); 219 count++; 220 totalAmount = totalAmount.add(document.getDisbVchrCheckTotalAmount()); 221 } 222 223 batch.setPaymentCount(new KualiInteger(count)); 224 batch.setPaymentTotalAmount(totalAmount); 225 226 businessObjectService.save(batch); 227 paymentFileEmailService.sendLoadEmail(batch); 228 } 229 230 /** 231 * This method creates a payment group from the disbursement voucher and batch provided and persists that group to the database. 232 * 233 * @param document The document used to build a payment group detail. 234 * @param batch The batch file used to build a payment group and detail. 235 * @param processRunDate The date the batch file is to post. 236 */ 237 protected void addPayment(DisbursementVoucherDocument document, Batch batch, Date processRunDate, boolean immediate) { 238 LOG.debug("addPayment() started"); 239 240 PaymentGroup pg = buildPaymentGroup(document, batch); 241 if (immediate) { 242 pg.setProcessImmediate(Boolean.TRUE); 243 } 244 PaymentDetail pd = buildPaymentDetail(document, batch, processRunDate); 245 246 pd.setPaymentGroup(pg); 247 pg.addPaymentDetails(pd); 248 this.businessObjectService.save(pg); 249 250 if (!testMode) { 251 try { 252 document.getFinancialSystemDocumentHeader().setFinancialDocumentStatusCode(DisbursementVoucherConstants.DocumentStatusCodes.EXTRACTED); 253 document.setExtractDate(new java.sql.Date(processRunDate.getTime())); 254 SpringContext.getBean(DocumentService.class).saveDocument(document, AccountingDocumentSaveWithNoLedgerEntryGenerationEvent.class); 255 } 256 catch (WorkflowException we) { 257 LOG.error("Could not save disbursement voucher document #" + document.getDocumentNumber() + ": " + we); 258 throw new RuntimeException(we); 259 } 260 } 261 } 262 263 /** 264 * This method creates a PaymentGroup from the disbursement voucher and batch provided. The values provided by the disbursement 265 * voucher are used to assign appropriate attributes to the payment group, including address and vendor detail information. The 266 * information added to the payment group includes tax encoding to identify if taxes should be taken out of the payment. The tax 267 * rules vary depending on the type of individual or entity being paid 268 * 269 * @param document The document to be used for retrieving the information about the vendor being paid. 270 * @param batch The batch that the payment group will be associated with. 271 * @return A PaymentGroup object fully populated with all the values necessary to make a payment. 272 */ 273 protected PaymentGroup buildPaymentGroup(DisbursementVoucherDocument document, Batch batch) { 274 LOG.debug("buildPaymentGroup() started"); 275 276 PaymentGroup pg = new PaymentGroup(); 277 pg.setBatch(batch); 278 pg.setCombineGroups(Boolean.TRUE); 279 pg.setCampusAddress(Boolean.FALSE); 280 281 DisbursementVoucherPayeeDetail pd = document.getDvPayeeDetail(); 282 String rc = pd.getDisbVchrPaymentReasonCode(); 283 284 // If the payee is an employee, set these flags accordingly 285 if ((document.getDvPayeeDetail().isVendor() && SpringContext.getBean(VendorService.class).isVendorInstitutionEmployee(pd.getDisbVchrVendorHeaderIdNumberAsInteger())) || document.getDvPayeeDetail().isEmployee()) { 286 pg.setEmployeeIndicator(Boolean.TRUE); 287 pg.setPayeeIdTypeCd(PdpConstants.PayeeIdTypeCodes.EMPLOYEE); 288 //Commented for the jira issue OLE-3415 289// pg.setTaxablePayment( 290// !/*REFACTORME*/SpringContext.getBean(ParameterEvaluatorService.class).getParameterEvaluator(DisbursementVoucherDocument.class, DisbursementVoucherConstants.RESEARCH_PAYMENT_REASONS_PARM_NM, rc).evaluationSucceeds() 291// && !parameterService.getParameterValueAsString(DisbursementVoucherDocument.class, DisbursementVoucherConstants.PAYMENT_REASON_CODE_RENTAL_PAYMENT_PARM_NM).equals(rc) 292// && !parameterService.getParameterValueAsString(DisbursementVoucherDocument.class, DisbursementVoucherConstants.PAYMENT_REASON_CODE_ROYALTIES_PARM_NM).equals(rc)); 293 } 294 // Payee is not an employee 295 else { 296 297 // These are taxable 298 VendorDetail vendDetail = SpringContext.getBean(VendorService.class).getVendorDetail(pd.getDisbVchrVendorHeaderIdNumberAsInteger(), pd.getDisbVchrVendorDetailAssignedIdNumberAsInteger()); 299 String vendorOwnerCode = vendDetail.getVendorHeader().getVendorOwnershipCode(); 300 String vendorOwnerCategoryCode = vendDetail.getVendorHeader().getVendorOwnershipCategoryCode(); 301 String payReasonCode = pd.getDisbVchrPaymentReasonCode(); 302 303 pg.setPayeeIdTypeCd(PdpConstants.PayeeIdTypeCodes.VENDOR_ID); 304 305 // Assume it is not taxable until proven otherwise 306 pg.setTaxablePayment(Boolean.FALSE); 307 pg.setPayeeOwnerCd(vendorOwnerCode); 308 309 ParameterEvaluator parameterEvaluator1 = /*REFACTORME*/SpringContext.getBean(ParameterEvaluatorService.class).getParameterEvaluator(DvToPdpExtractStep.class, PdpParameterConstants.TAXABLE_PAYMENT_REASON_CODES_BY_OWNERSHIP_CODES_PARAMETER_NAME, PdpParameterConstants.NON_TAXABLE_PAYMENT_REASON_CODES_BY_OWNERSHIP_CODES_PARAMETER_NAME, vendorOwnerCode, payReasonCode); 310 ParameterEvaluator parameterEvaluator2 = /*REFACTORME*/SpringContext.getBean(ParameterEvaluatorService.class).getParameterEvaluator(DvToPdpExtractStep.class, PdpParameterConstants.TAXABLE_PAYMENT_REASON_CODES_BY_CORPORATION_OWNERSHIP_TYPE_CATEGORY_PARAMETER_NAME, PdpParameterConstants.NON_TAXABLE_PAYMENT_REASON_CODES_BY_CORPORATION_OWNERSHIP_TYPE_CATEGORY_PARAMETER_NAME, vendorOwnerCategoryCode, payReasonCode); 311 312 if ( parameterEvaluator1.evaluationSucceeds() ) { 313 pg.setTaxablePayment(Boolean.TRUE); 314 } 315 else if (this.parameterService.getParameterValueAsString(DvToPdpExtractStep.class, PdpParameterConstants.CORPORATION_OWNERSHIP_TYPE_PARAMETER_NAME).equals("CP") && 316 StringUtils.isEmpty(vendorOwnerCategoryCode) && 317 /*REFACTORME*/SpringContext.getBean(ParameterEvaluatorService.class).getParameterEvaluator(DvToPdpExtractStep.class, PdpParameterConstants.TAXABLE_PAYMENT_REASON_CODES_FOR_BLANK_CORPORATION_OWNERSHIP_TYPE_CATEGORIES_PARAMETER_NAME, payReasonCode).evaluationSucceeds()) { 318 pg.setTaxablePayment(Boolean.TRUE); 319 } 320 else if (this.parameterService.getParameterValueAsString(DvToPdpExtractStep.class, PdpParameterConstants.CORPORATION_OWNERSHIP_TYPE_PARAMETER_NAME).equals("CP") 321 && !StringUtils.isEmpty(vendorOwnerCategoryCode) 322 && parameterEvaluator2.evaluationSucceeds() ) { 323 pg.setTaxablePayment(Boolean.TRUE); 324 } 325 } 326 327 pg.setCity(pd.getDisbVchrPayeeCityName()); 328 pg.setCountry(pd.getDisbVchrPayeeCountryCode()); 329 pg.setLine1Address(pd.getDisbVchrPayeeLine1Addr()); 330 pg.setLine2Address(pd.getDisbVchrPayeeLine2Addr()); 331 pg.setPayeeName(pd.getDisbVchrPayeePersonName()); 332 pg.setPayeeId(pd.getDisbVchrPayeeIdNumber()); 333 pg.setState(pd.getDisbVchrPayeeStateCode()); 334 pg.setZipCd(pd.getDisbVchrPayeeZipCode()); 335 pg.setPaymentDate(document.getDisbursementVoucherDueDate()); 336 337 // It doesn't look like the DV has a way to do immediate processes 338 pg.setProcessImmediate(Boolean.FALSE); 339 pg.setPymtAttachment(document.isDisbVchrAttachmentCode()); 340 pg.setPymtSpecialHandling(document.isDisbVchrSpecialHandlingCode()); 341 pg.setNraPayment(pd.isDisbVchrAlienPaymentCode()); 342 343 pg.setBankCode(document.getDisbVchrBankCode()); 344 pg.setPaymentStatusCode(OLEConstants.PdpConstants.PAYMENT_OPEN_STATUS_CODE); 345 346 return pg; 347 } 348 349 /** 350 * This method builds a payment detail object from the disbursement voucher document provided and links that detail file to the 351 * batch and process run date given. 352 * 353 * @param document The disbursement voucher document to retrieve payment information from to populate the PaymentDetail. 354 * @param batch The batch file associated with the payment. 355 * @param processRunDate The date of the payment detail invoice. 356 * @return A fully populated PaymentDetail instance. 357 */ 358 protected PaymentDetail buildPaymentDetail(DisbursementVoucherDocument document, Batch batch, Date processRunDate) { 359 LOG.debug("buildPaymentDetail() started"); 360 361 PaymentDetail pd = new PaymentDetail(); 362 if (StringUtils.isNotEmpty(document.getDocumentHeader().getOrganizationDocumentNumber())) { 363 pd.setOrganizationDocNbr(document.getDocumentHeader().getOrganizationDocumentNumber()); 364 } 365 if(((OleDisbursementVoucherDocument) document).getInvoiceNumber() != null) { 366 pd.setInvoiceNbr(((OleDisbursementVoucherDocument) document).getInvoiceNumber()); 367 } 368 pd.setCustPaymentDocNbr(document.getDocumentNumber()); 369 pd.setInvoiceDate(new java.sql.Date(processRunDate.getTime())); 370 pd.setOrigInvoiceAmount(document.getDisbVchrCheckTotalAmount()); 371 pd.setInvTotDiscountAmount(KualiDecimal.ZERO); 372 pd.setInvTotOtherCreditAmount(KualiDecimal.ZERO); 373 pd.setInvTotOtherDebitAmount(KualiDecimal.ZERO); 374 pd.setInvTotShipAmount(KualiDecimal.ZERO); 375 pd.setNetPaymentAmount(document.getDisbVchrCheckTotalAmount()); 376 pd.setPrimaryCancelledPayment(Boolean.FALSE); 377 pd.setFinancialDocumentTypeCode(DisbursementVoucherConstants.DOCUMENT_TYPE_CHECKACH); 378 pd.setFinancialSystemOriginCode(OLEConstants.ORIGIN_CODE_KUALI); 379 380 if(document.getDisbVchrPaymentMethodCode().equalsIgnoreCase(DisbursementVoucherConstants.PAYMENT_METHOD_CHECK)) { 381 pd.setPaymentMethodCode("Check"); 382 } 383 else if(document.getDisbVchrPaymentMethodCode().equalsIgnoreCase(DisbursementVoucherConstants.PAYMENT_METHOD_WIRE)) { 384 pd.setPaymentMethodCode("Wire"); 385 } 386 else if(document.getDisbVchrPaymentMethodCode().equalsIgnoreCase(DisbursementVoucherConstants.PAYMENT_METHOD_DRAFT)) { 387 pd.setPaymentMethodCode("Draft"); 388 } 389 390 // Handle accounts 391 for (Iterator iter = document.getSourceAccountingLines().iterator(); iter.hasNext();) { 392 SourceAccountingLine sal = (SourceAccountingLine) iter.next(); 393 394 PaymentAccountDetail pad = new PaymentAccountDetail(); 395 pad.setFinChartCode(sal.getChartOfAccountsCode()); 396 pad.setAccountNbr(sal.getAccountNumber()); 397 if (StringUtils.isNotEmpty(sal.getSubAccountNumber())) { 398 pad.setSubAccountNbr(sal.getSubAccountNumber()); 399 } 400 else { 401 pad.setSubAccountNbr(OLEConstants.getDashSubAccountNumber()); 402 } 403 pad.setFinObjectCode(sal.getFinancialObjectCode()); 404 if (StringUtils.isNotEmpty(sal.getFinancialSubObjectCode())) { 405 pad.setFinSubObjectCode(sal.getFinancialSubObjectCode()); 406 } 407 else { 408 pad.setFinSubObjectCode(OLEConstants.getDashFinancialSubObjectCode()); 409 } 410 if (StringUtils.isNotEmpty(sal.getOrganizationReferenceId())) { 411 pad.setOrgReferenceId(sal.getOrganizationReferenceId()); 412 } 413 if (StringUtils.isNotEmpty(sal.getProjectCode())) { 414 pad.setProjectCode(sal.getProjectCode()); 415 } 416 else { 417 pad.setProjectCode(OLEConstants.getDashProjectCode()); 418 } 419 pad.setAccountNetAmount(sal.getAmount()); 420 pd.addAccountDetail(pad); 421 } 422 423 // Handle notes 424 DisbursementVoucherPayeeDetail dvpd = document.getDvPayeeDetail(); 425 426 int line = 0; 427 PaymentNoteText pnt = new PaymentNoteText(); 428 pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); 429 pnt.setCustomerNoteText("Info: " + document.getDisbVchrContactPersonName() + " " + document.getDisbVchrContactPhoneNumber()); 430 pd.addNote(pnt); 431 432 String dvSpecialHandlingPersonName = null; 433 String dvSpecialHandlingLine1Address = null; 434 String dvSpecialHandlingLine2Address = null; 435 String dvSpecialHandlingCity = null; 436 String dvSpecialHandlingState = null; 437 String dvSpecialHandlingZip = null; 438 439 dvSpecialHandlingPersonName = dvpd.getDisbVchrSpecialHandlingPersonName(); 440 dvSpecialHandlingLine1Address = dvpd.getDisbVchrSpecialHandlingLine1Addr(); 441 dvSpecialHandlingLine2Address = dvpd.getDisbVchrSpecialHandlingLine2Addr(); 442 dvSpecialHandlingCity = dvpd.getDisbVchrSpecialHandlingCityName(); 443 dvSpecialHandlingState = dvpd.getDisbVchrSpecialHandlingStateCode(); 444 dvSpecialHandlingZip = dvpd.getDisbVchrSpecialHandlingZipCode(); 445 446 if (StringUtils.isNotEmpty(dvSpecialHandlingPersonName)) { 447 pnt = new PaymentNoteText(); 448 pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); 449 pnt.setCustomerNoteText("Send Check To: " + dvSpecialHandlingPersonName); 450 if (LOG.isDebugEnabled()) { 451 LOG.debug("Creating special handling person name note: "+pnt.getCustomerNoteText()); 452 } 453 pd.addNote(pnt); 454 } 455 if (StringUtils.isNotEmpty(dvSpecialHandlingLine1Address)) { 456 pnt = new PaymentNoteText(); 457 pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); 458 pnt.setCustomerNoteText(dvSpecialHandlingLine1Address); 459 if (LOG.isDebugEnabled()) { 460 LOG.debug("Creating special handling address 1 note: "+pnt.getCustomerNoteText()); 461 } 462 pd.addNote(pnt); 463 } 464 if (StringUtils.isNotEmpty(dvSpecialHandlingLine2Address)) { 465 pnt = new PaymentNoteText(); 466 pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); 467 pnt.setCustomerNoteText(dvSpecialHandlingLine2Address); 468 if (LOG.isDebugEnabled()) { 469 LOG.debug("Creating special handling address 2 note: "+pnt.getCustomerNoteText()); 470 } 471 pd.addNote(pnt); 472 } 473 if (StringUtils.isNotEmpty(dvSpecialHandlingCity)) { 474 pnt = new PaymentNoteText(); 475 pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); 476 pnt.setCustomerNoteText(dvSpecialHandlingCity + ", " + dvSpecialHandlingState + " " + dvSpecialHandlingZip); 477 if (LOG.isDebugEnabled()) { 478 LOG.debug("Creating special handling city note: "+pnt.getCustomerNoteText()); 479 } 480 pd.addNote(pnt); 481 } 482 if (document.isDisbVchrAttachmentCode()) { 483 pnt = new PaymentNoteText(); 484 pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); 485 pnt.setCustomerNoteText("Attachment Included"); 486 if (LOG.isDebugEnabled()) { 487 LOG.debug("create attachment note: "+pnt.getCustomerNoteText()); 488 } 489 pd.addNote(pnt); 490 } 491 492 String paymentReasonCode = dvpd.getDisbVchrPaymentReasonCode(); 493 //Commented for the jira issue OLE-3415 494 /*if (SpringContext.getBean(ParameterEvaluatorService.class).getParameterEvaluator(DisbursementVoucherDocument.class, DisbursementVoucherConstants.NONEMPLOYEE_TRAVEL_PAY_REASONS_PARM_NM, paymentReasonCode).evaluationSucceeds()) { 495 DisbursementVoucherNonEmployeeTravel dvnet = document.getDvNonEmployeeTravel(); 496 497 pnt = new PaymentNoteText(); 498 pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); 499 pnt.setCustomerNoteText("Reimbursement associated with " + dvnet.getDisbVchrServicePerformedDesc()); 500 if (LOG.isDebugEnabled()) { 501 LOG.debug("Creating non employee travel notes: "+pnt.getCustomerNoteText()); 502 } 503 pd.addNote(pnt); 504 505 pnt = new PaymentNoteText(); 506 pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); 507 pnt.setCustomerNoteText("The total per diem amount for your daily expenses is " + dvnet.getDisbVchrPerdiemCalculatedAmt()); 508 if (LOG.isDebugEnabled()) { 509 LOG.debug("Creating non employee travel notes: "+pnt.getCustomerNoteText()); 510 } 511 pd.addNote(pnt); 512 513 if (dvnet.getDisbVchrPersonalCarAmount() != null && dvnet.getDisbVchrPersonalCarAmount().compareTo(KualiDecimal.ZERO) != 0) { 514 pnt = new PaymentNoteText(); 515 pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); 516 pnt.setCustomerNoteText("The total dollar amount for your vehicle mileage is " + dvnet.getDisbVchrPersonalCarAmount()); 517 if (LOG.isDebugEnabled()) { 518 LOG.debug("Creating non employee travel vehicle note: "+pnt.getCustomerNoteText()); 519 } 520 pd.addNote(pnt); 521 522 for (Iterator iter = dvnet.getDvNonEmployeeExpenses().iterator(); iter.hasNext();) { 523 DisbursementVoucherNonEmployeeExpense exp = (DisbursementVoucherNonEmployeeExpense) iter.next(); 524 525 if (line < (maxNoteLines - 8)) { 526 pnt = new PaymentNoteText(); 527 pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); 528 pnt.setCustomerNoteText(exp.getDisbVchrExpenseCompanyName() + " " + exp.getDisbVchrExpenseAmount()); 529 if (LOG.isDebugEnabled()) { 530 LOG.debug("Creating non employee travel expense note: "+pnt.getCustomerNoteText()); 531 } 532 pd.addNote(pnt); 533 } 534 } 535 } 536 } 537 else if (SpringContext.getBean(ParameterEvaluatorService.class).getParameterEvaluator(DisbursementVoucherDocument.class, DisbursementVoucherConstants.PREPAID_TRAVEL_PAYMENT_REASONS_PARM_NM, paymentReasonCode).evaluationSucceeds()) { 538 pnt = new PaymentNoteText(); 539 pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); 540 pnt.setCustomerNoteText("Payment is for the following individuals/charges:"); 541 pd.addNote(pnt); 542 if (LOG.isDebugEnabled()) { 543 LOG.info("Creating prepaid travel note note: "+pnt.getCustomerNoteText()); 544 } 545 546 DisbursementVoucherPreConferenceDetail dvpcd = document.getDvPreConferenceDetail(); 547 548 for (Iterator iter = dvpcd.getDvPreConferenceRegistrants().iterator(); iter.hasNext();) { 549 DisbursementVoucherPreConferenceRegistrant dvpcr = (DisbursementVoucherPreConferenceRegistrant) iter.next(); 550 551 if (line < (maxNoteLines - 8)) { 552 pnt = new PaymentNoteText(); 553 pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); 554 pnt.setCustomerNoteText(dvpcr.getDvConferenceRegistrantName() + " " + dvpcr.getDisbVchrExpenseAmount()); 555 if (LOG.isDebugEnabled()) { 556 LOG.debug("Creating pre-paid conference registrants note: "+pnt.getCustomerNoteText()); 557 } 558 pd.addNote(pnt); 559 } 560 } 561 }*/ 562 563 // Get the original, raw form, note text from the DV document. 564 String text = document.getDisbVchrCheckStubText(); 565 if (text != null && text.length() > 0) { 566 567 // The WordUtils should be sufficient for the majority of cases. This method will 568 // word wrap the whole string based on the MAX_NOTE_LINE_SIZE, separating each wrapped 569 // word by a newline character. The 'wrap' method adds line feeds to the end causing 570 // the character length to exceed the max length by 1, hence the need for the replace 571 // method before splitting. 572 String wrappedText = WordUtils.wrap(text, DisbursementVoucherConstants.MAX_NOTE_LINE_SIZE); 573 String[] noteLines = wrappedText.replaceAll("[\r]", "").split("\\n"); 574 575 // Loop through all the note lines. 576 for (String noteLine : noteLines) { 577 if (line < (maxNoteLines - 3) && !StringUtils.isEmpty(noteLine)) { 578 579 // This should only happen if we encounter a word that is greater than the max length. 580 // The only concern I have for this occurring is with URLs/email addresses. 581 if (noteLine.length() > DisbursementVoucherConstants.MAX_NOTE_LINE_SIZE) { 582 for (String choppedWord : chopWord(noteLine, DisbursementVoucherConstants.MAX_NOTE_LINE_SIZE)) { 583 584 // Make sure we're still under the maximum number of note lines. 585 if (line < (maxNoteLines - 3) && !StringUtils.isEmpty(choppedWord)) { 586 pnt = new PaymentNoteText(); 587 pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); 588 pnt.setCustomerNoteText(choppedWord.replaceAll("\\n", "").trim()); 589 } 590 // We can't add any additional note lines, or we'll exceed the maximum, therefore 591 // just break out of the loop early - there's nothing left to do. 592 else { 593 break; 594 } 595 } 596 } 597 // This should be the most common case. Simply create a new PaymentNoteText, 598 // add the line at the correct line location. 599 else { 600 pnt = new PaymentNoteText(); 601 pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); 602 pnt.setCustomerNoteText(noteLine.replaceAll("\\n", "").trim()); 603 } 604 605 // Logging... 606 if (LOG.isDebugEnabled()) { 607 LOG.debug("Creating check stub text note: " + pnt.getCustomerNoteText()); 608 } 609 pd.addNote(pnt); 610 } 611 } 612 } 613 614 return pd; 615 } 616 617 /** 618 * This method will take a word and simply chop into smaller 619 * text segments that satisfy the limit requirements. All words 620 * brute force chopped, with no regard to preserving whole words. 621 * 622 * For example: 623 * 624 * "Java is a fun programming language!" 625 * 626 * Might be chopped into: 627 * 628 * "Java is a fun prog" 629 * "ramming language!" 630 * 631 * @param word The word that needs chopping 632 * @param limit Number of character that should represent a chopped word 633 * @return String [] of chopped words 634 */ 635 private String [] chopWord(String word, int limit) 636 { 637 StringBuilder builder = new StringBuilder(); 638 if (word != null && word.trim().length() > 0) { 639 640 char[] chars = word.toCharArray(); 641 int index = 0; 642 643 // First process all the words that fit into the limit. 644 for (int i = 0; i < chars.length/limit; i++) { 645 builder.append(String.copyValueOf(chars, index, limit)); 646 builder.append("\n"); 647 648 index += limit; 649 } 650 651 // Not all words will fit perfectly into the limit amount, so 652 // calculate the modulus value to determine any remaining characters. 653 int modValue = chars.length%limit; 654 if (modValue > 0) { 655 builder.append(String.copyValueOf(chars, index, modValue)); 656 } 657 658 } 659 660 // Split the chopped words into individual segments. 661 return builder.toString().split("\\n"); 662 } 663 664 /** 665 * This method creates a Batch instance and populates it with the information provided. 666 * 667 * @param campusCode The campus code used to retrieve a customer profile to be set on the batch. 668 * @param user The user who submitted the batch. 669 * @param processRunDate The date the batch was submitted and the date the customer profile was generated. 670 * @return A fully populated batch instance. 671 */ 672 protected Batch createBatch(String campusCode, Person user, Date processRunDate) { 673 String orgCode = parameterService.getParameterValueAsString(DisbursementVoucherDocument.class, DisbursementVoucherConstants.DvPdpExtractGroup.DV_PDP_ORG_CODE); 674 String subUnitCode = parameterService.getParameterValueAsString(DisbursementVoucherDocument.class, DisbursementVoucherConstants.DvPdpExtractGroup.DV_PDP_SBUNT_CODE); 675 CustomerProfile customer = customerProfileService.get(campusCode, orgCode, subUnitCode); 676 if (customer == null) { 677 throw new IllegalArgumentException("Unable to find customer profile for " + campusCode + "/" + orgCode + "/" + subUnitCode); 678 } 679 680 // Create the group for this campus 681 Batch batch = new Batch(); 682 batch.setCustomerProfile(customer); 683 batch.setCustomerFileCreateTimestamp(new Timestamp(processRunDate.getTime())); 684 batch.setFileProcessTimestamp(new Timestamp(processRunDate.getTime())); 685 batch.setPaymentFileName(OLEConstants.DISBURSEMENT_VOUCHER_PDP_EXTRACT_FILE_NAME); 686 batch.setSubmiterUserId(user.getPrincipalId()); 687 688 // Set these for now, we will update them later 689 batch.setPaymentCount(KualiInteger.ZERO); 690 batch.setPaymentTotalAmount(KualiDecimal.ZERO); 691 692 businessObjectService.save(batch); 693 694 return batch; 695 } 696 697 /** 698 * This method retrieves a collection of campus instances representing all the campuses which currently have disbursement 699 * vouchers with the status code provided. 700 * 701 * @param statusCode The status code to retrieve disbursement vouchers by. 702 * @return A collection of campus codes of all the campuses with disbursement vouchers in the status given. 703 */ 704 protected Set<String> getCampusListByDocumentStatusCode(String statusCode) { 705 LOG.debug("getCampusListByDocumentStatusCode() started"); 706 707 Set<String> campusSet = new HashSet<String>(); 708 709 Collection<DisbursementVoucherDocument> docs = disbursementVoucherDao.getDocumentsByHeaderStatus(statusCode, false); 710 for (DisbursementVoucherDocument element : docs) { 711 String dvdCampusCode = element.getCampusCode(); 712 campusSet.add(dvdCampusCode); 713 } 714 715 return campusSet; 716 } 717 718 /** 719 * Retrieves a list of campuses which have Disbursement Vouchers ready to be process which are marked for immediate processing 720 * @param statusCode the status code of the documents to retrieve 721 * @return the Set of campuses which have DV which are up for immediate disbursement 722 */ 723 protected Set<String> getImmediatesCampusListByDocumentStatusCode(String statusCode) { 724 LOG.debug("getCampusListByDocumentStatusCode() started"); 725 726 Set<String> campusSet = new HashSet<String>(); 727 728 Collection<DisbursementVoucherDocument> docs = disbursementVoucherDao.getDocumentsByHeaderStatus(statusCode, true); 729 for (DisbursementVoucherDocument element : docs) { 730 731 final String dvdCampusCode = element.getCampusCode(); 732 campusSet.add(dvdCampusCode); 733 } 734 735 return campusSet; 736 } 737 738 /** 739 * This method retrieves a list of disbursement voucher documents that are in the status provided for the campus code given. 740 * 741 * @param statusCode The status of the disbursement vouchers to be retrieved. 742 * @param campusCode The campus code that the disbursement vouchers will be associated with. 743 * @param immediatesOnly only retrieve Disbursement Vouchers marked for immediate payment 744 * @return A collection of disbursement voucher objects that meet the search criteria given. 745 */ 746 protected Collection<DisbursementVoucherDocument> getListByDocumentStatusCodeCampus(String statusCode, String campusCode, boolean immediatesOnly) { 747 LOG.debug("getListByDocumentStatusCodeCampus() started"); 748 749 Collection<DisbursementVoucherDocument> list = new ArrayList<DisbursementVoucherDocument>(); 750 751 try { 752 Collection<DisbursementVoucherDocument> docs = SpringContext.getBean(FinancialSystemDocumentService.class).findByDocumentHeaderStatusCode(DisbursementVoucherDocument.class, statusCode); 753 for (DisbursementVoucherDocument element : docs) { 754 String dvdCampusCode = element.getCampusCode(); 755 756 if (dvdCampusCode.equals(campusCode) && DisbursementVoucherConstants.PAYMENT_METHOD_CHECK.equals(element.getDisbVchrPaymentMethodCode())) { 757 if ((immediatesOnly && element.isImmediatePaymentIndicator()) || !immediatesOnly) { 758 list.add(element); 759 } 760 } 761 } 762 } 763 catch (WorkflowException we) { 764 LOG.error("Could not load Disbursement Voucher Documents with status code = " + statusCode + ": " + we); 765 throw new RuntimeException(we); 766 } 767 768 return list; 769 } 770 771 /** 772 * This cancels the disbursement voucher 773 * 774 * @param dv the disbursement voucher document to cancel 775 * @param processDate the date of the cancelation 776 * @see org.kuali.ole.fp.batch.service.DisbursementVoucherExtractService#cancelExtractedDisbursementVoucher(org.kuali.ole.fp.document.DisbursementVoucherDocument, java.sql.Date) 777 */ 778 @Override 779 public void cancelExtractedDisbursementVoucher(DisbursementVoucherDocument dv, java.sql.Date processDate) { 780 if (dv.getCancelDate() == null) { 781 try { 782 BusinessObjectService boService = SpringContext.getBean(BusinessObjectService.class); 783 // set the canceled date 784 dv.setCancelDate(processDate); 785 dv.refreshReferenceObject("generalLedgerPendingEntries"); 786 if (ObjectUtils.isNull(dv.getGeneralLedgerPendingEntries()) || dv.getGeneralLedgerPendingEntries().size() == 0) { 787 // generate all the pending entries for the document 788 SpringContext.getBean(GeneralLedgerPendingEntryService.class).generateGeneralLedgerPendingEntries(dv); 789 // for each pending entry, opposite-ify it and reattach it to the document 790 GeneralLedgerPendingEntrySequenceHelper glpeSeqHelper = new GeneralLedgerPendingEntrySequenceHelper(); 791 for (GeneralLedgerPendingEntry glpe : dv.getGeneralLedgerPendingEntries()) { 792 oppositifyEntry(glpe, boService, glpeSeqHelper); 793 } 794 } 795 else { 796 List<GeneralLedgerPendingEntry> newGLPEs = new ArrayList<GeneralLedgerPendingEntry>(); 797 GeneralLedgerPendingEntrySequenceHelper glpeSeqHelper = new GeneralLedgerPendingEntrySequenceHelper(dv.getGeneralLedgerPendingEntries().size() + 1); 798 for (GeneralLedgerPendingEntry glpe : dv.getGeneralLedgerPendingEntries()) { 799 glpe.refresh(); 800 if (glpe.getFinancialDocumentApprovedCode().equals(OLEConstants.PENDING_ENTRY_APPROVED_STATUS_CODE.PROCESSED)) { 801 // damn! it got processed! well, make a copy, oppositify, and save 802 GeneralLedgerPendingEntry undoer = new GeneralLedgerPendingEntry(glpe); 803 oppositifyEntry(undoer, boService, glpeSeqHelper); 804 newGLPEs.add(undoer); 805 } 806 else { 807 // just delete the GLPE before anything happens to it 808 boService.delete(glpe); 809 } 810 } 811 dv.setGeneralLedgerPendingEntries(newGLPEs); 812 } 813 // set the financial document status to canceled 814 dv.getFinancialSystemDocumentHeader().setFinancialDocumentStatusCode(OLEConstants.DocumentStatusCodes.CANCELLED); 815 // save the document 816 SpringContext.getBean(DocumentService.class).saveDocument(dv, AccountingDocumentSaveWithNoLedgerEntryGenerationEvent.class); 817 } 818 catch (WorkflowException we) { 819 LOG.error("encountered workflow exception while attempting to save Disbursement Voucher: " + dv.getDocumentNumber() + " " + we); 820 throw new RuntimeException(we); 821 } 822 } 823 } 824 825 /** 826 * Updates the given general ledger pending entry so that it will have the opposite effect of what it was created to do; this, 827 * in effect, undoes the entries that were already posted for this document 828 * 829 * @param glpe the general ledger pending entry to undo 830 */ 831 protected void oppositifyEntry(GeneralLedgerPendingEntry glpe, BusinessObjectService boService, GeneralLedgerPendingEntrySequenceHelper glpeSeqHelper) { 832 if (glpe.getTransactionDebitCreditCode().equals(OLEConstants.GL_CREDIT_CODE)) { 833 glpe.setTransactionDebitCreditCode(OLEConstants.GL_DEBIT_CODE); 834 } 835 else if (glpe.getTransactionDebitCreditCode().equals(OLEConstants.GL_DEBIT_CODE)) { 836 glpe.setTransactionDebitCreditCode(OLEConstants.GL_CREDIT_CODE); 837 } 838 glpe.setTransactionLedgerEntrySequenceNumber(glpeSeqHelper.getSequenceCounter()); 839 glpeSeqHelper.increment(); 840 glpe.setFinancialDocumentApprovedCode(OLEConstants.PENDING_ENTRY_APPROVED_STATUS_CODE.APPROVED); 841 boService.save(glpe); 842 } 843 844 /** 845 * This updates the disbursement voucher so that when it is re-extracted, information about it will be accurate 846 * 847 * @param dv the disbursement voucher document to reset 848 * @param processDate the date of the reseting 849 * @see org.kuali.ole.fp.batch.service.DisbursementVoucherExtractService#resetExtractedDisbursementVoucher(org.kuali.ole.fp.document.DisbursementVoucherDocument, java.sql.Date) 850 */ 851 @Override 852 public void resetExtractedDisbursementVoucher(DisbursementVoucherDocument dv, java.sql.Date processDate) { 853 try { 854 // 1. reset the extracted date 855 dv.setExtractDate(null); 856 dv.setPaidDate(null); 857 // 2. save the doc 858 SpringContext.getBean(DocumentService.class).saveDocument(dv, AccountingDocumentSaveWithNoLedgerEntryGenerationEvent.class); 859 } 860 catch (WorkflowException we) { 861 LOG.error("encountered workflow exception while attempting to save Disbursement Voucher: " + dv.getDocumentNumber() + " " + we); 862 throw new RuntimeException(we); 863 } 864 } 865 866 /** 867 * Looks up the document using document service, and deals with any nasty WorkflowException or ClassCastExceptions that pop up 868 * 869 * @param documentNumber the number of the document to look up 870 * @return the dv doc if found, or null otherwise 871 * @see org.kuali.ole.fp.batch.service.DisbursementVoucherExtractService#getDocumentById(java.lang.String) 872 */ 873 @Override 874 public DisbursementVoucherDocument getDocumentById(String documentNumber) { 875 DisbursementVoucherDocument dv = null; 876 try { 877 dv = (DisbursementVoucherDocument) SpringContext.getBean(DocumentService.class).getByDocumentHeaderId(documentNumber); 878 } 879 catch (WorkflowException we) { 880 LOG.error("encountered workflow exception while attempting to retrieve Disbursement Voucher: " + dv.getDocumentNumber() + " " + we); 881 throw new RuntimeException(we); 882 } 883 return dv; 884 } 885 886 /** 887 * Marks the disbursement voucher as paid by setting its paid date 888 * 889 * @param dv the dv document to mark as paid 890 * @param processDate the date when the dv was paid 891 * @see org.kuali.ole.fp.batch.service.DisbursementVoucherExtractService#markDisbursementVoucherAsPaid(org.kuali.ole.fp.document.DisbursementVoucherDocument, java.sql.Date) 892 */ 893 @Override 894 public void markDisbursementVoucherAsPaid(DisbursementVoucherDocument dv, java.sql.Date processDate) { 895 try { 896 dv.setPaidDate(processDate); 897 SpringContext.getBean(DocumentService.class).saveDocument(dv, AccountingDocumentSaveWithNoLedgerEntryGenerationEvent.class); 898 } 899 catch (WorkflowException we) { 900 LOG.error("encountered workflow exception while attempting to save Disbursement Voucher: " + dv.getDocumentNumber() + " " + we); 901 throw new RuntimeException(we); 902 } 903 } 904 905 906 907 /** 908 * Extracts a single DisbursementVoucherDocument 909 * @see org.kuali.ole.fp.batch.service.DisbursementVoucherExtractService#extractImmediatePayment(org.kuali.ole.fp.document.DisbursementVoucherDocument) 910 */ 911 @Override 912 public void extractImmediatePayment(DisbursementVoucherDocument disbursementVoucher) { 913 if (LOG.isDebugEnabled()) { 914 LOG.debug("extractImmediatePayment(DisbursementVoucherDocument) started"); 915 } 916 Date processRunDate = dateTimeService.getCurrentDate(); 917 String noteLines = parameterService.getParameterValueAsString(OleParameterConstants.PRE_DISBURSEMENT_ALL.class, PdpParameterConstants.MAX_NOTE_LINES); 918 try { 919 maxNoteLines = Integer.parseInt(noteLines); 920 } 921 catch (NumberFormatException nfe) { 922 throw new IllegalArgumentException("Invalid Max Notes Lines parameter"); 923 } 924 Person user = getPersonService().getPersonByPrincipalName(getOleSelectDocumentService().getSelectParameterValue(OLEConstants.SYSTEM_USER)); 925 if (user == null) { 926 LOG.debug("extractPayments() Unable to find user " + getOleSelectDocumentService().getSelectParameterValue(OLEConstants.SYSTEM_USER)); 927 throw new IllegalArgumentException("Unable to find user " + getOleSelectDocumentService().getSelectParameterValue(OLEConstants.SYSTEM_USER)); 928 } 929 930 Batch batch = createBatch(disbursementVoucher.getCampusCode(), user, processRunDate); 931 KualiDecimal totalAmount = KualiDecimal.ZERO; 932 933 addPayment(disbursementVoucher, batch, processRunDate, true); 934 totalAmount = totalAmount.add(disbursementVoucher.getDisbVchrCheckTotalAmount()); 935 936 batch.setPaymentCount(new KualiInteger(1)); 937 batch.setPaymentTotalAmount(totalAmount); 938 939 businessObjectService.save(batch); 940 paymentFileEmailService.sendDisbursementVoucherImmediateExtractEmail(disbursementVoucher, user); 941 } 942 943 /** 944 * This method sets the disbursementVoucherDao instance. 945 * 946 * @param disbursementVoucherDao The DisbursementVoucherDao to be set. 947 */ 948 public void setDisbursementVoucherDao(DisbursementVoucherDao disbursementVoucherDao) { 949 this.disbursementVoucherDao = disbursementVoucherDao; 950 } 951 952 /** 953 * This method sets the ParameterService instance. 954 * 955 * @param parameterService The ParameterService to be set. 956 */ 957 public void setParameterService(ParameterService parameterService) { 958 this.parameterService = parameterService; 959 } 960 961 /** 962 * This method sets the dateTimeService instance. 963 * 964 * @param dateTimeService The DateTimeService to be set. 965 */ 966 public void setDateTimeService(DateTimeService dateTimeService) { 967 this.dateTimeService = dateTimeService; 968 } 969 970 /** 971 * This method sets the customerProfileService instance. 972 * 973 * @param customerProfileService The CustomerProfileService to be set. 974 */ 975 public void setCustomerProfileService(CustomerProfileService customerProfileService) { 976 this.customerProfileService = customerProfileService; 977 } 978 979 /** 980 * This method sets the paymentFileService instance. 981 * 982 * @param paymentFileService The PaymentFileService to be set. 983 */ 984 public void setPaymentFileService(PaymentFileService paymentFileService) { 985 this.paymentFileService = paymentFileService; 986 } 987 988 /** 989 * This method sets the paymentGroupService instance. 990 * 991 * @param paymentGroupService The PaymentGroupService to be set. 992 */ 993 public void setPaymentGroupService(PaymentGroupService paymentGroupService) { 994 this.paymentGroupService = paymentGroupService; 995 } 996 997 /** 998 * Sets the businessObjectService attribute value. 999 * 1000 * @param businessObjectService The businessObjectService to set. 1001 */ 1002 public void setBusinessObjectService(BusinessObjectService businessObjectService) { 1003 this.businessObjectService = businessObjectService; 1004 } 1005 1006 /** 1007 * Sets the paymentFileEmailService attribute value. 1008 * 1009 * @param paymentFileEmailService The paymentFileEmailService to set. 1010 */ 1011 public void setPaymentFileEmailService(PdpEmailService paymentFileEmailService) { 1012 this.paymentFileEmailService = paymentFileEmailService; 1013 } 1014 1015 /** 1016 * @return Returns the personService. 1017 */ 1018 protected PersonService getPersonService() { 1019 if(personService==null) { 1020 personService = SpringContext.getBean(PersonService.class); 1021 } 1022 return personService; 1023 } 1024 1025 public OleSelectDocumentService getOleSelectDocumentService() { 1026 if(oleSelectDocumentService == null){ 1027 oleSelectDocumentService = SpringContext.getBean(OleSelectDocumentService.class); 1028 } 1029 return oleSelectDocumentService; 1030 } 1031 1032 public void setOleSelectDocumentService(OleSelectDocumentService oleSelectDocumentService) { 1033 this.oleSelectDocumentService = oleSelectDocumentService; 1034 } 1035 1036}