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.sql.Date;
019 import java.sql.Timestamp;
020 import java.text.ParseException;
021 import java.util.ArrayList;
022 import java.util.Calendar;
023 import java.util.Collection;
024 import java.util.HashMap;
025 import java.util.List;
026 import java.util.Map;
027
028 import org.apache.commons.lang.StringUtils;
029 import org.kuali.kfs.module.ar.ArConstants;
030 import org.kuali.kfs.module.ar.businessobject.AccountsReceivableDocumentHeader;
031 import org.kuali.kfs.module.ar.businessobject.Customer;
032 import org.kuali.kfs.module.ar.businessobject.CustomerAddress;
033 import org.kuali.kfs.module.ar.businessobject.CustomerInvoiceDetail;
034 import org.kuali.kfs.module.ar.businessobject.CustomerInvoiceRecurrenceDetails;
035 import org.kuali.kfs.module.ar.businessobject.InvoicePaidApplied;
036 import org.kuali.kfs.module.ar.businessobject.NonInvoicedDistribution;
037 import org.kuali.kfs.module.ar.businessobject.OrganizationOptions;
038 import org.kuali.kfs.module.ar.document.CustomerInvoiceDocument;
039 import org.kuali.kfs.module.ar.document.dataaccess.CustomerInvoiceDocumentDao;
040 import org.kuali.kfs.module.ar.document.service.AccountsReceivableDocumentHeaderService;
041 import org.kuali.kfs.module.ar.document.service.CustomerAddressService;
042 import org.kuali.kfs.module.ar.document.service.CustomerInvoiceDetailService;
043 import org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService;
044 import org.kuali.kfs.module.ar.document.service.InvoicePaidAppliedService;
045 import org.kuali.kfs.module.ar.document.service.NonInvoicedDistributionService;
046 import org.kuali.kfs.sys.KFSConstants;
047 import org.kuali.kfs.sys.businessobject.ChartOrgHolder;
048 import org.kuali.kfs.sys.businessobject.FinancialSystemDocumentHeader;
049 import org.kuali.kfs.sys.context.SpringContext;
050 import org.kuali.kfs.sys.service.FinancialSystemUserService;
051 import org.kuali.kfs.sys.service.UniversityDateService;
052 import org.kuali.rice.kew.exception.WorkflowException;
053 import org.kuali.rice.kim.bo.Person;
054 import org.kuali.rice.kim.service.PersonService;
055 import org.kuali.rice.kns.dao.DocumentDao;
056 import org.kuali.rice.kns.document.Document;
057 import org.kuali.rice.kns.exception.InfrastructureException;
058 import org.kuali.rice.kns.service.BusinessObjectService;
059 import org.kuali.rice.kns.service.DateTimeService;
060 import org.kuali.rice.kns.service.DocumentService;
061 import org.kuali.rice.kns.service.ParameterService;
062 import org.kuali.rice.kns.util.GlobalVariables;
063 import org.kuali.rice.kns.util.KualiDecimal;
064 import org.kuali.rice.kns.util.ObjectUtils;
065 import org.springframework.transaction.annotation.Transactional;
066
067 @Transactional
068 public class CustomerInvoiceDocumentServiceImpl implements CustomerInvoiceDocumentService {
069
070 private PersonService<Person> personService;
071 private BusinessObjectService businessObjectService;
072 private DateTimeService dateTimeService;
073 private ReceivableAccountingLineService receivableAccountingLineService;
074 private AccountsReceivableDocumentHeaderService accountsReceivableDocumentHeaderService;
075 private CustomerAddressService customerAddressService;
076 private CustomerInvoiceDocumentDao customerInvoiceDocumentDao;
077 private DocumentService documentService;
078 private DocumentDao documentDao;
079 private InvoicePaidAppliedService<CustomerInvoiceDetail> invoicePaidAppliedService;
080 private NonInvoicedDistributionService nonInvoicedDistributionService;
081 private CustomerInvoiceDetailService customerInvoiceDetailService;
082 private CustomerInvoiceRecurrenceDetails customerInvoiceRecurrenceDetails;
083 private UniversityDateService universityDateService;
084
085 protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(CustomerInvoiceDocumentServiceImpl.class);
086
087 public void convertDiscountsToPaidApplieds(CustomerInvoiceDocument invoice) {
088
089 // this needs a little explanation. we have to calculate manually
090 // whether we've written off the whole thing, because the regular
091 // code uses the invoice paid applieds to discount, but since those
092 // are added but not committed in this transaction, they're also not
093 // visible in this transaction, so we do it manually.
094 KualiDecimal openAmount = invoice.getOpenAmount();
095
096 String invoiceNumber = invoice.getDocumentNumber();
097 List<CustomerInvoiceDetail> discounts = invoice.getDiscounts();
098
099 // retrieve the number of current paid applieds, so we dont have item number overlap
100 Integer paidAppliedItemNumber = 0;
101
102 for (CustomerInvoiceDetail discount : discounts) {
103
104 // if credit amount is zero, do nothing
105 if (KualiDecimal.ZERO.equals(discount.getAmount())) {
106 continue;
107 }
108
109 if (paidAppliedItemNumber == 0) {
110 paidAppliedItemNumber = invoicePaidAppliedService.getNumberOfInvoicePaidAppliedsForInvoiceDetail(invoiceNumber, discount.getInvoiceItemNumber());
111 }
112
113 // create and save the paidApplied
114 InvoicePaidApplied invoicePaidApplied = new InvoicePaidApplied();
115 invoicePaidApplied.setDocumentNumber(invoiceNumber);
116 invoicePaidApplied.setPaidAppliedItemNumber(paidAppliedItemNumber++);
117 invoicePaidApplied.setFinancialDocumentReferenceInvoiceNumber(invoiceNumber);
118 invoicePaidApplied.setInvoiceItemNumber(discount.getInvoiceItemNumber());
119 invoicePaidApplied.setUniversityFiscalYear(universityDateService.getCurrentFiscalYear());
120 invoicePaidApplied.setUniversityFiscalPeriodCode(universityDateService.getCurrentUniversityDate().getUniversityFiscalAccountingPeriod());
121 invoicePaidApplied.setInvoiceItemAppliedAmount(discount.getAmount().abs());
122 openAmount = openAmount.subtract(discount.getAmount().abs());
123 businessObjectService.save(invoicePaidApplied);
124 }
125
126 // if its open, but now with a zero openamount, then close it
127 if (KualiDecimal.ZERO.equals(openAmount)) {
128 invoice.setOpenInvoiceIndicator(false);
129 invoice.setClosedDate(dateTimeService.getCurrentSqlDate());
130 documentService.updateDocument(invoice);
131 }
132 }
133
134 public Collection<CustomerInvoiceDocument> getAllOpenCustomerInvoiceDocuments() {
135 return getAllOpenCustomerInvoiceDocuments(true);
136 }
137
138 public Collection<CustomerInvoiceDocument> getAllOpenCustomerInvoiceDocumentsWithoutWorkflow() {
139 return getAllOpenCustomerInvoiceDocuments(false);
140 }
141
142 public Collection<CustomerInvoiceDocument> getAllOpenCustomerInvoiceDocuments(boolean includeWorkflowHeaders) {
143 Collection<CustomerInvoiceDocument> invoices = new ArrayList<CustomerInvoiceDocument>();
144
145 // retrieve the set of documents without workflow headers
146 invoices = customerInvoiceDocumentDao.getAllOpen();
147
148 // if we dont need workflow headers, then we're done
149 if (!includeWorkflowHeaders) {
150 return invoices;
151 }
152
153 // make a list of necessary workflow docs to retrieve
154 List<String> documentHeaderIds = new ArrayList<String>();
155 for (CustomerInvoiceDocument invoice : invoices) {
156 documentHeaderIds.add(invoice.getDocumentNumber());
157 }
158
159 // get all of our docs with full workflow headers
160 List<CustomerInvoiceDocument> docs = new ArrayList<CustomerInvoiceDocument>();
161 try {
162 docs = documentService.getDocumentsByListOfDocumentHeaderIds(CustomerInvoiceDocument.class, documentHeaderIds);
163 }
164 catch (WorkflowException e) {
165 throw new InfrastructureException("Unable to retrieve Customer Invoice Documents", e);
166 }
167
168 return docs;
169 }
170
171 public Collection<CustomerInvoiceDocument> attachWorkflowHeadersToTheInvoices(Collection<CustomerInvoiceDocument> invoices) {
172 List<CustomerInvoiceDocument> docs = new ArrayList<CustomerInvoiceDocument>();
173 if (invoices == null || invoices.isEmpty()) {
174 return docs;
175 }
176
177 // make a list of necessary workflow docs to retrieve
178 List<String> documentHeaderIds = new ArrayList<String>();
179 for (CustomerInvoiceDocument invoice : invoices) {
180 documentHeaderIds.add(invoice.getDocumentNumber());
181 }
182
183 // get all of our docs with full workflow headers
184 try {
185 docs = documentService.getDocumentsByListOfDocumentHeaderIds(CustomerInvoiceDocument.class, documentHeaderIds);
186 }
187 catch (WorkflowException e) {
188 throw new InfrastructureException("Unable to retrieve Customer Invoice Documents", e);
189 }
190
191 return docs;
192 }
193
194 public Collection<CustomerInvoiceDocument> getOpenInvoiceDocumentsByCustomerNumber(String customerNumber) {
195 Collection<CustomerInvoiceDocument> invoices = new ArrayList<CustomerInvoiceDocument>();
196
197 // customer number is not required to be populated, so we need to check that it's not null first
198 if (StringUtils.isNotEmpty(customerNumber)) {
199 // trim and force-caps the customer number
200 customerNumber = customerNumber.trim().toUpperCase();
201 }
202
203 invoices.addAll(customerInvoiceDocumentDao.getOpenByCustomerNumber(customerNumber));
204 return invoices;
205 }
206
207 public Collection<CustomerInvoiceDocument> getOpenInvoiceDocumentsByCustomerNameByCustomerType(String customerName, String customerTypeCode) {
208 Collection<CustomerInvoiceDocument> invoices = new ArrayList<CustomerInvoiceDocument>();
209
210 // trim and force-caps the customer name
211 customerName = StringUtils.replace(customerName, KFSConstants.WILDCARD_CHARACTER, KFSConstants.PERCENTAGE_SIGN);
212 customerName = customerName.trim();
213 if (customerName.indexOf("%") < 0)
214 customerName += "%";
215
216 // trim and force-caps
217 customerTypeCode = customerTypeCode.trim().toUpperCase();
218
219 invoices.addAll(customerInvoiceDocumentDao.getOpenByCustomerNameByCustomerType(customerName, customerTypeCode));
220 return invoices;
221 }
222
223 public Collection<CustomerInvoiceDocument> getOpenInvoiceDocumentsByCustomerName(String customerName) {
224 Collection<CustomerInvoiceDocument> invoices = new ArrayList<CustomerInvoiceDocument>();
225
226 // trim and force-caps the customer name
227 customerName = StringUtils.replace(customerName, KFSConstants.WILDCARD_CHARACTER, KFSConstants.PERCENTAGE_SIGN);
228 customerName = customerName.trim();
229 if (customerName.indexOf("%") < 0)
230 customerName += "%";
231
232 invoices.addAll(customerInvoiceDocumentDao.getOpenByCustomerName(customerName));
233 return invoices;
234 }
235
236 public Collection<CustomerInvoiceDocument> getOpenInvoiceDocumentsByCustomerType(String customerTypeCode) {
237 Collection<CustomerInvoiceDocument> invoices = new ArrayList<CustomerInvoiceDocument>();
238
239 // trim and force-caps
240 customerTypeCode = customerTypeCode.trim().toUpperCase();
241
242 invoices.addAll(customerInvoiceDocumentDao.getOpenByCustomerType(customerTypeCode));
243 return invoices;
244 }
245
246 /**
247 * @see org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#getCustomerInvoiceDetailsForCustomerInvoiceDocument(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument)
248 */
249 public Collection<CustomerInvoiceDetail> getCustomerInvoiceDetailsForCustomerInvoiceDocument(CustomerInvoiceDocument customerInvoiceDocument) {
250 return getCustomerInvoiceDetailsForCustomerInvoiceDocument(customerInvoiceDocument.getDocumentNumber());
251 }
252
253 /**
254 * @see org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#getCustomerInvoiceDetailsForCustomerInvoiceDocumentWithCaching(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument)
255 */
256 public Collection<CustomerInvoiceDetail> getCustomerInvoiceDetailsForCustomerInvoiceDocumentWithCaching(CustomerInvoiceDocument customerInvoiceDocument) {
257 return customerInvoiceDetailService.getCustomerInvoiceDetailsForInvoiceWithCaching(customerInvoiceDocument.getDocumentNumber());
258 }
259
260 /**
261 * @see org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#getCustomerInvoiceDetailsForCustomerInvoiceDocument(java.lang.String)
262 */
263 public Collection<CustomerInvoiceDetail> getCustomerInvoiceDetailsForCustomerInvoiceDocument(String customerInvoiceDocumentNumber) {
264 return customerInvoiceDetailService.getCustomerInvoiceDetailsForInvoice(customerInvoiceDocumentNumber);
265 }
266
267
268 public KualiDecimal getOpenAmountForCustomerInvoiceDocument(String customerInvoiceDocumentNumber) {
269 if (null == customerInvoiceDocumentNumber) {
270 return null;
271 }
272 return getOpenAmountForCustomerInvoiceDocument(getInvoiceByInvoiceDocumentNumber(customerInvoiceDocumentNumber));
273 }
274
275 public KualiDecimal getOpenAmountForCustomerInvoiceDocument(CustomerInvoiceDocument customerInvoiceDocument) {
276 KualiDecimal total = new KualiDecimal(0);
277 if (customerInvoiceDocument.isOpenInvoiceIndicator()) {
278 Collection<CustomerInvoiceDetail> customerInvoiceDetails = customerInvoiceDocument.getCustomerInvoiceDetailsWithoutDiscounts();
279 for (CustomerInvoiceDetail detail : customerInvoiceDetails) {
280 // note that we're now dealing with conditionally applying discounts
281 // depending on whether the doc is saved or approved one level down,
282 // in the CustomerInvoiceDetail.getAmountOpen()
283 detail.setCustomerInvoiceDocument(customerInvoiceDocument);
284 total = total.add(detail.getAmountOpen());
285 }
286 }
287 return total;
288 }
289
290 public KualiDecimal getOriginalTotalAmountForCustomerInvoiceDocument(CustomerInvoiceDocument customerInvoiceDocument) {
291 LOG.info("\n\n\n\t\t invoice: " + customerInvoiceDocument.getDocumentNumber() + "\n\t\t 111111111 HEADER TOTAL AMOUNT (should be null): " + customerInvoiceDocument.getDocumentHeader().getFinancialDocumentTotalAmount() + "\n\n");
292 customerInvoiceDocument.getDocumentNumber();
293 // original-amount = SpringContext.getBean(FinancialSystemDocumentService.class).get
294 HashMap criteria = new HashMap();
295 criteria.put("documentNumber", customerInvoiceDocument.getDocumentHeader().getDocumentTemplateNumber());
296 businessObjectService = SpringContext.getBean(BusinessObjectService.class);
297 FinancialSystemDocumentHeader financialSystemDocumentHeader = (FinancialSystemDocumentHeader) businessObjectService.findByPrimaryKey(FinancialSystemDocumentHeader.class, criteria);
298 KualiDecimal originalTotalAmount = KualiDecimal.ZERO;
299 originalTotalAmount = financialSystemDocumentHeader.getFinancialDocumentTotalAmount();
300
301 LOG.info("\n\n\n\t\t invoice: " + customerInvoiceDocument.getDocumentNumber() + "\n\t\t 333333333333 HEADER TOTAL AMOUNT (should be set now): " + customerInvoiceDocument.getDocumentHeader().getFinancialDocumentTotalAmount() + "\n\n");
302 return originalTotalAmount;
303 }
304
305 /**
306 * @see org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#getInvoicesByCustomerNumber(java.lang.String)
307 */
308 public Collection<CustomerInvoiceDocument> getCustomerInvoiceDocumentsByCustomerNumber(String customerNumber) {
309
310 Collection<CustomerInvoiceDocument> invoices = new ArrayList<CustomerInvoiceDocument>();
311
312 Map<String, String> fieldValues = new HashMap<String, String>();
313 fieldValues.put("customerNumber", customerNumber);
314
315 Collection<AccountsReceivableDocumentHeader> documentHeaders = businessObjectService.findMatching(AccountsReceivableDocumentHeader.class, fieldValues);
316
317 List<String> documentHeaderIds = new ArrayList<String>();
318 for (AccountsReceivableDocumentHeader header : documentHeaders) {
319 String documentNumber = null;
320 try {
321 Long.parseLong(header.getDocumentHeader().getDocumentNumber());
322 documentNumber = header.getDocumentHeader().getDocumentNumber();
323 documentHeaderIds.add(documentNumber);
324 }
325 catch (NumberFormatException nfe) {
326 }
327 }
328
329 if (0 < documentHeaderIds.size()) {
330 try {
331 invoices = documentService.getDocumentsByListOfDocumentHeaderIds(CustomerInvoiceDocument.class, documentHeaderIds);
332 }
333 catch (WorkflowException e) {
334 LOG.error(e.getMessage(), e);
335 }
336 }
337 return invoices;
338 }
339
340 /**
341 * @see org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#getCustomerByOrganizationInvoiceNumber(java.lang.String)
342 */
343 public Customer getCustomerByOrganizationInvoiceNumber(String organizationInvoiceNumber) {
344 CustomerInvoiceDocument invoice = getInvoiceByOrganizationInvoiceNumber(organizationInvoiceNumber);
345 return invoice.getAccountsReceivableDocumentHeader().getCustomer();
346 }
347
348 /**
349 * @see org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#getInvoiceByOrganizationInvoiceNumber(java.lang.String)
350 */
351 public CustomerInvoiceDocument getInvoiceByOrganizationInvoiceNumber(String organizationInvoiceNumber) {
352 return customerInvoiceDocumentDao.getInvoiceByOrganizationInvoiceNumber(organizationInvoiceNumber);
353 }
354
355 /**
356 * @param invoiceDocumentNumber
357 * @return
358 */
359 public Customer getCustomerByInvoiceDocumentNumber(String invoiceDocumentNumber) {
360 CustomerInvoiceDocument invoice = getInvoiceByInvoiceDocumentNumber(invoiceDocumentNumber);
361 return invoice.getAccountsReceivableDocumentHeader().getCustomer();
362 }
363
364 /**
365 * @see org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#getInvoiceByInvoiceDocumentNumber(java.lang.String)
366 */
367 public CustomerInvoiceDocument getInvoiceByInvoiceDocumentNumber(String invoiceDocumentNumber) {
368 return customerInvoiceDocumentDao.getInvoiceByInvoiceDocumentNumber(invoiceDocumentNumber);
369 }
370
371 public List<CustomerInvoiceDocument> getPrintableCustomerInvoiceDocumentsByInitiatorPrincipalName(String initiatorPrincipalName) {
372 if (StringUtils.isBlank(initiatorPrincipalName)) {
373 throw new IllegalArgumentException("The parameter [initiatorPrincipalName] passed in was null or blank.");
374 }
375
376 // IMPORTANT NOTES ABOUT THIS METHOD
377 //
378 // This method behaves differently than the other invoice printing methods. This is
379 // because there's no way from within KFS to do a direct DB call to get all the invoices
380 // you want. This is because workflow holds the document initiator, and you cant guarantee
381 // that in a given implementation that you have access to that other db. It could be on
382 // another box in another network, and you only have web-services access to the Rice box.
383 //
384 // Given that, we try to minimize the resource hit of this call as much as possible. First
385 // we retrieve all invoices that havent been printed (ie, dont have a print date) and that
386 // are marked for the USER print queue. At any given time that should be a manageable number of
387 // documents.
388 //
389 // Then we walk through them, retrieve the full workflow-populated version of it, and only
390 // return the ones that match the initiator.
391 //
392 // This isnt as performant a solution as the other getPrintableCustomerInvoiceBy...
393 // methods, but its the best we can do in this release, and it should be manageable.
394
395 //
396 // attempt to retrieve the initiator person specified, and puke if not found
397 Person initiator = getPersonService().getPersonByPrincipalName(initiatorPrincipalName);
398 if (initiator == null) {
399 throw new IllegalArgumentException("The parameter value for initiatorPrincipalName [" + initiatorPrincipalName + "] passed in doesnt map to a person.");
400 }
401
402 // retrieve all the ready-to-print docs in the user-queue for all users
403 List<String> printableUserQueueDocNumbers = customerInvoiceDocumentDao.getPrintableCustomerInvoiceDocumentNumbersFromUserQueue();
404
405 // get all the documents that might be right, but this set includes documents generated
406 // by the wrong user
407 List<CustomerInvoiceDocument> customerInvoiceDocumentsSuperSet;
408 if (printableUserQueueDocNumbers.size() > 0) {
409 try {
410 customerInvoiceDocumentsSuperSet = documentService.getDocumentsByListOfDocumentHeaderIds(CustomerInvoiceDocument.class, printableUserQueueDocNumbers);
411 }
412 catch (WorkflowException e) {
413 throw new InfrastructureException("Unable to retrieve Customer Invoice Documents", e);
414 }
415 }
416 else {
417 customerInvoiceDocumentsSuperSet = new ArrayList<CustomerInvoiceDocument>();
418 }
419
420 // filter only the ones initiated by the correct user
421 List<CustomerInvoiceDocument> customerInvoiceDocuments = new ArrayList<CustomerInvoiceDocument>();
422 for (CustomerInvoiceDocument superSetDocument : customerInvoiceDocumentsSuperSet) {
423 if (superSetDocument.getDocumentHeader().getWorkflowDocument().userIsInitiator(initiator)) {
424 customerInvoiceDocuments.add(superSetDocument);
425 }
426 }
427 return customerInvoiceDocuments;
428 }
429
430 public List<CustomerInvoiceDocument> getPrintableCustomerInvoiceDocumentsByBillingChartAndOrg(String chartOfAccountsCode, String organizationCode) {
431 List<String> documentHeaderIds = customerInvoiceDocumentDao.getPrintableCustomerInvoiceDocumentNumbersByBillingChartAndOrg(chartOfAccountsCode, organizationCode);
432
433 List<CustomerInvoiceDocument> customerInvoiceDocuments = new ArrayList<CustomerInvoiceDocument>();
434 if (documentHeaderIds != null && !documentHeaderIds.isEmpty()) {
435 try {
436 customerInvoiceDocuments = documentService.getDocumentsByListOfDocumentHeaderIds(CustomerInvoiceDocument.class, documentHeaderIds);
437 }
438 catch (WorkflowException e) {
439 throw new InfrastructureException("Unable to retrieve Customer Invoice Documents", e);
440 }
441 }
442 return customerInvoiceDocuments;
443 }
444
445 public List<CustomerInvoiceDocument> getPrintableCustomerInvoiceDocumentsForBillingStatementByBillingChartAndOrg(String chartOfAccountsCode, String organizationCode) {
446 List<String> documentHeaderIds = customerInvoiceDocumentDao.getPrintableCustomerInvoiceDocumentNumbersForBillingStatementByBillingChartAndOrg(chartOfAccountsCode, organizationCode);
447
448 List<CustomerInvoiceDocument> customerInvoiceDocuments = new ArrayList<CustomerInvoiceDocument>();
449 if (documentHeaderIds != null && !documentHeaderIds.isEmpty()) {
450 try {
451 customerInvoiceDocuments = documentService.getDocumentsByListOfDocumentHeaderIds(CustomerInvoiceDocument.class, documentHeaderIds);
452 }
453 catch (WorkflowException e) {
454 throw new InfrastructureException("Unable to retrieve Customer Invoice Documents", e);
455 }
456 }
457 return customerInvoiceDocuments;
458 }
459
460 /**
461 * @see org.kuali.module.ar.service.CustomerInvoiceDocumentService#getCustomerInvoiceDocumentsByCustomerNumber(java.lang.String)
462 */
463 public List<CustomerInvoiceDocument> getPrintableCustomerInvoiceDocumentsByProcessingChartAndOrg(String chartOfAccountsCode, String organizationCode) {
464
465 List<String> documentHeaderIds = customerInvoiceDocumentDao.getPrintableCustomerInvoiceDocumentNumbersByProcessingChartAndOrg(chartOfAccountsCode, organizationCode);
466
467 List<CustomerInvoiceDocument> customerInvoiceDocuments = new ArrayList<CustomerInvoiceDocument>();
468 if (documentHeaderIds != null && !documentHeaderIds.isEmpty()) {
469 try {
470 customerInvoiceDocuments = documentService.getDocumentsByListOfDocumentHeaderIds(CustomerInvoiceDocument.class, documentHeaderIds);
471 }
472 catch (WorkflowException e) {
473 throw new InfrastructureException("Unable to retrieve Customer Invoice Documents", e);
474 }
475 }
476 return customerInvoiceDocuments;
477 }
478
479 public Collection<CustomerInvoiceDocument> getCustomerInvoiceDocumentsByAccountNumber(String accountNumber) {
480
481 List<String> docNumbers = customerInvoiceDetailService.getCustomerInvoiceDocumentNumbersByAccountNumber(accountNumber);
482
483 Collection<CustomerInvoiceDocument> customerInvoiceDocuments = new ArrayList<CustomerInvoiceDocument>();
484
485 if (docNumbers.size() != 0) {
486 System.out.println(docNumbers);
487 // customerInvoiceDocuments.clear();
488 try {
489 customerInvoiceDocuments = documentService.getDocumentsByListOfDocumentHeaderIds(CustomerInvoiceDocument.class, docNumbers);
490 }
491 catch (WorkflowException e) {
492 throw new InfrastructureException("Unable to retrieve Customer Invoice Documents", e);
493 }
494 }
495 return customerInvoiceDocuments;
496 }
497
498 public List<CustomerInvoiceDocument> getCustomerInvoiceDocumentsByBillingChartAndOrg(String chartOfAccountsCode, String organizationCode) {
499 List<String> documentHeaderIds = customerInvoiceDocumentDao.getCustomerInvoiceDocumentNumbersByBillingChartAndOrg(chartOfAccountsCode, organizationCode);
500
501 List<CustomerInvoiceDocument> customerInvoiceDocuments = new ArrayList<CustomerInvoiceDocument>();
502 if (documentHeaderIds != null && !documentHeaderIds.isEmpty()) {
503 try {
504 customerInvoiceDocuments = documentService.getDocumentsByListOfDocumentHeaderIds(CustomerInvoiceDocument.class, documentHeaderIds);
505 }
506 catch (WorkflowException e) {
507 throw new InfrastructureException("Unable to retrieve Customer Invoice Documents", e);
508 }
509 }
510 return customerInvoiceDocuments;
511 }
512
513 /**
514 * @see org.kuali.module.ar.service.CustomerInvoiceDocumentService#getCustomerInvoiceDocumentsByCustomerNumber(java.lang.String)
515 */
516 public List<CustomerInvoiceDocument> getCustomerInvoiceDocumentsByProcessingChartAndOrg(String chartOfAccountsCode, String organizationCode) {
517
518 List<String> documentHeaderIds = customerInvoiceDocumentDao.getCustomerInvoiceDocumentNumbersByProcessingChartAndOrg(chartOfAccountsCode, organizationCode);
519
520 List<CustomerInvoiceDocument> customerInvoiceDocuments = new ArrayList<CustomerInvoiceDocument>();
521 if (documentHeaderIds != null && !documentHeaderIds.isEmpty()) {
522 try {
523 customerInvoiceDocuments = documentService.getDocumentsByListOfDocumentHeaderIds(CustomerInvoiceDocument.class, documentHeaderIds);
524 }
525 catch (WorkflowException e) {
526 throw new InfrastructureException("Unable to retrieve Customer Invoice Documents", e);
527 }
528 }
529 return customerInvoiceDocuments;
530 }
531
532 /**
533 * Refactor to have all the setters in here.
534 *
535 * @see org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#setupDefaultValuesForNewCustomerInvoiceDocument(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument)
536 */
537 public void setupDefaultValuesForNewCustomerInvoiceDocument(CustomerInvoiceDocument document) {
538
539 setupBasicDefaultValuesForCustomerInvoiceDocument(document);
540
541 // set up the default values for the AR DOC Header
542
543 AccountsReceivableDocumentHeader accountsReceivableDocumentHeader = accountsReceivableDocumentHeaderService.getNewAccountsReceivableDocumentHeaderForCurrentUser();
544 accountsReceivableDocumentHeader.setDocumentNumber(document.getDocumentNumber());
545 document.setAccountsReceivableDocumentHeader(accountsReceivableDocumentHeader);
546
547 // set up the primary key for AR_INV_RCURRNC_DTL_T
548 CustomerInvoiceRecurrenceDetails recurrenceDetails = new CustomerInvoiceRecurrenceDetails();
549 recurrenceDetails.setInvoiceNumber(document.getDocumentNumber());
550 // recurrenceDetails.setCustomerNumber(document.getCustomer().getCustomerNumber());
551 document.setCustomerInvoiceRecurrenceDetails(recurrenceDetails);
552
553 Map<String, String> criteria = new HashMap<String, String>();
554 criteria.put("chartOfAccountsCode", document.getBillByChartOfAccountCode());
555 criteria.put("organizationCode", document.getBilledByOrganizationCode());
556 OrganizationOptions organizationOptions = (OrganizationOptions) businessObjectService.findByPrimaryKey(OrganizationOptions.class, criteria);
557
558 if (ObjectUtils.isNotNull(organizationOptions)) {
559 document.setPrintInvoiceIndicator(organizationOptions.getPrintInvoiceIndicator());
560 document.setInvoiceTermsText(organizationOptions.getOrganizationPaymentTermsText());
561 }
562
563 // If document is using receivable option, set receivable accounting line for customer invoice document
564 String receivableOffsetOption = SpringContext.getBean(ParameterService.class).getParameterValue(CustomerInvoiceDocument.class, ArConstants.GLPE_RECEIVABLE_OFFSET_GENERATION_METHOD);
565 boolean isUsingReceivableFAU = ArConstants.GLPE_RECEIVABLE_OFFSET_GENERATION_METHOD_FAU.equals(receivableOffsetOption);
566 if (isUsingReceivableFAU) {
567 receivableAccountingLineService.setReceivableAccountingLineForCustomerInvoiceDocument(document);
568 }
569 }
570
571 /**
572 * @see org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#loadCustomerAddressesForCustomerInvoiceDocument(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument)
573 */
574 public void loadCustomerAddressesForCustomerInvoiceDocument(CustomerInvoiceDocument customerInvoiceDocument) {
575 // if address identifier is provided, try to refresh customer address data
576 if (ObjectUtils.isNotNull(customerInvoiceDocument.getAccountsReceivableDocumentHeader())) {
577 CustomerAddressService customerAddressService = SpringContext.getBean(CustomerAddressService.class);
578 CustomerAddress customerShipToAddress = customerAddressService.getByPrimaryKey(customerInvoiceDocument.getAccountsReceivableDocumentHeader().getCustomerNumber(), customerInvoiceDocument.getCustomerShipToAddressIdentifier());
579 CustomerAddress customerBillToAddress = customerAddressService.getByPrimaryKey(customerInvoiceDocument.getAccountsReceivableDocumentHeader().getCustomerNumber(), customerInvoiceDocument.getCustomerBillToAddressIdentifier());
580
581 if (ObjectUtils.isNotNull(customerShipToAddress)) {
582 customerInvoiceDocument.setCustomerShipToAddress(customerShipToAddress);
583 customerInvoiceDocument.setCustomerShipToAddressOnInvoice(customerShipToAddress);
584 }
585
586 if (ObjectUtils.isNotNull(customerBillToAddress)) {
587 customerInvoiceDocument.setCustomerBillToAddress(customerBillToAddress);
588 customerInvoiceDocument.setCustomerBillToAddressOnInvoice(customerBillToAddress);
589 }
590 }
591 }
592
593 /**
594 * @see org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#setupDefaultValuesForCopiedCustomerInvoiceDocument(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument)
595 */
596 public void setupDefaultValuesForCopiedCustomerInvoiceDocument(CustomerInvoiceDocument document) {
597
598 setupBasicDefaultValuesForCustomerInvoiceDocument(document);
599
600 // Save customer number since it will get overwritten when we retrieve the accounts receivable document header from service
601 String customerNumber = document.getAccountsReceivableDocumentHeader().getCustomerNumber();
602
603 // Set up the default values for the AR DOC Header
604 AccountsReceivableDocumentHeader accountsReceivableDocumentHeader = accountsReceivableDocumentHeaderService.getNewAccountsReceivableDocumentHeaderForCurrentUser();
605 accountsReceivableDocumentHeader.setDocumentNumber(document.getDocumentNumber());
606 accountsReceivableDocumentHeader.setCustomerNumber(customerNumber);
607 document.setAccountsReceivableDocumentHeader(accountsReceivableDocumentHeader);
608
609 // set up the primary key for AR_INV_RCURRNC_DTL_T
610 CustomerInvoiceRecurrenceDetails recurrenceDetails = new CustomerInvoiceRecurrenceDetails();
611 recurrenceDetails.setInvoiceNumber(document.getDocumentNumber());
612 // recurrenceDetails.setCustomerNumber(document.getAccountsReceivableDocumentHeader().getCustomerNumber());
613 document.setCustomerInvoiceRecurrenceDetails(recurrenceDetails);
614
615 // make open invoice indicator to true
616 document.setOpenInvoiceIndicator(true);
617 document.setPrintDate(null);
618 document.setBillingDate(SpringContext.getBean(DateTimeService.class).getCurrentSqlDateMidnight());
619 }
620
621 /**
622 * @see org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#getInvoicePaidAppliedsForCustomerInvoiceDocument(java.lang.String)
623 */
624 // public Collection<InvoicePaidApplied> getInvoicePaidAppliedsForInvoice(String documentNumber) {
625 // return invoicePaidAppliedService.getInvoicePaidAppliedsForInvoice(documentNumber);
626 // }
627 /**
628 * @see org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#getNonInvoicedDistributionsForInvoice(java.lang.String)
629 */
630 public Collection<NonInvoicedDistribution> getNonInvoicedDistributionsForInvoice(String documentNumber) {
631 return nonInvoicedDistributionService.getNonInvoicedDistributionsForInvoice(documentNumber);
632 }
633
634 /**
635 * @see org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#getNonInvoicedTotalForInvoice(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument)
636 */
637 public KualiDecimal getNonInvoicedTotalForInvoice(CustomerInvoiceDocument invoice) {
638 Collection<NonInvoicedDistribution> payments = this.nonInvoicedDistributionService.getNonInvoicedDistributionsForInvoice(invoice);
639 KualiDecimal total = new KualiDecimal(0);
640 for (NonInvoicedDistribution payment : payments) {
641 total = total.add(payment.getFinancialDocumentLineAmount());
642 }
643 return total;
644 }
645
646 /**
647 * @see org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#getNonInvoicedTotalForInvoice(java.lang.String)
648 */
649 public KualiDecimal getNonInvoicedTotalForInvoice(String documentNumber) {
650 return getNonInvoicedTotalForInvoice(getInvoiceByInvoiceDocumentNumber(documentNumber));
651 }
652
653 /**
654 * @see org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#getPaidAppliedTotalForInvoice(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument)
655 */
656 public KualiDecimal getPaidAppliedTotalForInvoice(CustomerInvoiceDocument invoice) {
657 Collection<InvoicePaidApplied> payments = invoicePaidAppliedService.getInvoicePaidAppliedsForInvoice(invoice);
658 KualiDecimal total = new KualiDecimal(0);
659 for (InvoicePaidApplied payment : payments) {
660 total = total.add(payment.getInvoiceItemAppliedAmount());
661 }
662 return total;
663 }
664
665 /**
666 * @see org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#getPaidAppliedTotalForInvoice(java.lang.String)
667 */
668 public KualiDecimal getPaidAppliedTotalForInvoice(String documentNumber) {
669 return getPaidAppliedTotalForInvoice(getInvoiceByInvoiceDocumentNumber(documentNumber));
670 }
671
672 /**
673 * @param document
674 */
675 protected void setupBasicDefaultValuesForCustomerInvoiceDocument(CustomerInvoiceDocument document) {
676 ChartOrgHolder currentUser = SpringContext.getBean(FinancialSystemUserService.class).getPrimaryOrganization(GlobalVariables.getUserSession().getPerson(), ArConstants.AR_NAMESPACE_CODE);
677 if (currentUser != null) {
678 document.setBillByChartOfAccountCode(currentUser.getChartOfAccountsCode());
679 document.setBilledByOrganizationCode(currentUser.getOrganizationCode());
680 }
681 document.setInvoiceDueDate(getDefaultInvoiceDueDate());
682 document.setOpenInvoiceIndicator(true);
683 }
684
685 /**
686 * This method sets due date equal to todays date +30 days by default
687 *
688 * @param dateTimeService
689 */
690 protected Date getDefaultInvoiceDueDate() {
691 Calendar cal = dateTimeService.getCurrentCalendar();
692 cal.add(Calendar.DATE, 30);
693 Date sqlDueDate = null;
694 try {
695 sqlDueDate = dateTimeService.convertToSqlDate(new Timestamp(cal.getTime().getTime()));
696 }
697 catch (ParseException e) {
698 // TODO: throw an error here, but don't die
699 }
700 return sqlDueDate;
701 }
702
703 public void closeCustomerInvoiceDocument(CustomerInvoiceDocument customerInvoiceDocument) {
704 customerInvoiceDocument.setOpenInvoiceIndicator(false);
705 customerInvoiceDocument.setClosedDate(dateTimeService.getCurrentSqlDate());
706 businessObjectService.save(customerInvoiceDocument);
707 }
708
709 public CustomerInvoiceDocumentDao getCustomerInvoiceDocumentDao() {
710 return customerInvoiceDocumentDao;
711 }
712
713 public void setCustomerInvoiceDocumentDao(CustomerInvoiceDocumentDao customerInvoiceDocumentDao) {
714 this.customerInvoiceDocumentDao = customerInvoiceDocumentDao;
715 }
716
717 public DocumentService getDocumentService() {
718 return documentService;
719 }
720
721 public void setDocumentService(DocumentService documentService) {
722 this.documentService = documentService;
723 }
724
725 public BusinessObjectService getBusinessObjectService() {
726 return businessObjectService;
727 }
728
729 public void setBusinessObjectService(BusinessObjectService businessObjectService) {
730 this.businessObjectService = businessObjectService;
731 }
732
733 public DateTimeService getDateTimeService() {
734 return dateTimeService;
735 }
736
737 public void setDateTimeService(DateTimeService dateTimeService) {
738 this.dateTimeService = dateTimeService;
739 }
740
741 public ReceivableAccountingLineService getReceivableAccountingLineService() {
742 return receivableAccountingLineService;
743 }
744
745 public void setReceivableAccountingLineService(ReceivableAccountingLineService receivableAccountingLineService) {
746 this.receivableAccountingLineService = receivableAccountingLineService;
747 }
748
749 public AccountsReceivableDocumentHeaderService getAccountsReceivableDocumentHeaderService() {
750 return accountsReceivableDocumentHeaderService;
751 }
752
753 public void setAccountsReceivableDocumentHeaderService(AccountsReceivableDocumentHeaderService accountsReceivableDocumentHeaderService) {
754 this.accountsReceivableDocumentHeaderService = accountsReceivableDocumentHeaderService;
755 }
756
757 public CustomerAddressService getCustomerAddressService() {
758 return customerAddressService;
759 }
760
761 public void setCustomerAddressService(CustomerAddressService customerAddressService) {
762 this.customerAddressService = customerAddressService;
763 }
764
765 public void setDocumentDao(DocumentDao documentDao) {
766 this.documentDao = documentDao;
767 }
768
769 public void setInvoicePaidAppliedService(InvoicePaidAppliedService invoicePaidAppliedService) {
770 this.invoicePaidAppliedService = invoicePaidAppliedService;
771 }
772
773 public void setNonInvoicedDistributionService(NonInvoicedDistributionService nonInvoicedDistributionService) {
774 this.nonInvoicedDistributionService = nonInvoicedDistributionService;
775 }
776
777 public void setCustomerInvoiceDetailService(CustomerInvoiceDetailService customerInvoiceDetailService) {
778 this.customerInvoiceDetailService = customerInvoiceDetailService;
779 }
780
781 public void setUniversityDateService(UniversityDateService universityDateService) {
782 this.universityDateService = universityDateService;
783 }
784
785 /**
786 * @return Returns the personService.
787 */
788 protected PersonService<Person> getPersonService() {
789 if (personService == null)
790 personService = SpringContext.getBean(PersonService.class);
791 return personService;
792 }
793
794 /**
795 * @see org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#checkIfInvoiceNumberIsFinal(java.lang.String)
796 */
797 public boolean checkIfInvoiceNumberIsFinal(String invDocumentNumber) {
798 boolean success = true;
799 if (StringUtils.isBlank(invDocumentNumber)) {
800 success &= false;
801 }
802 else {
803 CustomerInvoiceDocumentService service = SpringContext.getBean(CustomerInvoiceDocumentService.class);
804 CustomerInvoiceDocument customerInvoiceDocument = service.getInvoiceByInvoiceDocumentNumber(invDocumentNumber);
805
806 if (ObjectUtils.isNull(customerInvoiceDocument)) {
807 success &= false;
808 }
809 else {
810 Document doc = null;
811 try {
812 doc = SpringContext.getBean(DocumentService.class).getByDocumentHeaderId(invDocumentNumber);
813 }
814 catch (WorkflowException e) {
815 success &= false;
816 }
817 if (ObjectUtils.isNull(doc) || ObjectUtils.isNull(doc.getDocumentHeader()) || doc.getDocumentHeader().getWorkflowDocument() == null || !(doc.getDocumentHeader().getWorkflowDocument().stateIsApproved() || doc.getDocumentHeader().getWorkflowDocument().stateIsProcessed())) {
818 success &= false;
819 }
820 }
821 }
822 return success;
823 }
824
825 }