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 }