gt:             invoiceWriteoffAmount = customerInvoiceDocument.getOpenAmount();
context: /*
   * The Kuali Financial System, a comprehensive financial management system for higher education.
   * 
   * Copyright 2005-2014 The Kuali Foundation
   * 
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU Affero General Public License as
   * published by the Free Software Foundation, either version 3 of the
   * License, or (at your option) any later version.
   * 
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU Affero General Public License for more details.
   * 
   * You should have received a copy of the GNU Affero General Public License
   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  package org.kuali.kfs.module.ar.document;
  
  import java.sql.Date;
  import java.util.ArrayList;
  import java.util.List;
  
  import org.apache.commons.lang.StringUtils;
  import org.kuali.kfs.coa.businessobject.Account;
  import org.kuali.kfs.coa.businessobject.Chart;
  import org.kuali.kfs.coa.businessobject.ObjectCode;
  import org.kuali.kfs.coa.businessobject.ProjectCode;
  import org.kuali.kfs.coa.businessobject.SubAccount;
  import org.kuali.kfs.coa.businessobject.SubObjectCode;
  import org.kuali.kfs.module.ar.ArConstants;
  import org.kuali.kfs.module.ar.businessobject.AccountsReceivableDocumentHeader;
  import org.kuali.kfs.module.ar.businessobject.CustomerInvoiceDetail;
  import org.kuali.kfs.module.ar.businessobject.ReceivableCustomerInvoiceDetail;
  import org.kuali.kfs.module.ar.businessobject.SalesTaxCustomerInvoiceDetail;
  import org.kuali.kfs.module.ar.businessobject.WriteoffCustomerInvoiceDetail;
  import org.kuali.kfs.module.ar.businessobject.WriteoffTaxCustomerInvoiceDetail;
  import org.kuali.kfs.module.ar.document.service.AccountsReceivablePendingEntryService;
  import org.kuali.kfs.module.ar.document.service.AccountsReceivableTaxService;
  import org.kuali.kfs.module.ar.document.service.CustomerInvoiceWriteoffDocumentService;
  import org.kuali.kfs.module.ar.document.service.CustomerService;
  import org.kuali.kfs.sys.KFSConstants;
  import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntry;
  import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper;
  import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail;
  import org.kuali.kfs.sys.businessobject.TaxDetail;
  import org.kuali.kfs.sys.context.SpringContext;
  import org.kuali.kfs.sys.document.AmountTotaling;
  import org.kuali.kfs.sys.document.GeneralLedgerPendingEntrySource;
  import org.kuali.kfs.sys.document.GeneralLedgerPostingDocumentBase;
  import org.kuali.kfs.sys.service.GeneralLedgerPendingEntryService;
  import org.kuali.kfs.sys.service.TaxService;
  import org.kuali.rice.core.api.util.type.KualiDecimal;
  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
  import org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange;
  import org.kuali.rice.krad.bo.Note;
  import org.kuali.rice.krad.exception.ValidationException;
  import org.kuali.rice.krad.rules.rule.event.KualiDocumentEvent;
  import org.kuali.rice.krad.util.ObjectUtils;
  
  public class CustomerInvoiceWriteoffDocument extends GeneralLedgerPostingDocumentBase implements GeneralLedgerPendingEntrySource, AmountTotaling {
  
      protected static final String REQUIRES_APPROVAL_NODE = "RequiresApproval";
      protected String chartOfAccountsCode;
      protected String accountNumber;
      protected String subAccountNumber;
      protected String financialObjectCode;
      protected String financialSubObjectCode;
      protected String projectCode;
      protected String organizationReferenceIdentifier;
      protected String financialDocumentReferenceInvoiceNumber;
      protected String statusCode;
  
      protected String customerNote;
  
      protected Account account;
      protected Chart chartOfAccounts;
      protected SubAccount subAccount;
      protected ObjectCode financialObject;
      protected SubObjectCode financialSubObject;
      protected ProjectCode project;
      protected CustomerInvoiceDocument customerInvoiceDocument;
      protected AccountsReceivableDocumentHeader accountsReceivableDocumentHeader;
      protected KualiDecimal invoiceWriteoffAmount;
  
      // GLPEs from invoice to be written off - used for collecting tax amounts that should be written off
      protected class WriteOffGlpes {
          GeneralLedgerPendingEntry glpe;
          boolean isWriteOffDetail;
  
          public WriteOffGlpes(GeneralLedgerPendingEntry pe, boolean writeOff) {
              this.glpe = pe;
              this.isWriteOffDetail = writeOff;
          }
      }
  
      public AccountsReceivableDocumentHeader getAccountsReceivableDocumentHeader() {
          return accountsReceivableDocumentHeader;
      }
  
      public void setAccountsReceivableDocumentHeader(AccountsReceivableDocumentHeader accountsReceivableDocumentHeader) {
          this.accountsReceivableDocumentHeader = accountsReceivableDocumentHeader;
      }
  
      public String getChartOfAccountsCode() {
          return chartOfAccountsCode;
      }
  
      public void setChartOfAccountsCode(String chartOfAccountsCode) {
          this.chartOfAccountsCode = chartOfAccountsCode;
      }
  
      public String getAccountNumber() {
          return accountNumber;
      }
  
      public void setAccountNumber(String accountNumber) {
          this.accountNumber = accountNumber;
      }
  
      public String getSubAccountNumber() {
          return subAccountNumber;
      }
  
      public void setSubAccountNumber(String subAccountNumber) {
          this.subAccountNumber = subAccountNumber;
      }
  
      public String getFinancialObjectCode() {
          return financialObjectCode;
      }
  
      public void setFinancialObjectCode(String financialObjectCode) {
          this.financialObjectCode = financialObjectCode;
      }
  
      public String getFinancialSubObjectCode() {
          return financialSubObjectCode;
      }
  
      public void setFinancialSubObjectCode(String financialSubObjectCode) {
          this.financialSubObjectCode = financialSubObjectCode;
      }
  
      public String getProjectCode() {
          return projectCode;
      }
  
      public void setProjectCode(String projectCode) {
          this.projectCode = projectCode;
      }
  
      public String getOrganizationReferenceIdentifier() {
          return organizationReferenceIdentifier;
      }
  
      public void setOrganizationReferenceIdentifier(String organizationReferenceIdentifier) {
          this.organizationReferenceIdentifier = organizationReferenceIdentifier;
      }
  
      public String getFinancialDocumentReferenceInvoiceNumber() {
          return financialDocumentReferenceInvoiceNumber;
      }
  
      public void setFinancialDocumentReferenceInvoiceNumber(String financialDocumentReferenceInvoiceNumber) {
          this.financialDocumentReferenceInvoiceNumber = financialDocumentReferenceInvoiceNumber;
      }
  
      public Account getAccount() {
          return account;
      }
  
      public void setAccount(Account account) {
          this.account = account;
      }
  
      public Chart getChartOfAccounts() {
          return chartOfAccounts;
      }
  
      public void setChartOfAccounts(Chart chartOfAccounts) {
          this.chartOfAccounts = chartOfAccounts;
      }
  
      public SubAccount getSubAccount() {
          return subAccount;
      }
  
      public void setSubAccount(SubAccount subAccount) {
          this.subAccount = subAccount;
      }
  
      public ObjectCode getFinancialObject() {
          return financialObject;
      }
  
      public void setFinancialObject(ObjectCode financialObject) {
          this.financialObject = financialObject;
      }
  
      public SubObjectCode getFinancialSubObject() {
          return financialSubObject;
      }
  
      public void setFinancialSubObject(SubObjectCode financialSubObject) {
          this.financialSubObject = financialSubObject;
      }
  
      public ProjectCode getProject() {
          return project;
      }
  
      public void setProject(ProjectCode project) {
          this.project = project;
      }
  
      public CustomerInvoiceDocument getCustomerInvoiceDocument() {
          if (ObjectUtils.isNull(customerInvoiceDocument) && StringUtils.isNotEmpty(financialDocumentReferenceInvoiceNumber)) {
              refreshReferenceObject("customerInvoiceDocument");
          }
  
          return customerInvoiceDocument;
      }
  
      public void setCustomerInvoiceDocument(CustomerInvoiceDocument customerInvoiceDocument) {
          this.customerInvoiceDocument = customerInvoiceDocument;
      }
  
      /**
       * This method returns all the applicable invoice details for writeoff. This method also sets the writeoff document number on
       * each of the invoice details for making retrieval of the actual writeoff amount easier.
       *
       * @return
       */
      public List<CustomerInvoiceDetail> getCustomerInvoiceDetailsForWriteoff() {
          List<CustomerInvoiceDetail> customerInvoiceDetailsForWriteoff = new ArrayList<CustomerInvoiceDetail>();
          for (CustomerInvoiceDetail customerInvoiceDetail : getCustomerInvoiceDocument().getCustomerInvoiceDetailsWithoutDiscounts()) {
              customerInvoiceDetail.setCustomerInvoiceWriteoffDocumentNumber(this.documentNumber);
              customerInvoiceDetailsForWriteoff.add(customerInvoiceDetail);
          }
  
          return customerInvoiceDetailsForWriteoff;
      }
  
      /**
       * This method returns the total amount to be written off
       *
       * @return
       */
      public KualiDecimal getInvoiceWriteoffAmount() {
          // only pull the invoice open amount as the invoice writeoff amount while the doc
          // is in play. once its been approved, rely on the amount stored in the db.
          if (!KFSConstants.DocumentStatusCodes.APPROVED.equals(getFinancialSystemDocumentHeader().getFinancialDocumentStatusCode())) {
  