001 /* 002 * Copyright 2011 The Kuali Foundation. 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.kfs.module.ar.document.service.impl; 017 018 import java.util.ArrayList; 019 import java.util.Collection; 020 import java.util.HashMap; 021 import java.util.List; 022 import java.util.Map; 023 024 import org.apache.commons.lang.StringUtils; 025 import org.kuali.kfs.coa.businessobject.ObjectCode; 026 import org.kuali.kfs.coa.service.ObjectCodeService; 027 import org.kuali.kfs.module.ar.ArConstants; 028 import org.kuali.kfs.module.ar.ArPropertyConstants; 029 import org.kuali.kfs.module.ar.batch.service.CustomerInvoiceWriteoffBatchService; 030 import org.kuali.kfs.module.ar.batch.vo.CustomerInvoiceWriteoffBatchVO; 031 import org.kuali.kfs.module.ar.businessobject.AccountsReceivableDocumentHeader; 032 import org.kuali.kfs.module.ar.businessobject.CustomerInvoiceDetail; 033 import org.kuali.kfs.module.ar.businessobject.CustomerInvoiceWriteoffLookupResult; 034 import org.kuali.kfs.module.ar.businessobject.InvoicePaidApplied; 035 import org.kuali.kfs.module.ar.businessobject.OrganizationAccountingDefault; 036 import org.kuali.kfs.module.ar.businessobject.lookup.CustomerInvoiceWriteoffLookupUtil; 037 import org.kuali.kfs.module.ar.document.CustomerCreditMemoDocument; 038 import org.kuali.kfs.module.ar.document.CustomerInvoiceDocument; 039 import org.kuali.kfs.module.ar.document.CustomerInvoiceWriteoffDocument; 040 import org.kuali.kfs.module.ar.document.service.AccountsReceivableDocumentHeaderService; 041 import org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService; 042 import org.kuali.kfs.module.ar.document.service.CustomerInvoiceWriteoffDocumentService; 043 import org.kuali.kfs.module.ar.document.service.CustomerService; 044 import org.kuali.kfs.module.ar.document.service.InvoicePaidAppliedService; 045 import org.kuali.kfs.sys.KFSConstants; 046 import org.kuali.kfs.sys.businessobject.ChartOrgHolder; 047 import org.kuali.kfs.sys.context.SpringContext; 048 import org.kuali.kfs.sys.service.FinancialSystemUserService; 049 import org.kuali.kfs.sys.service.UniversityDateService; 050 import org.kuali.rice.kew.exception.WorkflowException; 051 import org.kuali.rice.kim.bo.Person; 052 import org.kuali.rice.kns.exception.UnknownDocumentIdException; 053 import org.kuali.rice.kns.service.BusinessObjectService; 054 import org.kuali.rice.kns.service.DateTimeService; 055 import org.kuali.rice.kns.service.DocumentService; 056 import org.kuali.rice.kns.service.ParameterService; 057 import org.kuali.rice.kns.util.GlobalVariables; 058 import org.kuali.rice.kns.util.KualiDecimal; 059 import org.kuali.rice.kns.util.ObjectUtils; 060 import org.kuali.rice.kns.workflow.service.KualiWorkflowDocument; 061 import org.kuali.rice.kns.workflow.service.WorkflowDocumentService; 062 import org.springframework.transaction.annotation.Transactional; 063 064 @Transactional 065 public class CustomerInvoiceWriteoffDocumentServiceImpl implements CustomerInvoiceWriteoffDocumentService { 066 067 private ParameterService parameterService; 068 private UniversityDateService universityDateService; 069 private BusinessObjectService businessObjectService; 070 private AccountsReceivableDocumentHeaderService accountsReceivableDocumentHeaderService; 071 private CustomerInvoiceDocumentService customerInvoiceDocumentService; 072 private CustomerService customerService; 073 private DocumentService documentService; 074 private CustomerInvoiceWriteoffBatchService invoiceWriteoffBatchService; 075 private DateTimeService dateTimeService; 076 private InvoicePaidAppliedService<CustomerInvoiceDetail> paidAppliedService; 077 078 079 /** 080 * 081 * @see org.kuali.kfs.module.ar.document.service.CustomerInvoiceWriteoffDocumentService#completeWriteoffProcess(org.kuali.kfs.module.ar.document.CustomerInvoiceWriteoffDocument) 082 */ 083 public void completeWriteoffProcess(CustomerInvoiceWriteoffDocument writeoff) { 084 085 // retrieve the document and make sure its not already closed, crash if so 086 String invoiceNumber = writeoff.getFinancialDocumentReferenceInvoiceNumber(); 087 CustomerInvoiceDocument invoice; 088 try { 089 invoice = (CustomerInvoiceDocument) documentService.getByDocumentHeaderId(invoiceNumber); 090 } 091 catch (WorkflowException e) { 092 throw new RuntimeException("A WorkflowException was generated when trying to load Customer Invoice #" + invoiceNumber + ".", e); 093 } 094 if (!invoice.isOpenInvoiceIndicator()) { 095 throw new UnsupportedOperationException("The Invoice Writeoff Document #" + writeoff.getDocumentNumber() + " attempted to writeoff " + 096 "an Invoice [#" + invoiceNumber + "] that was already closed. This is not supported."); 097 } 098 099 Integer paidAppliedItemNumber = 0; 100 KualiDecimal totalApplied = KualiDecimal.ZERO; 101 102 // retrieve the customer invoice details, and generate paid applieds for each 103 List<CustomerInvoiceDetail> invoiceDetails = invoice.getCustomerInvoiceDetailsWithoutDiscounts(); 104 for (CustomerInvoiceDetail invoiceDetail : invoiceDetails) { 105 106 // if no open amount on the detail, then do nothing 107 if (invoiceDetail.getAmountOpen().isZero()) { 108 continue; 109 } 110 111 // retrieve the number of current paid applieds, so we dont have item number overlap 112 if (paidAppliedItemNumber == 0) { 113 paidAppliedItemNumber = paidAppliedService.getNumberOfInvoicePaidAppliedsForInvoiceDetail(invoiceNumber, 114 invoiceDetail.getInvoiceItemNumber()); 115 } 116 117 // create and save the paidApplied 118 InvoicePaidApplied invoicePaidApplied = new InvoicePaidApplied(); 119 invoicePaidApplied.setDocumentNumber(writeoff.getDocumentNumber()); 120 invoicePaidApplied.setPaidAppliedItemNumber(paidAppliedItemNumber++); 121 invoicePaidApplied.setFinancialDocumentReferenceInvoiceNumber(invoiceNumber); 122 invoicePaidApplied.setInvoiceItemNumber(invoiceDetail.getInvoiceItemNumber()); 123 invoicePaidApplied.setUniversityFiscalYear(universityDateService.getCurrentFiscalYear()); 124 invoicePaidApplied.setUniversityFiscalPeriodCode(universityDateService.getCurrentUniversityDate().getUniversityFiscalAccountingPeriod()); 125 invoicePaidApplied.setInvoiceItemAppliedAmount(invoiceDetail.getAmountOpen()); 126 businessObjectService.save(invoicePaidApplied); 127 128 // record how much we're applying 129 totalApplied = totalApplied.add(invoicePaidApplied.getInvoiceItemAppliedAmount()); 130 } 131 132 // close the document 133 invoice.setOpenInvoiceIndicator(false); 134 invoice.setClosedDate(dateTimeService.getCurrentSqlDate()); 135 documentService.updateDocument(invoice); 136 137 // set the final document total for the invoice 138 writeoff.setInvoiceWriteoffAmount(totalApplied); 139 writeoff.getDocumentHeader().setFinancialDocumentTotalAmount(totalApplied); 140 documentService.updateDocument(writeoff); 141 } 142 143 /** 144 * @see org.kuali.kfs.module.ar.document.service.CustomerInvoiceWriteoffDocumentService#setupDefaultValuesForNewCustomerInvoiceWriteoffDocument(org.kuali.kfs.module.ar.document.CustomerInvoiceWriteoffDocument) 145 */ 146 public void setupDefaultValuesForNewCustomerInvoiceWriteoffDocument(CustomerInvoiceWriteoffDocument customerInvoiceWriteoffDocument) { 147 148 // update status 149 customerInvoiceWriteoffDocument.setStatusCode(ArConstants.CustomerInvoiceWriteoffStatuses.IN_PROCESS); 150 151 // set accounts receivable document header 152 AccountsReceivableDocumentHeader accountsReceivableDocumentHeader = accountsReceivableDocumentHeaderService.getNewAccountsReceivableDocumentHeaderForCurrentUser(); 153 accountsReceivableDocumentHeader.setDocumentNumber(customerInvoiceWriteoffDocument.getDocumentNumber()); 154 accountsReceivableDocumentHeader.setCustomerNumber(customerInvoiceWriteoffDocument.getCustomerInvoiceDocument().getAccountsReceivableDocumentHeader().getCustomerNumber()); 155 customerInvoiceWriteoffDocument.setAccountsReceivableDocumentHeader(accountsReceivableDocumentHeader); 156 157 // if writeoffs are generated based on organization accounting default, populate those fields now 158 String writeoffGenerationOption = parameterService.getParameterValue(CustomerInvoiceWriteoffDocument.class, ArConstants.GLPE_WRITEOFF_GENERATION_METHOD); 159 boolean isUsingOrgAcctDefaultWriteoffFAU = ArConstants.GLPE_WRITEOFF_GENERATION_METHOD_ORG_ACCT_DEFAULT.equals(writeoffGenerationOption); 160 161 String writeoffTaxGenerationOption = SpringContext.getBean(ParameterService.class).getParameterValue(CustomerInvoiceWriteoffDocument.class, ArConstants.ALLOW_SALES_TAX_LIABILITY_ADJUSTMENT_IND); 162 boolean isUsingTaxGenerationMethodDisallow = ArConstants.ALLOW_SALES_TAX_LIABILITY_ADJUSTMENT_IND_NO.equals( writeoffTaxGenerationOption ); 163 if (isUsingOrgAcctDefaultWriteoffFAU || isUsingTaxGenerationMethodDisallow) { 164 165 Integer currentUniversityFiscalYear = universityDateService.getCurrentFiscalYear(); 166 ChartOrgHolder currentUser = SpringContext.getBean(FinancialSystemUserService.class).getPrimaryOrganization(GlobalVariables.getUserSession().getPerson(), ArConstants.AR_NAMESPACE_CODE); 167 168 Map<String, Object> criteria = new HashMap<String, Object>(); 169 criteria.put("universityFiscalYear", currentUniversityFiscalYear); 170 criteria.put("chartOfAccountsCode", customerInvoiceWriteoffDocument.getCustomerInvoiceDocument().getBillByChartOfAccountCode()); 171 criteria.put("organizationCode", customerInvoiceWriteoffDocument.getCustomerInvoiceDocument().getBilledByOrganizationCode()); 172 173 OrganizationAccountingDefault organizationAccountingDefault = (OrganizationAccountingDefault) businessObjectService.findByPrimaryKey(OrganizationAccountingDefault.class, criteria); 174 if (ObjectUtils.isNotNull(organizationAccountingDefault)) { 175 customerInvoiceWriteoffDocument.setChartOfAccountsCode(organizationAccountingDefault.getWriteoffChartOfAccountsCode()); 176 customerInvoiceWriteoffDocument.setAccountNumber(organizationAccountingDefault.getWriteoffAccountNumber()); 177 customerInvoiceWriteoffDocument.setSubAccountNumber(organizationAccountingDefault.getWriteoffSubAccountNumber()); 178 customerInvoiceWriteoffDocument.setFinancialObjectCode(organizationAccountingDefault.getWriteoffFinancialObjectCode()); 179 customerInvoiceWriteoffDocument.setFinancialSubObjectCode(organizationAccountingDefault.getWriteoffFinancialSubObjectCode()); 180 customerInvoiceWriteoffDocument.setProjectCode(organizationAccountingDefault.getWriteoffProjectCode()); 181 customerInvoiceWriteoffDocument.setOrganizationReferenceIdentifier(organizationAccountingDefault.getWriteoffOrganizationReferenceIdentifier()); 182 } 183 } 184 } 185 186 187 public boolean isCustomerInvoiceWriteoffDocumentApproved(String customerInvoiceWriteoffDocumentNumber) { 188 Map criteria = new HashMap(); 189 criteria.put("documentNumber", customerInvoiceWriteoffDocumentNumber); 190 criteria.put("documentHeader.financialDocumentStatusCode", KFSConstants.DocumentStatusCodes.APPROVED); 191 return businessObjectService.countMatching(CustomerInvoiceWriteoffDocument.class, criteria) == 1; 192 } 193 /* 194 public Collection<CustomerInvoiceWriteoffLookupResult> getCustomerInvoiceDocumentsForInvoiceWriteoffLookup() { 195 // change this service call to a service method that actually takes in the lookup parameters 196 Collection<CustomerInvoiceDocument> customerInvoiceDocuments = customerInvoiceDocumentService.getAllCustomerInvoiceDocumentsWithoutWorkflowInfo(); 197 198 Collection<CustomerInvoiceDocument> customerInvoiceDocumentsWithOpenBalance = new ArrayList<CustomerInvoiceDocument>(); 199 for (Iterator itr = customerInvoiceDocuments.iterator(); itr.hasNext();) { 200 CustomerInvoiceDocument invoice = (CustomerInvoiceDocument) itr.next(); 201 if (invoice.getOpenAmount().isGreaterThan(KualiDecimal.ZERO)) 202 customerInvoiceDocumentsWithOpenBalance.add(invoice); 203 } 204 205 return CustomerInvoiceWriteoffLookupUtil.getPopulatedCustomerInvoiceWriteoffLookupResults(customerInvoiceDocumentsWithOpenBalance); 206 } 207 */ 208 public Collection<CustomerInvoiceWriteoffLookupResult> getCustomerInvoiceDocumentsForInvoiceWriteoffLookup(Map<String, String> fieldValues) { 209 210 // only one of these four will be used, based on priority 211 String customerNumber = fieldValues.get(ArPropertyConstants.CustomerInvoiceWriteoffLookupResultFields.CUSTOMER_NUMBER); 212 String customerName = fieldValues.get(ArPropertyConstants.CustomerInvoiceWriteoffLookupResultFields.CUSTOMER_NAME); 213 String customerTypeCode = fieldValues.get(ArPropertyConstants.CustomerInvoiceWriteoffLookupResultFields.CUSTOMER_TYPE_CODE); 214 String customerInvoiceNumber = fieldValues.get(ArPropertyConstants.CustomerInvoiceWriteoffLookupResultFields.CUSTOMER_INVOICE_NUMBER); 215 216 // this may be combined with any of the four above 217 String age = fieldValues.get(ArPropertyConstants.CustomerInvoiceWriteoffLookupResultFields.AGE); 218 219 // this is the priority order for searching if multiples are entered 220 Collection<CustomerInvoiceDocument> customerInvoiceDocuments; 221 if (StringUtils.isNotEmpty(customerInvoiceNumber)) { 222 customerInvoiceDocuments = new ArrayList<CustomerInvoiceDocument>(); 223 CustomerInvoiceDocument customerInvoiceDocument = customerInvoiceDocumentService.getInvoiceByInvoiceDocumentNumber(customerInvoiceNumber); 224 if (customerInvoiceDocument.isOpenInvoiceIndicator()) 225 customerInvoiceDocuments.add(customerInvoiceDocument); 226 else 227 customerInvoiceDocuments = new ArrayList<CustomerInvoiceDocument>(); 228 } 229 else if (StringUtils.isNotEmpty(customerNumber)) { 230 customerInvoiceDocuments = customerInvoiceDocumentService.getOpenInvoiceDocumentsByCustomerNumber(customerNumber); 231 } 232 else if (StringUtils.isNotEmpty(customerName) && StringUtils.isNotEmpty(customerTypeCode)) { 233 customerInvoiceDocuments = customerInvoiceDocumentService.getOpenInvoiceDocumentsByCustomerNameByCustomerType(customerName, customerTypeCode); 234 } 235 else if (StringUtils.isNotEmpty(customerName)) { 236 customerInvoiceDocuments = customerInvoiceDocumentService.getOpenInvoiceDocumentsByCustomerName(customerName); 237 } 238 else if (StringUtils.isNotEmpty(customerTypeCode)) { 239 customerInvoiceDocuments = customerInvoiceDocumentService.getOpenInvoiceDocumentsByCustomerType(customerTypeCode); 240 } 241 else { 242 customerInvoiceDocuments = customerInvoiceDocumentService.getAllOpenCustomerInvoiceDocumentsWithoutWorkflow(); 243 } 244 245 // attach headers 246 customerInvoiceDocuments = customerInvoiceDocumentService.attachWorkflowHeadersToTheInvoices(customerInvoiceDocuments); 247 // filter invoices which have related CRMs and writeoffs in route. 248 Collection<CustomerInvoiceDocument> filteredCustomerInvoiceDocuments = filterInvoices(customerInvoiceDocuments); 249 250 // if no age value was specified, then we're done! 251 if (StringUtils.isEmpty(age)) { 252 return CustomerInvoiceWriteoffLookupUtil.getPopulatedCustomerInvoiceWriteoffLookupResults(filteredCustomerInvoiceDocuments); 253 } 254 255 // walk through what we have, and do any extra filtering based on age, if necessary 256 boolean eligibleInvoiceFlag; 257 Collection<CustomerInvoiceDocument> eligibleInvoices = new ArrayList<CustomerInvoiceDocument>(); 258 for (CustomerInvoiceDocument invoice : filteredCustomerInvoiceDocuments) { 259 eligibleInvoiceFlag = true; 260 261 if (ObjectUtils.isNotNull(invoice.getAge())) { 262 eligibleInvoiceFlag &=((new Integer(age)).compareTo(invoice.getAge()) <= 0); 263 } else { 264 eligibleInvoiceFlag = false; 265 } 266 267 if (eligibleInvoiceFlag) { 268 eligibleInvoices.add(invoice); 269 } 270 } 271 272 return CustomerInvoiceWriteoffLookupUtil.getPopulatedCustomerInvoiceWriteoffLookupResults(eligibleInvoices); 273 } 274 275 /** 276 * This method returns invoices which are in FINAL status and have no related CRMs and writeoffs in route 277 * 278 * @param customerInvoiceDocuments 279 * @return filteredInvoices 280 */ 281 public Collection<CustomerInvoiceDocument> filterInvoices(Collection<CustomerInvoiceDocument> customerInvoiceDocuments) { 282 Collection<CustomerInvoiceDocument> filteredInvoices = new ArrayList<CustomerInvoiceDocument>(); 283 boolean hasNoDocumentsInRouteFlag; 284 285 for (CustomerInvoiceDocument invoice : customerInvoiceDocuments) { 286 if (invoice.getDocumentHeader().getWorkflowDocument().stateIsFinal()) { 287 hasNoDocumentsInRouteFlag = checkIfThereIsNoAnotherCRMInRouteForTheInvoice(invoice.getDocumentNumber()); 288 if (hasNoDocumentsInRouteFlag) 289 hasNoDocumentsInRouteFlag = checkIfThereIsNoAnotherWriteoffInRouteForTheInvoice(invoice.getDocumentNumber()); 290 if (hasNoDocumentsInRouteFlag) 291 filteredInvoices.add(invoice); 292 } 293 } 294 return filteredInvoices; 295 } 296 297 /** 298 * This method checks if there is no another CRM in route for the invoice 299 * Not in route if CRM status is one of the following: processed, cancelled, or disapproved 300 * 301 * @param invoice 302 * @return 303 */ 304 public boolean checkIfThereIsNoAnotherCRMInRouteForTheInvoice(String invoiceDocumentNumber) { 305 306 KualiWorkflowDocument workflowDocument; 307 boolean success = true; 308 309 Map<String, String> fieldValues = new HashMap<String, String>(); 310 fieldValues.put("financialDocumentReferenceInvoiceNumber", invoiceDocumentNumber); 311 312 BusinessObjectService businessObjectService = SpringContext.getBean(BusinessObjectService.class); 313 Collection<CustomerCreditMemoDocument> customerCreditMemoDocuments = businessObjectService.findMatching(CustomerCreditMemoDocument.class, fieldValues); 314 315 // no CRMs associated with the invoice are found 316 if (customerCreditMemoDocuments.isEmpty()) 317 return success; 318 319 Person user = GlobalVariables.getUserSession().getPerson(); 320 321 for (CustomerCreditMemoDocument customerCreditMemoDocument : customerCreditMemoDocuments) { 322 try { 323 workflowDocument = SpringContext.getBean(WorkflowDocumentService.class).createWorkflowDocument(Long.valueOf(customerCreditMemoDocument.getDocumentNumber()), user); 324 } 325 catch (WorkflowException e) { 326 throw new UnknownDocumentIdException("no document found for documentHeaderId '" + customerCreditMemoDocument.getDocumentNumber() + "'", e); 327 } 328 329 if (!(workflowDocument.stateIsApproved() || workflowDocument.stateIsCanceled() || workflowDocument.stateIsDisapproved())) { 330 success = false; 331 break; 332 } 333 } 334 return success; 335 } 336 337 /** 338 * This method checks if there is no another writeoff in route for the invoice 339 * Not in route if writeoff status is one of the following: processed, cancelled, or disapproved 340 * 341 * @param invoice 342 * @return 343 */ 344 public boolean checkIfThereIsNoAnotherWriteoffInRouteForTheInvoice(String invoiceDocumentNumber) { 345 346 KualiWorkflowDocument workflowDocument; 347 boolean success = true; 348 349 Map<String, String> fieldValues = new HashMap<String, String>(); 350 fieldValues.put("financialDocumentReferenceInvoiceNumber", invoiceDocumentNumber); 351 352 BusinessObjectService businessObjectService = SpringContext.getBean(BusinessObjectService.class); 353 Collection<CustomerInvoiceWriteoffDocument> customerInvoiceWriteoffDocuments = businessObjectService.findMatching(CustomerInvoiceWriteoffDocument.class, fieldValues); 354 355 356 // no writeoffs associated with the invoice are found 357 if (customerInvoiceWriteoffDocuments.isEmpty()) 358 return success; 359 360 Person user = GlobalVariables.getUserSession().getPerson(); 361 362 for (CustomerInvoiceWriteoffDocument customerInvoiceWriteoffDocument : customerInvoiceWriteoffDocuments) { 363 try { 364 workflowDocument = SpringContext.getBean(WorkflowDocumentService.class).createWorkflowDocument(Long.valueOf(customerInvoiceWriteoffDocument.getDocumentNumber()), user); 365 } 366 catch (WorkflowException e) { 367 throw new UnknownDocumentIdException("no document found for documentHeaderId '" + customerInvoiceWriteoffDocument.getDocumentNumber() + "'", e); 368 } 369 370 if (!(workflowDocument.stateIsApproved() || workflowDocument.stateIsCanceled() || workflowDocument.stateIsDisapproved())) { 371 success = false; 372 break; 373 } 374 } 375 return success; 376 } 377 378 379 /** 380 * 381 * @see org.kuali.kfs.module.ar.document.service.CustomerInvoiceWriteoffDocumentService#sendCustomerInvoiceWriteoffDocumentsToBatch(org.kuali.rice.kim.bo.Person, java.util.Collection) 382 */ 383 public String sendCustomerInvoiceWriteoffDocumentsToBatch(Person person, Collection<CustomerInvoiceWriteoffLookupResult> customerInvoiceWriteoffLookupResults) { 384 385 CustomerInvoiceWriteoffBatchVO batch = new CustomerInvoiceWriteoffBatchVO(person.getPrincipalName()); 386 387 // add the date 388 batch.setSubmittedOn(dateTimeService.getCurrentTimestamp().toString()); 389 390 // add the customer note, if one was added 391 String note = null; 392 for( CustomerInvoiceWriteoffLookupResult customerInvoiceWriteoffLookupResult : customerInvoiceWriteoffLookupResults ){ 393 note = customerInvoiceWriteoffLookupResult.getCustomerNote(); 394 } 395 if (StringUtils.isNotBlank(note)) { 396 batch.setNote(note); 397 } 398 399 // add the document numbers 400 for( CustomerInvoiceWriteoffLookupResult customerInvoiceWriteoffLookupResult : customerInvoiceWriteoffLookupResults ){ 401 for( CustomerInvoiceDocument customerInvoiceDocument : customerInvoiceWriteoffLookupResult.getCustomerInvoiceDocuments() ){ 402 batch.addInvoiceNumber(customerInvoiceDocument.getDocumentNumber()); 403 } 404 } 405 406 // use the batch service to create the XML and drop it in the directory 407 return invoiceWriteoffBatchService.createBatchDrop(person, batch); 408 } 409 410 public String createCustomerInvoiceWriteoffDocument(Person initiator, String invoiceNumber, String note) throws WorkflowException { 411 412 // force the initiating user into the header 413 GlobalVariables.getUserSession().setBackdoorUser(initiator.getPrincipalName()); 414 415 // create the new writeoff document 416 CustomerInvoiceWriteoffDocument document = (CustomerInvoiceWriteoffDocument) documentService.getNewDocument(CustomerInvoiceWriteoffDocument.class); 417 418 // setup the defaults and tie it to the Invoice document 419 document.setFinancialDocumentReferenceInvoiceNumber(invoiceNumber); 420 setupDefaultValuesForNewCustomerInvoiceWriteoffDocument( document ); 421 document.getDocumentHeader().setDocumentDescription(ArConstants.CUSTOMER_INVOICE_WRITEOFF_DOCUMENT_DESCRIPTION + " " + invoiceNumber + "."); 422 423 document.setCustomerNote(note); 424 425 // satisfy silly > 10 chars explanation rule 426 if (StringUtils.isBlank(note)) { 427 note = "Document created by batch process."; 428 } 429 else if (note.length() <= 10) { 430 note = "Document created by batch process. " + note; 431 } 432 document.getDocumentHeader().setExplanation(note); 433 434 // route the document 435 documentService.routeDocument(document, "Routed by Customer Invoice Writeoff Document Batch Service", null); 436 437 // clear the user overrid 438 GlobalVariables.getUserSession().clearBackdoorUser(); 439 440 return document.getDocumentNumber(); 441 } 442 443 public String getFinancialObjectCode(CustomerInvoiceDetail postable, CustomerInvoiceWriteoffDocument poster, boolean isUsingOrgAcctDefaultWriteoffFAU, boolean isUsingChartForWriteoff, String chartOfAccountsCode) { 444 445 if ( isUsingOrgAcctDefaultWriteoffFAU ){ 446 return poster.getFinancialObjectCode(); 447 } else if ( isUsingChartForWriteoff ) { 448 return SpringContext.getBean(ParameterService.class).getParameterValue(CustomerInvoiceWriteoffDocument.class, ArConstants.GLPE_WRITEOFF_OBJECT_CODE_BY_CHART, chartOfAccountsCode); 449 } else { 450 return postable.getAccountsReceivableObjectCode(); 451 } 452 } 453 454 public ObjectCode getObjectCode(CustomerInvoiceDetail postable, CustomerInvoiceWriteoffDocument poster, boolean isUsingOrgAcctDefaultWriteoffFAU, boolean isUsingChartForWriteoff, String chartOfAccountsCode) { 455 456 return SpringContext.getBean(ObjectCodeService.class).getByPrimaryIdForCurrentYear(chartOfAccountsCode, this.getFinancialObjectCode(postable, poster, isUsingOrgAcctDefaultWriteoffFAU,isUsingChartForWriteoff, chartOfAccountsCode)); 457 } 458 459 public ParameterService getParameterService() { 460 return parameterService; 461 } 462 463 public void setParameterService(ParameterService parameterService) { 464 this.parameterService = parameterService; 465 } 466 467 public UniversityDateService getUniversityDateService() { 468 return universityDateService; 469 } 470 471 public void setUniversityDateService(UniversityDateService universityDateService) { 472 this.universityDateService = universityDateService; 473 } 474 475 public BusinessObjectService getBusinessObjectService() { 476 return businessObjectService; 477 } 478 479 public void setBusinessObjectService(BusinessObjectService businessObjectService) { 480 this.businessObjectService = businessObjectService; 481 } 482 483 public CustomerInvoiceDocumentService getCustomerInvoiceDocumentService() { 484 return customerInvoiceDocumentService; 485 } 486 487 public void setCustomerInvoiceDocumentService(CustomerInvoiceDocumentService customerInvoiceDocumentService) { 488 this.customerInvoiceDocumentService = customerInvoiceDocumentService; 489 } 490 491 public AccountsReceivableDocumentHeaderService getAccountsReceivableDocumentHeaderService() { 492 return accountsReceivableDocumentHeaderService; 493 } 494 495 public void setAccountsReceivableDocumentHeaderService(AccountsReceivableDocumentHeaderService accountsReceivableDocumentHeaderService) { 496 this.accountsReceivableDocumentHeaderService = accountsReceivableDocumentHeaderService; 497 } 498 499 500 public CustomerService getCustomerService() { 501 return customerService; 502 } 503 504 505 public void setCustomerService(CustomerService customerService) { 506 this.customerService = customerService; 507 } 508 509 510 public DocumentService getDocumentService() { 511 return documentService; 512 } 513 514 515 public void setDocumentService(DocumentService documentService) { 516 this.documentService = documentService; 517 } 518 519 520 public void setInvoiceWriteoffBatchService(CustomerInvoiceWriteoffBatchService invoiceWriteoffBatchService) { 521 this.invoiceWriteoffBatchService = invoiceWriteoffBatchService; 522 } 523 524 525 public void setDateTimeService(DateTimeService dateTimeService) { 526 this.dateTimeService = dateTimeService; 527 } 528 529 public void setPaidAppliedService(InvoicePaidAppliedService<CustomerInvoiceDetail> paidAppliedService) { 530 this.paidAppliedService = paidAppliedService; 531 } 532 533 } 534