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