/** * @see * org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#attachWorkflowHeadersToTheInvoices(java.util.Collection) */ @Override public Collection<CustomerInvoiceDocument> attachWorkflowHeadersToTheInvoices( Collection<CustomerInvoiceDocument> invoices) { List<CustomerInvoiceDocument> docs = new ArrayList<CustomerInvoiceDocument>(); if (invoices == null || invoices.isEmpty()) { return docs; } // make a list of necessary workflow docs to retrieve List<String> documentHeaderIds = new ArrayList<String>(); for (CustomerInvoiceDocument invoice : invoices) { documentHeaderIds.add(invoice.getDocumentNumber()); } // get all of our docs with full workflow headers try { for (Document doc : documentService.getDocumentsByListOfDocumentHeaderIds( CustomerInvoiceDocument.class, documentHeaderIds)) { docs.add((CustomerInvoiceDocument) doc); } } catch (WorkflowException e) { throw new RuntimeException("Unable to retrieve Customer Invoice Documents", e); } return docs; }
/** * @see * org.kuali.kfs.module.ar.document.service.AccountsReceivableTaxService#getPostalCodeForTaxation(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument) */ @Override public String getPostalCodeForTaxation(CustomerInvoiceDocument document) { String postalCode = null; String customerNumber = document.getAccountsReceivableDocumentHeader().getCustomerNumber(); Integer shipToAddressIdentifier = document.getCustomerShipToAddressIdentifier(); // if customer number or ship to address id isn't provided, go to org options if (ObjectUtils.isNotNull(shipToAddressIdentifier) && StringUtils.isNotEmpty(customerNumber)) { CustomerAddressService customerAddressService = SpringContext.getBean(CustomerAddressService.class); CustomerAddress customerShipToAddress = customerAddressService.getByPrimaryKey(customerNumber, shipToAddressIdentifier); if (ObjectUtils.isNotNull(customerShipToAddress)) { postalCode = customerShipToAddress.getCustomerZipCode(); } } else { Map<String, String> criteria = new HashMap<String, String>(); criteria.put("chartOfAccountsCode", document.getBillByChartOfAccountCode()); criteria.put("organizationCode", document.getBilledByOrganizationCode()); OrganizationOptions organizationOptions = (OrganizationOptions) businessObjectService.findByPrimaryKey(OrganizationOptions.class, criteria); if (ObjectUtils.isNotNull(organizationOptions)) { postalCode = organizationOptions.getOrganizationPostalZipCode(); } } return postalCode; }
/** * @param includeWorkflowHeaders * @return */ public Collection<CustomerInvoiceDocument> getAllOpenCustomerInvoiceDocuments( boolean includeWorkflowHeaders) { Collection<CustomerInvoiceDocument> invoices = new ArrayList<CustomerInvoiceDocument>(); // retrieve the set of documents without workflow headers invoices = customerInvoiceDocumentDao.getAllOpen(); // if we dont need workflow headers, then we're done if (!includeWorkflowHeaders) { return invoices; } // make a list of necessary workflow docs to retrieve List<String> documentHeaderIds = new ArrayList<String>(); for (CustomerInvoiceDocument invoice : invoices) { documentHeaderIds.add(invoice.getDocumentNumber()); } // get all of our docs with full workflow headers List<CustomerInvoiceDocument> docs = new ArrayList<CustomerInvoiceDocument>(); try { for (Document doc : documentService.getDocumentsByListOfDocumentHeaderIds( CustomerInvoiceDocument.class, documentHeaderIds)) { docs.add((CustomerInvoiceDocument) doc); } } catch (WorkflowException e) { throw new RuntimeException("Unable to retrieve Customer Invoice Documents", e); } return docs; }
/** * @see * org.kuali.kfs.module.ar.document.service.InvoiceRecurrenceService#isInvoiceApproved(String) */ @Override public boolean isInvoiceApproved(String invoiceNumber) { boolean success = true; if (ObjectUtils.isNull(invoiceNumber)) { return success; } CustomerInvoiceDocument customerInvoiceDocument = null; try { customerInvoiceDocument = (CustomerInvoiceDocument) SpringContext.getBean(DocumentService.class).getByDocumentHeaderId(invoiceNumber); } catch (WorkflowException e) { } if (ObjectUtils.isNotNull(customerInvoiceDocument)) { WorkflowDocument workflowDocument = customerInvoiceDocument.getDocumentHeader().getWorkflowDocument(); if (!(workflowDocument.isApproved())) { success = false; } } else { success = false; } return success; }
/** * @see * org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#loadCustomerAddressesForCustomerInvoiceDocument(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument) */ @Override public void loadCustomerAddressesForCustomerInvoiceDocument( CustomerInvoiceDocument customerInvoiceDocument) { // if address identifier is provided, try to refresh customer address data if (ObjectUtils.isNotNull(customerInvoiceDocument.getAccountsReceivableDocumentHeader())) { CustomerAddress customerShipToAddress = customerAddressService.getByPrimaryKey( customerInvoiceDocument.getAccountsReceivableDocumentHeader().getCustomerNumber(), customerInvoiceDocument.getCustomerShipToAddressIdentifier()); CustomerAddress customerBillToAddress = customerAddressService.getByPrimaryKey( customerInvoiceDocument.getAccountsReceivableDocumentHeader().getCustomerNumber(), customerInvoiceDocument.getCustomerBillToAddressIdentifier()); if (ObjectUtils.isNotNull(customerShipToAddress)) { customerInvoiceDocument.setCustomerShipToAddress(customerShipToAddress); customerInvoiceDocument.setCustomerShipToAddressOnInvoice(customerShipToAddress); } if (ObjectUtils.isNotNull(customerBillToAddress)) { customerInvoiceDocument.setCustomerBillToAddress(customerBillToAddress); customerInvoiceDocument.setCustomerBillToAddressOnInvoice(customerBillToAddress); } } }
/** @param document */ protected void setupBasicDefaultValuesForCustomerInvoiceDocument( CustomerInvoiceDocument document) { ChartOrgHolder currentUser = financialSystemUserService.getPrimaryOrganization( GlobalVariables.getUserSession().getPerson(), ArConstants.AR_NAMESPACE_CODE); if (currentUser != null) { document.setBillByChartOfAccountCode(currentUser.getChartOfAccountsCode()); document.setBilledByOrganizationCode(currentUser.getOrganizationCode()); } document.setInvoiceDueDate(getDefaultInvoiceDueDate()); document.setOpenInvoiceIndicator(true); }
/** * @see * org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#updateReportedDate(String) */ @Override public void updateReportedDate(String docNumber) { HashMap<String, String> criteria = new HashMap<String, String>(); criteria.put("documentNumber", docNumber); CustomerInvoiceDocument customerInvoiceDocument = businessObjectService.findByPrimaryKey(CustomerInvoiceDocument.class, criteria); Date reportedDate = dateTimeService.getCurrentSqlDate(); if (ObjectUtils.isNotNull(customerInvoiceDocument)) { customerInvoiceDocument.setReportedDate(reportedDate); businessObjectService.save(customerInvoiceDocument); } }
/** * @see * org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#setupDefaultValuesForCopiedCustomerInvoiceDocument(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument) */ @Override public void setupDefaultValuesForCopiedCustomerInvoiceDocument(CustomerInvoiceDocument document) { setupBasicDefaultValuesForCustomerInvoiceDocument(document); // Save customer number since it will get overwritten when we retrieve the accounts receivable // document header from service String customerNumber = document.getAccountsReceivableDocumentHeader().getCustomerNumber(); // Set up the default values for the AR DOC Header AccountsReceivableDocumentHeader accountsReceivableDocumentHeader = accountsReceivableDocumentHeaderService .getNewAccountsReceivableDocumentHeaderForCurrentUser(); accountsReceivableDocumentHeader.setDocumentNumber(document.getDocumentNumber()); accountsReceivableDocumentHeader.setCustomerNumber(customerNumber); document.setAccountsReceivableDocumentHeader(accountsReceivableDocumentHeader); // set up the primary key for AR_INV_RCURRNC_DTL_T CustomerInvoiceRecurrenceDetails recurrenceDetails = new CustomerInvoiceRecurrenceDetails(); recurrenceDetails.setInvoiceNumber(document.getDocumentNumber()); // recurrenceDetails.setCustomerNumber(document.getAccountsReceivableDocumentHeader().getCustomerNumber()); document.setCustomerInvoiceRecurrenceDetails(recurrenceDetails); // make open invoice indicator to true document.setOpenInvoiceIndicator(true); document.setPrintDate(null); document.setBillingDate(dateTimeService.getCurrentSqlDateMidnight()); }
/** * @see * org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#convertDiscountsToPaidApplieds(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument) */ @Override public void convertDiscountsToPaidApplieds(CustomerInvoiceDocument invoice) { // this needs a little explanation. we have to calculate manually // whether we've written off the whole thing, because the regular // code uses the invoice paid applieds to discount, but since those // are added but not committed in this transaction, they're also not // visible in this transaction, so we do it manually. KualiDecimal openAmount = invoice.getOpenAmount(); String invoiceNumber = invoice.getDocumentNumber(); List<CustomerInvoiceDetail> discounts = invoice.getDiscounts(); // retrieve the number of current paid applieds, so we dont have item number overlap Integer paidAppliedItemNumber = 0; for (CustomerInvoiceDetail discount : discounts) { // if credit amount is zero, do nothing if (KualiDecimal.ZERO.equals(discount.getAmount())) { continue; } if (paidAppliedItemNumber == 0) { paidAppliedItemNumber = invoicePaidAppliedService.getNumberOfInvoicePaidAppliedsForInvoiceDetail( invoiceNumber, discount.getInvoiceItemNumber()); } // create and save the paidApplied InvoicePaidApplied invoicePaidApplied = new InvoicePaidApplied(); invoicePaidApplied.setDocumentNumber(invoiceNumber); invoicePaidApplied.setPaidAppliedItemNumber(paidAppliedItemNumber++); invoicePaidApplied.setFinancialDocumentReferenceInvoiceNumber(invoiceNumber); invoicePaidApplied.setInvoiceItemNumber(discount.getInvoiceItemNumber()); invoicePaidApplied.setUniversityFiscalYear(universityDateService.getCurrentFiscalYear()); invoicePaidApplied.setUniversityFiscalPeriodCode( universityDateService.getCurrentUniversityDate().getUniversityFiscalAccountingPeriod()); invoicePaidApplied.setInvoiceItemAppliedAmount(discount.getAmount().abs()); openAmount = openAmount.subtract(discount.getAmount().abs()); businessObjectService.save(invoicePaidApplied); } // if its open, but now with a zero openamount, then close it if (KualiDecimal.ZERO.equals(openAmount)) { invoice.setOpenInvoiceIndicator(false); invoice.setClosedDate(dateTimeService.getCurrentSqlDate()); documentService.updateDocument(invoice); } }
/** * @see * org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#getCustomerInvoiceDetailsForCustomerInvoiceDocumentWithCaching(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument) */ @Override public Collection<CustomerInvoiceDetail> getCustomerInvoiceDetailsForCustomerInvoiceDocumentWithCaching( CustomerInvoiceDocument customerInvoiceDocument) { return customerInvoiceDetailService.getCustomerInvoiceDetailsForInvoiceWithCaching( customerInvoiceDocument.getDocumentNumber()); }
/** * @see * org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#getOpenAmountForCustomerInvoiceDocument(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument) */ @Override public KualiDecimal getOpenAmountForCustomerInvoiceDocument( CustomerInvoiceDocument customerInvoiceDocument) { KualiDecimal total = new KualiDecimal(0); if (customerInvoiceDocument.isOpenInvoiceIndicator()) { Collection<CustomerInvoiceDetail> customerInvoiceDetails = customerInvoiceDocument.getCustomerInvoiceDetailsWithoutDiscounts(); for (CustomerInvoiceDetail detail : customerInvoiceDetails) { // note that we're now dealing with conditionally applying discounts // depending on whether the doc is saved or approved one level down, // in the CustomerInvoiceDetail.getAmountOpen() detail.setCustomerInvoiceDocument(customerInvoiceDocument); total = total.add(detail.getAmountOpen()); } } return total; }
/** * @see * org.kuali.kfs.module.ar.document.service.AccountsReceivableTaxService#isCustomerInvoiceDetailTaxable(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument, * org.kuali.kfs.module.ar.businessobject.CustomerInvoiceDetail) */ @Override public boolean isCustomerInvoiceDetailTaxable( CustomerInvoiceDocument customerInvoiceDocument, CustomerInvoiceDetail customerInvoiceDetail) { // check if sales tax is enabled if (!parameterService.getParameterValueAsBoolean( KfsParameterConstants.ACCOUNTS_RECEIVABLE_DOCUMENT.class, ArConstants.ENABLE_SALES_TAX_IND)) { return false; } // check if customer is tax exempt if (ObjectUtils.isNotNull(customerInvoiceDocument.getCustomer())) { if (customerInvoiceDocument.getCustomer().isCustomerTaxExemptIndicator()) { return false; } } // check item if the taxable indicator is checked if (!customerInvoiceDetail.isTaxableIndicator()) { return false; } // check item if item is taxable /* if( StringUtils.isNotEmpty(customerInvoiceDetail.getInvoiceItemCode()) ){ Map<String, String> criteria = new HashMap<String, String>(); criteria.put("invoiceItemCode", customerInvoiceDetail.getInvoiceItemCode()); criteria.put("chartOfAccountsCode", customerInvoiceDocument.getAccountsReceivableDocumentHeader().getProcessingChartOfAccountCode()); criteria.put("organizationCode", customerInvoiceDocument.getAccountsReceivableDocumentHeader().getProcessingOrganizationCode()); CustomerInvoiceItemCode customerInvoiceItemCode = (CustomerInvoiceItemCode) businessObjectService.findByPrimaryKey(CustomerInvoiceItemCode.class, criteria); if (ObjectUtils.isNotNull(customerInvoiceItemCode) && !customerInvoiceItemCode.isTaxableIndicator()){ return false; } } */ // if address of billing org's postal code isn't the same as shipping address, return false??? return true; }
/** * @see * org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#getOriginalTotalAmountForCustomerInvoiceDocument(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument) */ @Override public KualiDecimal getOriginalTotalAmountForCustomerInvoiceDocument( CustomerInvoiceDocument customerInvoiceDocument) { LOG.info( "\n\n\n\t\t invoice: " + customerInvoiceDocument.getDocumentNumber() + "\n\t\t 111111111 HEADER TOTAL AMOUNT (should be null): " + customerInvoiceDocument .getFinancialSystemDocumentHeader() .getFinancialDocumentTotalAmount() + "\n\n"); customerInvoiceDocument.getDocumentNumber(); HashMap criteria = new HashMap(); criteria.put( KFSPropertyConstants.DOCUMENT_NUMBER, customerInvoiceDocument.getDocumentHeader().getDocumentTemplateNumber()); FinancialSystemDocumentHeader financialSystemDocumentHeader = businessObjectService.findByPrimaryKey(FinancialSystemDocumentHeader.class, criteria); KualiDecimal originalTotalAmount = KualiDecimal.ZERO; originalTotalAmount = financialSystemDocumentHeader.getFinancialDocumentTotalAmount(); LOG.info( "\n\n\n\t\t invoice: " + customerInvoiceDocument.getDocumentNumber() + "\n\t\t 333333333333 HEADER TOTAL AMOUNT (should be set now): " + customerInvoiceDocument .getFinancialSystemDocumentHeader() .getFinancialDocumentTotalAmount() + "\n\n"); return originalTotalAmount; }
public boolean validate(AttributedDocumentEvent event) { if (StringUtils.isEmpty(customerInvoiceDocument.getPaymentAccountNumber())) { GlobalVariables.getMessageMap() .putError( DOCUMENT_ERROR_PREFIX + ArPropertyConstants.CustomerInvoiceDocumentFields.PAYMENT_ACCOUNT_NUMBER, OrganizationAccountingDefaultErrors.ERROR_PAYMENT_ACCOUNT_NUMBER_REQUIRED); return false; } else { customerInvoiceDocument.refreshReferenceObject( ArPropertyConstants.CustomerInvoiceDocumentFields.PAYMENT_ACCOUNT); if (ObjectUtils.isNull(customerInvoiceDocument.getPaymentAccount())) { GlobalVariables.getMessageMap() .putError( DOCUMENT_ERROR_PREFIX + ArPropertyConstants.CustomerInvoiceDocumentFields.PAYMENT_ACCOUNT_NUMBER, ArKeyConstants.ERROR_CUSTOMER_INVOICE_DOCUMENT_INVALID_PAYMENT_ACCOUNT_NUMBER); return false; } } return true; }
/** * Refactor to have all the setters in here. * * @see * org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#setupDefaultValuesForNewCustomerInvoiceDocument(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument) */ @Override public void setupDefaultValuesForNewCustomerInvoiceDocument(CustomerInvoiceDocument document) { setupBasicDefaultValuesForCustomerInvoiceDocument(document); // set up the default values for the AR DOC Header AccountsReceivableDocumentHeader accountsReceivableDocumentHeader = accountsReceivableDocumentHeaderService .getNewAccountsReceivableDocumentHeaderForCurrentUser(); accountsReceivableDocumentHeader.setDocumentNumber(document.getDocumentNumber()); document.setAccountsReceivableDocumentHeader(accountsReceivableDocumentHeader); // set up the primary key for AR_INV_RCURRNC_DTL_T CustomerInvoiceRecurrenceDetails recurrenceDetails = new CustomerInvoiceRecurrenceDetails(); recurrenceDetails.setInvoiceNumber(document.getDocumentNumber()); // recurrenceDetails.setCustomerNumber(document.getCustomer().getCustomerNumber()); document.setCustomerInvoiceRecurrenceDetails(recurrenceDetails); Map<String, String> criteria = new HashMap<String, String>(); criteria.put( KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, document.getBillByChartOfAccountCode()); criteria.put(KFSPropertyConstants.ORGANIZATION_CODE, document.getBilledByOrganizationCode()); OrganizationOptions organizationOptions = businessObjectService.findByPrimaryKey(OrganizationOptions.class, criteria); if (ObjectUtils.isNotNull(organizationOptions)) { document.setPrintInvoiceIndicator(organizationOptions.getPrintInvoiceIndicator()); document.setInvoiceTermsText(organizationOptions.getOrganizationPaymentTermsText()); } // If document is using receivable option, set receivable accounting line for customer invoice // document String receivableOffsetOption = parameterService.getParameterValueAsString( CustomerInvoiceDocument.class, ArConstants.GLPE_RECEIVABLE_OFFSET_GENERATION_METHOD); boolean isUsingReceivableFAU = ArConstants.GLPE_RECEIVABLE_OFFSET_GENERATION_METHOD_FAU.equals(receivableOffsetOption); if (isUsingReceivableFAU) { receivableAccountingLineService.setReceivableAccountingLineForCustomerInvoiceDocument( document); } }
@Override public void closeCustomerInvoiceDocument(CustomerInvoiceDocument customerInvoiceDocument) { customerInvoiceDocument.setOpenInvoiceIndicator(false); customerInvoiceDocument.setClosedDate(dateTimeService.getCurrentSqlDate()); businessObjectService.save(customerInvoiceDocument); }
/** * @see * org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#getCustomerInvoiceDetailsForCustomerInvoiceDocument(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument) */ @Override public Collection<CustomerInvoiceDetail> getCustomerInvoiceDetailsForCustomerInvoiceDocument( CustomerInvoiceDocument customerInvoiceDocument) { return getCustomerInvoiceDetailsForCustomerInvoiceDocument( customerInvoiceDocument.getDocumentNumber()); }
/** * @param invoiceDocumentNumber * @return */ @Override public Customer getCustomerByInvoiceDocumentNumber(String invoiceDocumentNumber) { CustomerInvoiceDocument invoice = getInvoiceByInvoiceDocumentNumber(invoiceDocumentNumber); return invoice.getAccountsReceivableDocumentHeader().getCustomer(); }
/** * @see * org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#getPrintableCustomerInvoiceDocumentsByInitiatorPrincipalName(java.lang.String) */ @Override public List<CustomerInvoiceDocument> getPrintableCustomerInvoiceDocumentsByInitiatorPrincipalName( String initiatorPrincipalName) { if (StringUtils.isBlank(initiatorPrincipalName)) { throw new IllegalArgumentException( "The parameter [initiatorPrincipalName] passed in was null or blank."); } // IMPORTANT NOTES ABOUT THIS METHOD // // This method behaves differently than the other invoice printing methods. This is // because there's no way from within KFS to do a direct DB call to get all the invoices // you want. This is because workflow holds the document initiator, and you cant guarantee // that in a given implementation that you have access to that other db. It could be on // another box in another network, and you only have web-services access to the Rice box. // // Given that, we try to minimize the resource hit of this call as much as possible. First // we retrieve all invoices that havent been printed (ie, dont have a print date) and that // are marked for the USER print queue. At any given time that should be a manageable number of // documents. // // Then we walk through them, retrieve the full workflow-populated version of it, and only // return the ones that match the initiator. // // This isnt as performant a solution as the other getPrintableCustomerInvoiceBy... // methods, but its the best we can do in this release, and it should be manageable. // // attempt to retrieve the initiator person specified, and puke if not found Principal initiator = KimApiServiceLocator.getIdentityService() .getPrincipalByPrincipalName(initiatorPrincipalName); if (initiator == null) { throw new IllegalArgumentException( "The parameter value for initiatorPrincipalName [" + initiatorPrincipalName + "] passed in doesnt map to a person."); } // retrieve all the ready-to-print docs in the user-queue for all users List<String> printableUserQueueDocNumbers = customerInvoiceDocumentDao.getPrintableCustomerInvoiceDocumentNumbersFromUserQueue(); // get all the documents that might be right, but this set includes documents generated // by the wrong user List<CustomerInvoiceDocument> customerInvoiceDocumentsSuperSet = new ArrayList<CustomerInvoiceDocument>(); if (printableUserQueueDocNumbers.size() > 0) { try { for (Document doc : documentService.getDocumentsByListOfDocumentHeaderIds( CustomerInvoiceDocument.class, printableUserQueueDocNumbers)) { customerInvoiceDocumentsSuperSet.add((CustomerInvoiceDocument) doc); } } catch (WorkflowException e) { throw new RuntimeException("Unable to retrieve Customer Invoice Documents", e); } } else { customerInvoiceDocumentsSuperSet = new ArrayList<CustomerInvoiceDocument>(); } // filter only the ones initiated by the correct user List<CustomerInvoiceDocument> customerInvoiceDocuments = new ArrayList<CustomerInvoiceDocument>(); for (CustomerInvoiceDocument superSetDocument : customerInvoiceDocumentsSuperSet) { if (StringUtils.equalsIgnoreCase( superSetDocument.getDocumentHeader().getWorkflowDocument().getInitiatorPrincipalId(), initiator.getPrincipalId())) { customerInvoiceDocuments.add(superSetDocument); } } return customerInvoiceDocuments; }
@Override public void completeCustomerCreditMemo(CustomerCreditMemoDocument creditMemo) { // retrieve the document and make sure its not already closed, crash if so String invoiceNumber = creditMemo.getFinancialDocumentReferenceInvoiceNumber(); CustomerInvoiceDocument invoice; try { invoice = (CustomerInvoiceDocument) documentService.getByDocumentHeaderId(invoiceNumber); } catch (WorkflowException e) { throw new RuntimeException( "A WorkflowException was generated when trying to load Customer Invoice #" + invoiceNumber + ".", e); } if (!invoice.isOpenInvoiceIndicator()) { throw new UnsupportedOperationException( "The CreditMemo Document #" + creditMemo.getDocumentNumber() + " attempted to credit " + "an Invoice [#" + invoiceNumber + "] that was already closed. This is not supported."); } // this needs a little explanation. we have to calculate manually // whether we've written off the whole thing, because the regular // code uses the invoice paid applieds to discount, but since those // are added but not committed in this transaction, they're also not // visible in this transaction, so we do it manually. KualiDecimal openAmount = invoice.getOpenAmount(); Integer paidAppliedItemNumber = 0; // retrieve the customer invoice details, and generate paid applieds for each List<CustomerCreditMemoDetail> details = creditMemo.getCreditMemoDetails(); for (CustomerCreditMemoDetail detail : details) { CustomerInvoiceDetail invoiceDetail = detail.getCustomerInvoiceDetail(); // if credit amount is zero, do nothing if (detail.getCreditMemoLineTotalAmount().isZero()) { continue; } // if credit amount is greater than the open amount, crash and complain if (detail .getCreditMemoLineTotalAmount() .abs() .isGreaterThan(invoiceDetail.getAmountOpen())) { throw new UnsupportedOperationException( "The credit detail for CreditMemo Document #" + creditMemo.getDocumentNumber() + " attempted " + "to credit more than the Open Amount on the Invoice Detail. This is not supported."); } // retrieve the number of current paid applieds, so we dont have item number overlap if (paidAppliedItemNumber == 0) { paidAppliedItemNumber = paidAppliedService.getNumberOfInvoicePaidAppliedsForInvoiceDetail( invoiceNumber, invoiceDetail.getInvoiceItemNumber()); } // create and save the paidApplied InvoicePaidApplied invoicePaidApplied = new InvoicePaidApplied(); invoicePaidApplied.setDocumentNumber(creditMemo.getDocumentNumber()); invoicePaidApplied.setPaidAppliedItemNumber(paidAppliedItemNumber++); invoicePaidApplied.setFinancialDocumentReferenceInvoiceNumber(invoiceNumber); invoicePaidApplied.setInvoiceItemNumber(invoiceDetail.getInvoiceItemNumber()); invoicePaidApplied.setUniversityFiscalYear(universityDateService.getCurrentFiscalYear()); invoicePaidApplied.setUniversityFiscalPeriodCode( universityDateService.getCurrentUniversityDate().getUniversityFiscalAccountingPeriod()); invoicePaidApplied.setInvoiceItemAppliedAmount(detail.getCreditMemoLineTotalAmount().abs()); openAmount = openAmount.subtract(detail.getCreditMemoLineTotalAmount().abs()); businessObjectService.save(invoicePaidApplied); } // if its open, but now with a zero openamount, then close it if (invoice.isOpenInvoiceIndicator() && KualiDecimal.ZERO.equals(openAmount)) { customerInvoiceDocumentService.addCloseNote( invoice, creditMemo.getDocumentHeader().getWorkflowDocument()); invoice.setOpenInvoiceIndicator(false); invoice.setClosedDate(dateTimeService.getCurrentSqlDate()); documentService.updateDocument(invoice); } }
/** * @see * org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService#getCustomerByOrganizationInvoiceNumber(java.lang.String) */ @Override public Customer getCustomerByOrganizationInvoiceNumber(String organizationInvoiceNumber) { CustomerInvoiceDocument invoice = getInvoiceByOrganizationInvoiceNumber(organizationInvoiceNumber); return invoice.getAccountsReceivableDocumentHeader().getCustomer(); }