/**
   * @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);
    }
  }
  @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);
    }
  }