/**
   * @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;
  }
  /**
   * @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#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#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;
  }
  /**
   * @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;
  }
  /**
   * 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);
    }
  }
  /**
   * @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#getCustomerInvoiceDetailsForCustomerInvoiceDocument(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument)
  */
 @Override
 public Collection<CustomerInvoiceDetail> getCustomerInvoiceDetailsForCustomerInvoiceDocument(
     CustomerInvoiceDocument customerInvoiceDocument) {
   return getCustomerInvoiceDetailsForCustomerInvoiceDocument(
       customerInvoiceDocument.getDocumentNumber());
 }