/* * 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.purap.businessobject; import java.math.BigDecimal; import java.util.HashMap; import java.util.Iterator; import java.util.List; import org.kuali.kfs.module.purap.PurapPropertyConstants; import org.kuali.kfs.module.purap.document.PaymentRequestDocument; import org.kuali.kfs.module.purap.document.PurchaseOrderDocument; import org.kuali.kfs.module.purap.document.VendorCreditMemoDocument; import org.kuali.kfs.module.purap.document.service.AccountsPayableService; import org.kuali.kfs.module.purap.document.service.PaymentRequestService; import org.kuali.kfs.module.purap.document.service.PurapService; import org.kuali.kfs.module.purap.document.service.PurchaseOrderService; import org.kuali.kfs.module.purap.exception.PurError; import org.kuali.kfs.module.purap.util.ExpiredOrClosedAccountEntry; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.rice.core.api.util.type.KualiDecimal; import org.kuali.rice.krad.util.ObjectUtils; /** * Item line Business Object for Credit Memo Document. */ public class CreditMemoItem extends AccountsPayableItemBase { private KualiDecimal poInvoicedTotalQuantity; private BigDecimal poUnitPrice; private KualiDecimal poTotalAmount; private KualiDecimal preqInvoicedTotalQuantity; private BigDecimal preqUnitPrice; private KualiDecimal preqTotalAmount; /** * Default constructor. */ public CreditMemoItem() { } /** * Constructs a CreditMemoItem object from an existing Purchase Order Item. - Delegate * * @param cmDocument the Credit Memo Document this item belongs to. * @param poItem the Purchase Order Item to copy from. */ public CreditMemoItem(VendorCreditMemoDocument cmDocument, PurchaseOrderItem poItem) { this(cmDocument, poItem, new HashMap<String, ExpiredOrClosedAccountEntry>()); } /** * Constructs a CreditMemoItem object from an existing Purchase Order Item, and check and process expired or closed accounts * item might contain. * * @param cmDocument the Credit Memo Document this item belongs to. * @param poItem the Purchase Order Item to copy from. * @param expiredOrClosedAccountList the list of expired or closed accounts to check against. */ public CreditMemoItem(VendorCreditMemoDocument cmDocument, PurchaseOrderItem poItem, HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountList) { super(); setPurapDocumentIdentifier(cmDocument.getPurapDocumentIdentifier()); setPurapDocument(cmDocument); setItemLineNumber(poItem.getItemLineNumber()); setPoInvoicedTotalQuantity(poItem.getItemInvoicedTotalQuantity()); setPoUnitPrice(poItem.getItemUnitPrice()); setPoTotalAmount(poItem.getItemInvoicedTotalAmount()); setItemTypeCode(poItem.getItemTypeCode()); //recalculate tax SpringContext.getBean(PurapService.class).calculateTax(cmDocument); if ((ObjectUtils.isNotNull(this.getItemType()) && this.getItemType().isAmountBasedGeneralLedgerIndicator())) { // setting unit price to be null to be more consistent with other below the line this.setItemUnitPrice(null); } else { setItemUnitPrice(poItem.getItemUnitPrice()); } setItemCatalogNumber(poItem.getItemCatalogNumber()); setItemDescription(poItem.getItemDescription()); if (getPoInvoicedTotalQuantity() == null) { setPoInvoicedTotalQuantity(KualiDecimal.ZERO); } if (getPoUnitPrice() == null) { setPoUnitPrice(BigDecimal.ZERO); } if (getPoTotalAmount() == null) { setPoTotalAmount(KualiDecimal.ZERO); } for (Iterator iter = poItem.getSourceAccountingLines().iterator(); iter.hasNext();) { PurchaseOrderAccount account = (PurchaseOrderAccount) iter.next(); // check if this account is expired/closed and replace as needed SpringContext.getBean(AccountsPayableService.class).processExpiredOrClosedAccount(account, expiredOrClosedAccountList); getSourceAccountingLines().add(new CreditMemoAccount(account)); } } /** * Constructs a CreditMemoItem object from an existing Payment Request Item, and check and process expired or closed accounts * item might contain. * * @param cmDocument the Credit Memo Document this item belongs to. * @param preqItem the Payment Request Item to copy from. * @param poItem the Purchase Order Item to copy from. * @param expiredOrClosedAccountList the list of expired or closed accounts to check against. */ public CreditMemoItem(VendorCreditMemoDocument cmDocument, PaymentRequestItem preqItem, PurchaseOrderItem poItem, HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountList) { super(); setPurapDocumentIdentifier(cmDocument.getPurapDocumentIdentifier()); setItemLineNumber(preqItem.getItemLineNumber()); this.setPurapDocument(cmDocument); // take invoiced quantities from the lower of the preq and po if different if (poItem.getItemInvoicedTotalQuantity() != null && preqItem.getItemQuantity() != null && poItem.getItemInvoicedTotalQuantity().isLessThan(preqItem.getItemQuantity())) { setPreqInvoicedTotalQuantity(poItem.getItemInvoicedTotalQuantity()); setPreqTotalAmount(poItem.getItemInvoicedTotalAmount()); } else { setPreqInvoicedTotalQuantity(preqItem.getItemQuantity()); setPreqTotalAmount(preqItem.getTotalAmount()); } setPreqUnitPrice(preqItem.getItemUnitPrice()); setItemTypeCode(preqItem.getItemTypeCode()); if ((ObjectUtils.isNotNull(this.getItemType()) && this.getItemType().isAmountBasedGeneralLedgerIndicator())) { // setting unit price to be null to be more consistent with other below the line this.setItemUnitPrice(null); } else { setItemUnitPrice(preqItem.getItemUnitPrice()); } setItemCatalogNumber(preqItem.getItemCatalogNumber()); setItemDescription(preqItem.getItemDescription()); setCapitalAssetTransactionTypeCode(preqItem.getCapitalAssetTransactionTypeCode()); if (getPreqInvoicedTotalQuantity() == null) { setPreqInvoicedTotalQuantity(KualiDecimal.ZERO); } if (getPreqUnitPrice() == null) { setPreqUnitPrice(BigDecimal.ZERO); } if (getPreqTotalAmount() == null) { setPreqTotalAmount(KualiDecimal.ZERO); } for (Iterator iter = preqItem.getSourceAccountingLines().iterator(); iter.hasNext();) { PaymentRequestAccount account = (PaymentRequestAccount) iter.next(); // check if this account is expired/closed and replace as needed SpringContext.getBean(AccountsPayableService.class).processExpiredOrClosedAccount(account, expiredOrClosedAccountList); getSourceAccountingLines().add(new CreditMemoAccount(account)); } } /** * @see org.kuali.kfs.module.purap.businessobject.PurApItemBase#getAccountingLineClass() */ @Override public Class<CreditMemoAccount> getAccountingLineClass() { return CreditMemoAccount.class; } public KualiDecimal getPoTotalAmount() { return poTotalAmount; } public void setPoTotalAmount(KualiDecimal poTotalAmount) { this.poTotalAmount = poTotalAmount; } public KualiDecimal getPoInvoicedTotalQuantity() { return poInvoicedTotalQuantity; } public void setPoInvoicedTotalQuantity(KualiDecimal poInvoicedTotalQuantity) { this.poInvoicedTotalQuantity = poInvoicedTotalQuantity; } public BigDecimal getPoUnitPrice() { return poUnitPrice; } public void setPoUnitPrice(BigDecimal poUnitPrice) { this.poUnitPrice = poUnitPrice; } public KualiDecimal getPreqTotalAmount() { return preqTotalAmount; } public void setPreqTotalAmount(KualiDecimal preqTotalAmount) { this.preqTotalAmount = preqTotalAmount; } public KualiDecimal getPreqInvoicedTotalQuantity() { return preqInvoicedTotalQuantity; } public void setPreqInvoicedTotalQuantity(KualiDecimal preqInvoicedTotalQuantity) { this.preqInvoicedTotalQuantity = preqInvoicedTotalQuantity; } public BigDecimal getPreqUnitPrice() { return preqUnitPrice; } public void setPreqUnitPrice(BigDecimal preqUnitPrice) { this.preqUnitPrice = preqUnitPrice; } @Override public Class getUseTaxClass() { return CreditMemoItemUseTax.class; } public PurchaseOrderItem getPurchaseOrderItem(){ PurchaseOrderItem poi = null; //refresh vendor document if (ObjectUtils.isNotNull(this.getPurapDocumentIdentifier())) { if (ObjectUtils.isNull(this.getVendorCreditMemo())) { this.refreshReferenceObject(PurapPropertyConstants.PURAP_DOC); } } //if vendor document not null, then attempt to pull PO off of it if (ObjectUtils.isNotNull(getVendorCreditMemo())) { PurchaseOrderDocument purchaseOrderDocument = null; Integer purchaseOrderDocumentId = getVendorCreditMemo().getPurchaseOrderIdentifier(); if (getVendorCreditMemo().isSourceDocumentPaymentRequest() && ObjectUtils.isNull(purchaseOrderDocumentId)) { PaymentRequestDocument paymentRequestDocument = SpringContext.getBean(PaymentRequestService.class).getPaymentRequestById(getVendorCreditMemo().getPaymentRequestIdentifier()); purchaseOrderDocumentId = paymentRequestDocument.getPurchaseOrderIdentifier(); } // if we found a valid po id number then check it for reopening if (ObjectUtils.isNotNull(purchaseOrderDocumentId)) { purchaseOrderDocument = SpringContext.getBean(PurchaseOrderService.class).getCurrentPurchaseOrder(purchaseOrderDocumentId); } //if we have a PO document, get po item if(ObjectUtils.isNotNull(purchaseOrderDocument)){ if (this.getItemType().isLineItemIndicator()) { List<PurchaseOrderItem> items = purchaseOrderDocument.getItems(); poi = items.get(this.getItemLineNumber().intValue() - 1); } else { poi = (PurchaseOrderItem) SpringContext.getBean(PurapService.class).getBelowTheLineByType(purchaseOrderDocument, this.getItemType()); } } } else { throw new PurError("Credit Memo Object in Purchase Order item line number " + getItemLineNumber() + "or itemType " + getItemTypeCode() + " is null"); } return poi; } public VendorCreditMemoDocument getVendorCreditMemo() { return super.getPurapDocument(); } }