/*
* 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.businessobject;
import java.math.BigDecimal;
import java.sql.Date;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.kuali.kfs.coa.businessobject.ObjectCode;
import org.kuali.kfs.coa.businessobject.SubObjectCode;
import org.kuali.kfs.integration.ar.AccountsReceivableCustomerInvoiceDetail;
import org.kuali.kfs.module.ar.document.CustomerInvoiceDocument;
import org.kuali.kfs.module.ar.document.service.CustomerInvoiceWriteoffDocumentService;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.businessobject.SourceAccountingLine;
import org.kuali.kfs.sys.businessobject.UnitOfMeasure;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.rice.core.api.util.type.KualiDecimal;
import org.kuali.rice.kew.api.exception.WorkflowException;
import org.kuali.rice.krad.service.BusinessObjectService;
import org.kuali.rice.krad.service.DocumentService;
import org.kuali.rice.krad.util.ObjectUtils;
/**
* This class represents a customer invoice detail on the customer invoice document. This class extends SourceAccountingLine since
* each customer invoice detail has associated accounting line information.
*
* @author Kuali Nervous System Team (kualidev@oncourse.iu.edu)
*/
public class CustomerInvoiceDetail extends SourceAccountingLine implements AppliedPayment, AccountsReceivableCustomerInvoiceDetail {
private static Logger LOG = Logger.getLogger(CustomerInvoiceDetail.class);
public static final String CACHE_NAME = KFSConstants.APPLICATION_NAMESPACE_CODE + "/" + "CustomerInvoiceDetail";
// private Integer invoiceItemNumber; using SourceAccountingLine.sequenceNumber
private BigDecimal invoiceItemQuantity;
private BigDecimal invoiceItemUnitPrice;
// private KualiDecimal invoiceItemTotalAmount; using SourceAccountingLine.amount for now
private Date invoiceItemServiceDate;
private String invoiceItemCode;
private String invoiceItemDescription;
private String accountsReceivableObjectCode;
private String accountsReceivableSubObjectCode;
private KualiDecimal invoiceItemTaxAmount = KualiDecimal.ZERO;;
private boolean taxableIndicator;
private boolean isDebit;
private Integer invoiceItemDiscountLineNumber;
private String invoiceItemUnitOfMeasureCode;
private UnitOfMeasure unitOfMeasure;
private SubObjectCode accountsReceivableSubObject;
private ObjectCode accountsReceivableObject;
private transient CustomerInvoiceDocument customerInvoiceDocument;
private transient CustomerInvoiceDetail parentDiscountCustomerInvoiceDetail;
private transient CustomerInvoiceDetail discountCustomerInvoiceDetail;
// fields used for CustomerInvoiceWriteoffDocument
private KualiDecimal writeoffAmount;
private String customerInvoiceWriteoffDocumentNumber;
// ---- BEGIN OPEN AMOUNTS
public KualiDecimal getAmountOpen() {
// if the parent isnt saved, or if its saved but not approved, we
// need to include the discounts. If its both saved AND approved,
// we do not include the discounts.
boolean includeDiscounts = !(isParentSaved() && isParentApproved());
KualiDecimal amount = getAmount();
KualiDecimal applied = getAmountApplied();
KualiDecimal a = amount.subtract(applied);
if (includeDiscounts) {
CustomerInvoiceDetail discount = getDiscountCustomerInvoiceDetail();
if (ObjectUtils.isNotNull(discount)) {
a = a.add(discount.getAmount());
}
}
return a;
}
private boolean isParentSaved() {
return getCustomerInvoiceDocument() != null;
}
private boolean isParentApproved() {
if (getCustomerInvoiceDocument() == null) {
return false;
}
return KFSConstants.DocumentStatusCodes.APPROVED.equalsIgnoreCase(getCustomerInvoiceDocument().getFinancialSystemDocumentHeader().getFinancialDocumentStatusCode());
}
//TODO Andrew
// @Deprecated
// private KualiDecimal getAmountOpenFromDatabaseNoDiscounts() {
// KualiDecimal amount = getAmount();
// KualiDecimal applied = getAmountAppliedFromDatabase();
// KualiDecimal a = amount.subtract(applied);
// return a;
// }
//
// @Deprecated
// private KualiDecimal getAmountOpenFromDatabaseDiscounted() {
// KualiDecimal amount = getAmount();
// KualiDecimal applied = getAmountAppliedFromDatabase();
// KualiDecimal a = amount.subtract(applied);
// CustomerInvoiceDetail discount = getDiscountCustomerInvoiceDetail();
// if (ObjectUtils.isNotNull(discount)) {
// a = a.add(discount.getAmount());
// }
// return a;
// }
//TODO Andrew
//public KualiDecimal getAmountOpenExcludingAnyAmountFromCurrentPaymentApplicationDocument() {
// return getAmountOpenExcludingAnyAmountFrom(getCurrentPaymentApplicationDocument());
//}
/**
*
* Retrieves the discounted amount. This is the amount minues any
* discounts that might exist. If no discount exists, then it
* just returns the amount.
*
* NOTE this does not subtract PaidApplieds, only discounts.
*
* @return
*/
//PAYAPP
public KualiDecimal getAmountDiscounted() {
KualiDecimal a = getAmount();
CustomerInvoiceDetail discount = getDiscountCustomerInvoiceDetail();
if(ObjectUtils.isNotNull(discount)) {
KualiDecimal d = discount.getAmount();
a = a.add(d);
}
return a;
}
//TODO Andrew
// public KualiDecimal getAmountOpenExcludingAnyAmountFrom(PaymentApplicationDocument paymentApplicationDocument) {
// return getAmountDiscounted().subtract(getAmountAppliedExcludingAnyAmountAppliedBy(paymentApplicationDocument));
// }
//
// public KualiDecimal getAmountOpenPerCurrentPaymentApplicationDocument() {
// return getAmountDiscounted().subtract(getAmountAppliedByCurrentPaymentApplicationDocument());
// }
/**
* This method returns the amount that remained unapplied on a given date.
*
* @param date
* @return
*/
public KualiDecimal getAmountOpenByDateFromDatabase(java.sql.Date date) {
return getAmountOpen();
//TODO Andrew - need to fix this to actually respect the dates
//return getAmountOpenByDateFromDatabaseExcludingAnyAmountAppliedByPaymentApplicationDocument(date, null);
}
public KualiDecimal getAmountOpenByDateFromDatabase(java.util.Date date) {
return getAmountOpen();
//TODO Andrew - need to fix this to actually respect the dates
//return getAmountOpenByDateFromDatabaseExcludingAnyAmountAppliedByPaymentApplicationDocument(new java.sql.Date(date.getTime()),null);
}
//TODO Andrew
// public KualiDecimal getAmountOpenByDateFromDatabaseExcludingAnyAmountAppliedByPaymentApplicationDocument(java.sql.Date date, PaymentApplicationDocument paymentApplicationDocument) {
// BusinessObjectService businessObjectService = SpringContext.getBean(BusinessObjectService.class);
//
// // Lookup all applied payments as of the given date
// Map<String,Object> criteria = new HashMap<String,Object>();
// criteria.put("invoiceItemNumber", getSequenceNumber());
// criteria.put("financialDocumentReferenceInvoiceNumber", getDocumentNumber());
// criteria.put("documentHeader.financialDocumentStatusCode", KFSConstants.DocumentStatusCodes.APPROVED);
// Collection<InvoicePaidApplied> invoicePaidAppliedsAsOfDate = businessObjectService.findMatching(InvoicePaidApplied.class, criteria);
//
// KualiDecimal totalAppliedAmount = new KualiDecimal(0);
// KualiDecimal appliedAmount = new KualiDecimal(0);
// for (InvoicePaidApplied invoicePaidApplied : invoicePaidAppliedsAsOfDate) {
// appliedAmount = invoicePaidApplied.getInvoiceItemAppliedAmount();
// Date invoicePaidDate = invoicePaidApplied.getDocumentHeader().getDocumentFinalDate();
// // get the paid date and use that to limit the adds from below
// if (ObjectUtils.isNotNull(appliedAmount)&&!invoicePaidDate.after(date)) {
// if(null != paymentApplicationDocument) {
// if(!invoicePaidApplied.getDocumentNumber().equals(paymentApplicationDocument.getDocumentNumber())) {
// totalAppliedAmount = totalAppliedAmount.add(appliedAmount);
// }
// } else {
// totalAppliedAmount = totalAppliedAmount.add(appliedAmount);
// }
// }
// }
//
// return getAmount().subtract(totalAppliedAmount);
// }
//
// public KualiDecimal getAmountOpenByDateFromDatabaseExcludingAnyAmountAppliedByPaymentApplicationDocument(java.util.Date date, PaymentApplicationDocument paymentApplicationDocument) {
// return getAmountOpenByDateFromDatabaseExcludingAnyAmountAppliedByPaymentApplicationDocument(new java.sql.Date(date.getTime()),paymentApplicationDocument);
// }
// ---- END OPEN AMOUNTS
// ---- BEGIN APPLIED AMOUNTS
public KualiDecimal getAmountApplied() {
List<InvoicePaidApplied> invoicePaidApplieds = null;
invoicePaidApplieds = getMatchingInvoicePaidAppliedsMatchingAnyDocumentFromDatabase();
KualiDecimal appliedAmount = new KualiDecimal(0);
for(InvoicePaidApplied invoicePaidApplied : invoicePaidApplieds) {
appliedAmount = appliedAmount.add(invoicePaidApplied.getInvoiceItemAppliedAmount());
}
return appliedAmount;
}
//TODO Andrew
// /**
// * @return the applied amount by getting it from the matching invoice paid applied
// */
// public KualiDecimal getAmountAppliedFromDatabase() {
// return getAmountAppliedBy(null);
// }
//
// /**
// * This method is a convenience method used from the Struts form on the payment application document screen.
// * @return
// */
// public KualiDecimal getAmountAppliedByCurrentPaymentApplicationDocument() {
// return getAmountAppliedBy(getCurrentPaymentApplicationDocument());
// }
//
/**
* @param paymentApplicationDocument
* @return
*/
public KualiDecimal getAmountAppliedBy(String documentNumber) {
List<InvoicePaidApplied> invoicePaidApplieds = null;
if (StringUtils.isBlank(documentNumber)) {
invoicePaidApplieds = getMatchingInvoicePaidAppliedsMatchingAnyDocumentFromDatabase();
} else {
invoicePaidApplieds = getMatchingInvoicePaidAppliedsMatchingDocument(documentNumber);
}
KualiDecimal appliedAmount = new KualiDecimal(0);
for(InvoicePaidApplied invoicePaidApplied : invoicePaidApplieds) {
appliedAmount = appliedAmount.add(invoicePaidApplied.getInvoiceItemAppliedAmount());
}
return appliedAmount;
}
/**
* @param paymentApplicationDocument
* @return the sum of applied amounts according to the database, excluding any amounts applied by paymentApplicationDocument
*/
public KualiDecimal getAmountAppliedExcludingAnyAmountAppliedBy(String documentNumber) {
List<InvoicePaidApplied> invoicePaidApplieds = getMatchingInvoicePaidAppliedsMatchingAnyDocumentFromDatabase();
KualiDecimal appliedAmount = new KualiDecimal(0);
for (InvoicePaidApplied invoicePaidApplied : invoicePaidApplieds) {
// Exclude any amounts applied by paymentApplicationDocument
if (StringUtils.isNotBlank(documentNumber)) {
}
if (StringUtils.isBlank(documentNumber) || !documentNumber.equalsIgnoreCase(invoicePaidApplied.getDocumentNumber())) {
appliedAmount = appliedAmount.add(invoicePaidApplied.getInvoiceItemAppliedAmount());
}
}
return appliedAmount;
}
// ---- END APPLIED AMOUNTS
/**
* This method returns the writeoff amount. If writeoff document hasn't been approved yet, display the open amount. Else display
* the amount applied from the specific approved writeoff document.
*
* @param customerInvoiceWriteoffDocumentNumber
* @return
*/
public KualiDecimal getWriteoffAmount() {
if (SpringContext.getBean(CustomerInvoiceWriteoffDocumentService.class).isCustomerInvoiceWriteoffDocumentApproved(customerInvoiceWriteoffDocumentNumber)) {
//TODO this probably isnt right ... in the case of discounts and/or credit
// memos, the getAmount() isnt the amount that the writeoff document will have
// written off
return super.getAmount(); // using the accounting line amount ... see comments at top of class
}
else {
return getAmountOpen();
}
}
/**
* This method returns the invoice pre tax amount
*
* @return
*/
public KualiDecimal getInvoiceItemPreTaxAmount() {
if (ObjectUtils.isNotNull(invoiceItemUnitPrice) && ObjectUtils.isNotNull(invoiceItemQuantity)) {
BigDecimal bd = invoiceItemUnitPrice.multiply(invoiceItemQuantity);
bd = bd.setScale(KualiDecimal.SCALE, KualiDecimal.ROUND_BEHAVIOR);
return new KualiDecimal(bd);
} else {
return KualiDecimal.ZERO;
}
}
/**
* Gets the accountsReceivableObjectCode attribute.
*
* @return Returns the accountsReceivableObjectCode
*/
public String getAccountsReceivableObjectCode() {
return accountsReceivableObjectCode;
}
/**
* Sets the accountsReceivableObjectCode attribute.
*
* @param accountsReceivableObjectCode The accountsReceivableObjectCode to set.
*/
@Override
public void setAccountsReceivableObjectCode(String accountsReceivableObjectCode) {
this.accountsReceivableObjectCode = accountsReceivableObjectCode;
}
/**
* Gets the accountsReceivableSubObjectCode attribute.
*
* @return Returns the accountsReceivableSubObjectCode
*/
public String getAccountsReceivableSubObjectCode() {
return accountsReceivableSubObjectCode;
}
/**
* Sets the accountsReceivableSubObjectCode attribute.
*
* @param accountsReceivableSubObjectCode The accountsReceivableSubObjectCode to set.
*/
public void setAccountsReceivableSubObjectCode(String accountsReceivableSubObjectCode) {
this.accountsReceivableSubObjectCode = accountsReceivableSubObjectCode;
}
/**
* Gets the invoiceItemQuantity attribute.
*
* @return Returns the invoiceItemQuantity
*/
public BigDecimal getInvoiceItemQuantity() {
return invoiceItemQuantity;
}
/**
* Sets the invoiceItemQuantity attribute.
*
* @param invoiceItemQuantity The invoiceItemQuantity to set.
*/
@Override
public void setInvoiceItemQuantity(BigDecimal invoiceItemQuantity) {
this.invoiceItemQuantity = invoiceItemQuantity;
}
/**
* Gets the invoiceItemUnitOfMeasureCode attribute.
*
* @return Returns the invoiceItemUnitOfMeasureCode
*/
public String getInvoiceItemUnitOfMeasureCode() {
return invoiceItemUnitOfMeasureCode;
}
/**
* Sets the invoiceItemUnitOfMeasureCode attribute.
*
* @param invoiceItemUnitOfMeasureCode The invoiceItemUnitOfMeasureCode to set.
*/
public void setInvoiceItemUnitOfMeasureCode(String invoiceItemUnitOfMeasureCode) {
this.invoiceItemUnitOfMeasureCode = invoiceItemUnitOfMeasureCode;
}
/**
* Gets the invoiceItemUnitPrice attribute.
*
* @return Returns the invoiceItemUnitPrice
*/
public BigDecimal getInvoiceItemUnitPrice() {
return invoiceItemUnitPrice;
}
/**
* @param invoiceItemUnitPrice
*/
@Override
public void setInvoiceItemUnitPrice(KualiDecimal invoiceItemUnitPrice) {
if (ObjectUtils.isNotNull(invoiceItemUnitPrice)) {
this.invoiceItemUnitPrice = invoiceItemUnitPrice.bigDecimalValue();
}
else {
this.invoiceItemUnitPrice = BigDecimal.ZERO;
}
}
/**
* Sets the invoiceItemUnitPrice attribute.
*
* @param invoiceItemUnitPrice The invoiceItemUnitPrice to set.
*/
public void setInvoiceItemUnitPrice(BigDecimal invoiceItemUnitPrice) {
this.invoiceItemUnitPrice = invoiceItemUnitPrice;
}
/**
* Gets the invoiceItemServiceDate attribute.
*
* @return Returns the invoiceItemServiceDate
*/
public Date getInvoiceItemServiceDate() {
return invoiceItemServiceDate;
}
/**
* Sets the invoiceItemServiceDate attribute.
*
* @param invoiceItemServiceDate The invoiceItemServiceDate to set.
*/
public void setInvoiceItemServiceDate(Date invoiceItemServiceDate) {
this.invoiceItemServiceDate = invoiceItemServiceDate;
}
/**
* Gets the invoiceItemCode attribute.
*
* @return Returns the invoiceItemCode
*/
public String getInvoiceItemCode() {
return invoiceItemCode;
}
/**
* Sets the invoiceItemCode attribute.
*
* @param invoiceItemCode The invoiceItemCode to set.
*/
public void setInvoiceItemCode(String invoiceItemCode) {
this.invoiceItemCode = invoiceItemCode;
}
/**
* Gets the invoiceItemDescription attribute.
*
* @return Returns the invoiceItemDescription
*/
public String getInvoiceItemDescription() {
return invoiceItemDescription;
}
/**
* Sets the invoiceItemDescription attribute.
*
* @param invoiceItemDescription The invoiceItemDescription to set.
*/
public void setInvoiceItemDescription(String invoiceItemDescription) {
this.invoiceItemDescription = invoiceItemDescription;
}
/**
* Gets the invoiceItemTaxAmount attribute. TODO Use tax service to get invoice item tax amount
*
* @return Returns the invoiceItemTaxAmount.
*/
public KualiDecimal getInvoiceItemTaxAmount() {
return invoiceItemTaxAmount;
}
/**
* Sets the invoiceItemTaxAmount attribute value.
*
* @param invoiceItemTaxAmount The invoiceItemTaxAmount to set.
*/
public void setInvoiceItemTaxAmount(KualiDecimal invoiceItemTaxAmount) {
this.invoiceItemTaxAmount = invoiceItemTaxAmount;
}
/**
* Gets the invoiceItemDiscountLineNumber attribute.
*
* @return Returns the invoiceItemDiscountLineNumber.
*/
public Integer getInvoiceItemDiscountLineNumber() {
return invoiceItemDiscountLineNumber;
}
/**
* Sets the invoiceItemDiscountLineNumber attribute value.
*
* @param invoiceItemDiscountLineNumber The invoiceItemDiscountLineNumber to set.
*/
public void setInvoiceItemDiscountLineNumber(Integer invoiceItemDiscountLineNumber) {
this.invoiceItemDiscountLineNumber = invoiceItemDiscountLineNumber;
}
/**
* Gets the accountsReceivableSubObject attribute.
*
* @return Returns the accountsReceivableSubObject
*/
public SubObjectCode getAccountsReceivableSubObject() {
return accountsReceivableSubObject;
}
/**
* Sets the accountsReceivableSubObject attribute.
*
* @param accountsReceivableSubObject The accountsReceivableSubObject to set.
* @deprecated
*/
@Deprecated
public void setAccountsReceivableSubObject(SubObjectCode accountsReceivableSubObject) {
this.accountsReceivableSubObject = accountsReceivableSubObject;
}
/**
* Gets the accountsReceivableObject attribute.
*
* @return Returns the accountsReceivableObject
*/
public ObjectCode getAccountsReceivableObject() {
return accountsReceivableObject;
}
/**
* Sets the accountsReceivableObject attribute.
*
* @param accountsReceivableObject The accountsReceivableObject to set.
* @deprecated
*/
@Deprecated
public void setAccountsReceivableObject(ObjectCode accountsReceivableObject) {
this.accountsReceivableObject = accountsReceivableObject;
}
/**
* @see org.kuali.rice.krad.bo.BusinessObjectBase#toStringMapper()
*/
@Override
@SuppressWarnings("unchecked")
protected LinkedHashMap toStringMapper_RICE20_REFACTORME() {
LinkedHashMap m = new LinkedHashMap();
m.put("documentNumber", getDocumentNumber());
if (this.getSequenceNumber() != null) {
m.put("invoiceItemNumber", this.getSequenceNumber().toString());
}
return m;
}
/**
* Update line amount based on quantity and unit price
*/
@Override
public void updateAmountBasedOnQuantityAndUnitPrice() {
setAmount(getInvoiceItemPreTaxAmount());
}
public boolean isTaxableIndicator() {
return taxableIndicator;
}
// yes this is redundant, its required for the JSP on the accounting
// line checkbox field
public boolean getTaxableIndicator() {
return taxableIndicator;
}
public void setTaxableIndicator(boolean taxableIndicator) {
this.taxableIndicator = taxableIndicator;
}
public boolean isDebit() {
return isDebit;
}
public void setDebit(boolean isDebit) {
this.isDebit = isDebit;
}
/**
* This method returns true if customer invoice detail has a corresponding discount line
*
* @return
*/
public boolean isDiscountLineParent() {
return ObjectUtils.isNotNull(getInvoiceItemDiscountLineNumber());
}
/**
* This method should only be used to determine if detail is discount line in JSP. If you want to determine if invoice detail is
* a detail line use CustomerInvoiceDocument.isDiscountLineBasedOnSequenceNumber() instead.
*
* @return
*/
public boolean isDiscountLine() {
return ObjectUtils.isNotNull(parentDiscountCustomerInvoiceDetail);
}
/**
* This method sets the amount to negative if it isn't already negative
*
* @return
*/
public void setInvoiceItemUnitPriceToNegative() {
// if unit price is positive
if (invoiceItemUnitPrice.compareTo(BigDecimal.ZERO) == 1) {
invoiceItemUnitPrice = invoiceItemUnitPrice.negate();
}
}
public CustomerInvoiceDetail getParentDiscountCustomerInvoiceDetail() {
return parentDiscountCustomerInvoiceDetail;
}
public void setParentDiscountCustomerInvoiceDetail(CustomerInvoiceDetail parentDiscountCustomerInvoiceDetail) {
this.parentDiscountCustomerInvoiceDetail = parentDiscountCustomerInvoiceDetail;
}
public CustomerInvoiceDetail getDiscountCustomerInvoiceDetail() {
return discountCustomerInvoiceDetail;
}
public void setDiscountCustomerInvoiceDetail(CustomerInvoiceDetail discountCustomerInvoiceDetail) {
this.discountCustomerInvoiceDetail = discountCustomerInvoiceDetail;
}
// ---- Methods to find matching InvoicePaidApplieds.
/**
* @return matching InvoicePaidApplieds from the database if they exist
*/
public List<InvoicePaidApplied> getMatchingInvoicePaidAppliedsMatchingAnyDocumentFromDatabase() {
//TODO Andrew
//return getMatchingInvoicePaidApplieds(null);
BusinessObjectService businessObjectService = SpringContext.getBean(BusinessObjectService.class);
// assuming here that you never have a PaidApplied against a Discount line
Map<String,Object> criteria = new HashMap<String,Object>();
criteria.put("invoiceItemNumber", getInvoiceItemNumber());
criteria.put("financialDocumentReferenceInvoiceNumber", getDocumentNumber());
criteria.put("documentHeader.financialDocumentStatusCode", KFSConstants.DocumentStatusCodes.APPROVED);
List<InvoicePaidApplied> invoicePaidApplieds = (List<InvoicePaidApplied>) businessObjectService.findMatching(InvoicePaidApplied.class, criteria);
if(ObjectUtils.isNull(invoicePaidApplieds)) {
invoicePaidApplieds = new ArrayList<InvoicePaidApplied>();
}
return invoicePaidApplieds;
}
/**
* @param paymentApplicationDocumentNumber
* @return the List of matching InvoicePaidApplieds.
* If paymentApplicationDocumentNumber is null invoicePaidApplieds matching any PaymentApplicationDocument will be returned.
* If paymentApplicationDocumentNumber is not null only the invoicePaidApplieds that match on that PaymentApplicationDocument will be returned.
*/
private List<InvoicePaidApplied> getMatchingInvoicePaidAppliedsMatchingDocument(String documentNumber) {
if (StringUtils.isBlank(documentNumber)) {
return getMatchingInvoicePaidAppliedsMatchingAnyDocumentFromDatabase();
}
BusinessObjectService businessObjectService = SpringContext.getBean(BusinessObjectService.class);
Map<String,Object> criteria = new HashMap<String,Object>();
criteria.put("documentNumber", documentNumber);
criteria.put("invoiceItemNumber", getSequenceNumber());
criteria.put("financialDocumentReferenceInvoiceNumber", getDocumentNumber());
List<InvoicePaidApplied> invoicePaidApplieds = (List<InvoicePaidApplied>) businessObjectService.findMatching(InvoicePaidApplied.class, criteria);
if(ObjectUtils.isNull(invoicePaidApplieds)) {
invoicePaidApplieds = new ArrayList<InvoicePaidApplied>();
}
return invoicePaidApplieds;
}
//TODO Andrew
// /**
// * @param paymentApplicationDocumentNumber
// * @return matching InvoicePaidApplieds from the database matching the specific PaymentApplicationDocument if they exist
// */
// public List<InvoicePaidApplied> getMatchingInvoicePaidAppliedsMatchingASpecificPaymentApplicationDocumentFromDatabase(String paymentApplicationDocumentNumber) {
// return getMatchingInvoicePaidApplieds(paymentApplicationDocumentNumber);
// }
//
// /**
// * @param paymentApplicationDocumentNumber
// * @return
// */
// public InvoicePaidApplied getSingleMatchingInvoicePaidAppliedMatchingASpecificPaymentApplicationDocumentFromDatabase(String paymentApplicationDocumentNumber) {
// List<InvoicePaidApplied> matchingInvoicePaidApplieds = getMatchingInvoicePaidApplieds(paymentApplicationDocumentNumber);
// return matchingInvoicePaidApplieds.iterator().next();
// }
//
//
// /**
// * Get InvoicePaidApplieds related to this CustomerInvoiceDetail if they
// * exist in a PaymentApplicationDocument and do it just by looking at the
// * PaymentApplicationDocument as it is in memory. Don't get anything from
// * the database.
// *
// * @param paymentApplicationDocument
// * @return
// */
// public List<InvoicePaidApplied> getMatchingInvoicePaidAppliedsMatchingPaymentApplicationDocumentNoDatabase(PaymentApplicationDocument paymentApplicationDocument) {
// List<InvoicePaidApplied> invoicePaidApplieds = paymentApplicationDocument.getInvoicePaidApplieds();
// List<InvoicePaidApplied> selectedInvoicePaidApplieds = new ArrayList<InvoicePaidApplied>();
// // The paymentApplicationDocumentService isn't used to pull anything from the database.
// // It's just used to try to pair CustomerInvoiceDetails and InvoicePaidApplieds
// PaymentApplicationDocumentService paymentApplicationDocumentService = SpringContext.getBean(PaymentApplicationDocumentService.class);
// for(InvoicePaidApplied invoicePaidApplied : invoicePaidApplieds) {
// if(paymentApplicationDocumentService.customerInvoiceDetailPairsWithInvoicePaidApplied(this, invoicePaidApplied)) {
// selectedInvoicePaidApplieds.add(invoicePaidApplied);
// }
// }
// return selectedInvoicePaidApplieds;
// }
//
// /**
// * This method returns the results of @link getMatchingInvoicePaidAppliedsMatchingPaymentApplicationDocumentNoDatabase(PaymentApplicationDocument)
// * as a single InvoicePaidApplied. This is OK because there's only one
// * InvoicePaidApplied for a CustomerInvoiceDetail on a given PaymentApplicationDocument.
// *
// * @param paymentApplicationDocument
// * @return
// */
// public InvoicePaidApplied getSingleMatchingInvoicepaidAppliedMatchingPaymentApplicationDocumentNoDatabase(PaymentApplicationDocument paymentApplicationDocument) {
// List<InvoicePaidApplied> matchingInvoicePaidApplieds = getMatchingInvoicePaidAppliedsMatchingPaymentApplicationDocumentNoDatabase(paymentApplicationDocument);
// return matchingInvoicePaidApplieds.iterator().next();
// }
// ---- Simple getters/setters
public CustomerInvoiceDocument getCustomerInvoiceDocument() {
if (customerInvoiceDocument == null) {
DocumentService documentService = SpringContext.getBean(DocumentService.class);
try {
customerInvoiceDocument = (CustomerInvoiceDocument) documentService.getByDocumentHeaderId(getDocumentNumber());
}
catch (WorkflowException e) {
throw new RuntimeException("A WorkflowException was thrown when trying to open the details parent document. This should never happen.", e);
}
}
return customerInvoiceDocument;
}
public void setCustomerInvoiceDocument(CustomerInvoiceDocument customerInvoiceDocument) {
this.customerInvoiceDocument = customerInvoiceDocument;
}
public String getCustomerInvoiceWriteoffDocumentNumber() {
return customerInvoiceWriteoffDocumentNumber;
}
public void setCustomerInvoiceWriteoffDocumentNumber(String customerInvoiceWriteoffDocumentNumber) {
this.customerInvoiceWriteoffDocumentNumber = customerInvoiceWriteoffDocumentNumber;
}
public void setWriteoffAmount(KualiDecimal writeoffAmount) {
this.writeoffAmount = writeoffAmount;
}
public UnitOfMeasure getUnitOfMeasure() {
return unitOfMeasure;
}
public void setUnitOfMeasure(UnitOfMeasure unitOfMeasure) {
this.unitOfMeasure = unitOfMeasure;
}
//TODO Andrew
// public boolean isFullApply() {
// return fullApply;
// }
//
// public void setFullApply(boolean fullApply) {
// this.fullApply = fullApply;
// }
/**
* If the detail is a discount customer invoice detail, return the parent customer invoice detail's sequence number instead
*
* @see org.kuali.kfs.module.ar.businessobject.AppliedPayment#getInvoiceItemNumber()
*/
@Override
public Integer getInvoiceItemNumber() {
if (isDiscountLine()) {
return parentDiscountCustomerInvoiceDetail.getSequenceNumber();
} else {
return this.getSequenceNumber();
}
}
/**
* If detail is part of an invoice that is a reversal, return the invoice that is being corrected. Else return the customer
* details document number.
*
* @see org.kuali.kfs.module.ar.businessobject.AppliedPayment#getInvoiceReferenceNumber()
*/
@Override
public String getInvoiceReferenceNumber() {
return getDocumentNumber();
}
/**
*
* @see org.kuali.rice.krad.bo.PersistableBusinessObjectBase#refresh()
*/
@Override
public void refresh() {
super.refresh();
this.updateAmountBasedOnQuantityAndUnitPrice();
}
@Override
public void refreshNonUpdateableReferences() {
super.refreshNonUpdateableReferences();
}
@Override
public void setDocumentNumber(String documentNumber) {
super.setDocumentNumber(documentNumber);
}
}