001 /* 002 * Copyright 2011 The Kuali Foundation. 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package org.kuali.kfs.module.purap.businessobject; 018 019 import java.math.BigDecimal; 020 import java.util.HashMap; 021 import java.util.Iterator; 022 023 import org.kuali.kfs.module.purap.PurapPropertyConstants; 024 import org.kuali.kfs.module.purap.document.PaymentRequestDocument; 025 import org.kuali.kfs.module.purap.document.PurchaseOrderDocument; 026 import org.kuali.kfs.module.purap.document.VendorCreditMemoDocument; 027 import org.kuali.kfs.module.purap.document.service.AccountsPayableService; 028 import org.kuali.kfs.module.purap.document.service.PaymentRequestService; 029 import org.kuali.kfs.module.purap.document.service.PurapService; 030 import org.kuali.kfs.module.purap.document.service.PurchaseOrderService; 031 import org.kuali.kfs.module.purap.exception.PurError; 032 import org.kuali.kfs.module.purap.util.ExpiredOrClosedAccountEntry; 033 import org.kuali.kfs.sys.context.SpringContext; 034 import org.kuali.rice.kns.util.KualiDecimal; 035 import org.kuali.rice.kns.util.ObjectUtils; 036 037 /** 038 * Item line Business Object for Credit Memo Document. 039 */ 040 public class CreditMemoItem extends AccountsPayableItemBase { 041 private KualiDecimal poInvoicedTotalQuantity; 042 private BigDecimal poUnitPrice; 043 private KualiDecimal poTotalAmount; 044 private KualiDecimal preqInvoicedTotalQuantity; 045 private BigDecimal preqUnitPrice; 046 private KualiDecimal preqTotalAmount; 047 048 /** 049 * Default constructor. 050 */ 051 public CreditMemoItem() { 052 } 053 054 /** 055 * Constructs a CreditMemoItem object from an existing Purchase Order Item. - Delegate 056 * 057 * @param cmDocument the Credit Memo Document this item belongs to. 058 * @param poItem the Purchase Order Item to copy from. 059 */ 060 public CreditMemoItem(VendorCreditMemoDocument cmDocument, PurchaseOrderItem poItem) { 061 this(cmDocument, poItem, new HashMap<String, ExpiredOrClosedAccountEntry>()); 062 } 063 064 /** 065 * Constructs a CreditMemoItem object from an existing Purchase Order Item, and check and process expired or closed accounts 066 * item might contain. 067 * 068 * @param cmDocument the Credit Memo Document this item belongs to. 069 * @param poItem the Purchase Order Item to copy from. 070 * @param expiredOrClosedAccountList the list of expired or closed accounts to check against. 071 */ 072 public CreditMemoItem(VendorCreditMemoDocument cmDocument, PurchaseOrderItem poItem, HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountList) { 073 super(); 074 075 setPurapDocumentIdentifier(cmDocument.getPurapDocumentIdentifier()); 076 setPurapDocument(cmDocument); 077 setItemLineNumber(poItem.getItemLineNumber()); 078 setPoInvoicedTotalQuantity(poItem.getItemInvoicedTotalQuantity()); 079 setPoUnitPrice(poItem.getItemUnitPrice()); 080 setPoTotalAmount(poItem.getItemInvoicedTotalAmount()); 081 setItemTypeCode(poItem.getItemTypeCode()); 082 083 //recalculate tax 084 SpringContext.getBean(PurapService.class).calculateTax(cmDocument); 085 086 if ((ObjectUtils.isNotNull(this.getItemType()) && this.getItemType().isAmountBasedGeneralLedgerIndicator())) { 087 // setting unit price to be null to be more consistent with other below the line 088 this.setItemUnitPrice(null); 089 } 090 else { 091 setItemUnitPrice(poItem.getItemUnitPrice()); 092 } 093 094 setItemCatalogNumber(poItem.getItemCatalogNumber()); 095 096 setItemDescription(poItem.getItemDescription()); 097 098 if (getPoInvoicedTotalQuantity() == null) { 099 setPoInvoicedTotalQuantity(KualiDecimal.ZERO); 100 } 101 if (getPoUnitPrice() == null) { 102 setPoUnitPrice(BigDecimal.ZERO); 103 } 104 if (getPoTotalAmount() == null) { 105 setPoTotalAmount(KualiDecimal.ZERO); 106 } 107 108 for (Iterator iter = poItem.getSourceAccountingLines().iterator(); iter.hasNext();) { 109 PurchaseOrderAccount account = (PurchaseOrderAccount) iter.next(); 110 111 // check if this account is expired/closed and replace as needed 112 SpringContext.getBean(AccountsPayableService.class).processExpiredOrClosedAccount(account, expiredOrClosedAccountList); 113 114 getSourceAccountingLines().add(new CreditMemoAccount(account)); 115 } 116 } 117 118 /** 119 * Constructs a CreditMemoItem object from an existing Payment Request Item, and check and process expired or closed accounts 120 * item might contain. 121 * 122 * @param cmDocument the Credit Memo Document this item belongs to. 123 * @param preqItem the Payment Request Item to copy from. 124 * @param poItem the Purchase Order Item to copy from. 125 * @param expiredOrClosedAccountList the list of expired or closed accounts to check against. 126 */ 127 public CreditMemoItem(VendorCreditMemoDocument cmDocument, PaymentRequestItem preqItem, PurchaseOrderItem poItem, HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountList) { 128 super(); 129 130 setPurapDocumentIdentifier(cmDocument.getPurapDocumentIdentifier()); 131 setItemLineNumber(preqItem.getItemLineNumber()); 132 this.setPurapDocument(cmDocument); 133 134 // take invoiced quantities from the lower of the preq and po if different 135 if (poItem.getItemInvoicedTotalQuantity() != null && preqItem.getItemQuantity() != null && poItem.getItemInvoicedTotalQuantity().isLessThan(preqItem.getItemQuantity())) { 136 setPreqInvoicedTotalQuantity(poItem.getItemInvoicedTotalQuantity()); 137 setPreqTotalAmount(poItem.getItemInvoicedTotalAmount()); 138 } 139 else { 140 setPreqInvoicedTotalQuantity(preqItem.getItemQuantity()); 141 setPreqTotalAmount(preqItem.getTotalAmount()); 142 } 143 144 setPreqUnitPrice(preqItem.getItemUnitPrice()); 145 setItemTypeCode(preqItem.getItemTypeCode()); 146 147 if ((ObjectUtils.isNotNull(this.getItemType()) && this.getItemType().isAmountBasedGeneralLedgerIndicator())) { 148 // setting unit price to be null to be more consistent with other below the line 149 this.setItemUnitPrice(null); 150 } 151 else { 152 setItemUnitPrice(preqItem.getItemUnitPrice()); 153 } 154 155 setItemCatalogNumber(preqItem.getItemCatalogNumber()); 156 setItemDescription(preqItem.getItemDescription()); 157 158 setCapitalAssetTransactionTypeCode(preqItem.getCapitalAssetTransactionTypeCode()); 159 160 if (getPreqInvoicedTotalQuantity() == null) { 161 setPreqInvoicedTotalQuantity(KualiDecimal.ZERO); 162 } 163 if (getPreqUnitPrice() == null) { 164 setPreqUnitPrice(BigDecimal.ZERO); 165 } 166 if (getPreqTotalAmount() == null) { 167 setPreqTotalAmount(KualiDecimal.ZERO); 168 } 169 170 for (Iterator iter = preqItem.getSourceAccountingLines().iterator(); iter.hasNext();) { 171 PaymentRequestAccount account = (PaymentRequestAccount) iter.next(); 172 173 // check if this account is expired/closed and replace as needed 174 SpringContext.getBean(AccountsPayableService.class).processExpiredOrClosedAccount(account, expiredOrClosedAccountList); 175 176 getSourceAccountingLines().add(new CreditMemoAccount(account)); 177 } 178 } 179 180 /** 181 * @see org.kuali.kfs.module.purap.businessobject.PurApItemBase#getAccountingLineClass() 182 */ 183 @Override 184 public Class<CreditMemoAccount> getAccountingLineClass() { 185 return CreditMemoAccount.class; 186 } 187 188 public KualiDecimal getPoTotalAmount() { 189 return poTotalAmount; 190 } 191 192 public void setPoTotalAmount(KualiDecimal poTotalAmount) { 193 this.poTotalAmount = poTotalAmount; 194 } 195 196 public KualiDecimal getPoInvoicedTotalQuantity() { 197 return poInvoicedTotalQuantity; 198 } 199 200 public void setPoInvoicedTotalQuantity(KualiDecimal poInvoicedTotalQuantity) { 201 this.poInvoicedTotalQuantity = poInvoicedTotalQuantity; 202 } 203 204 public BigDecimal getPoUnitPrice() { 205 return poUnitPrice; 206 } 207 208 public void setPoUnitPrice(BigDecimal poUnitPrice) { 209 this.poUnitPrice = poUnitPrice; 210 } 211 212 public KualiDecimal getPreqTotalAmount() { 213 return preqTotalAmount; 214 } 215 216 public void setPreqTotalAmount(KualiDecimal preqTotalAmount) { 217 this.preqTotalAmount = preqTotalAmount; 218 } 219 220 public KualiDecimal getPreqInvoicedTotalQuantity() { 221 return preqInvoicedTotalQuantity; 222 } 223 224 public void setPreqInvoicedTotalQuantity(KualiDecimal preqInvoicedTotalQuantity) { 225 this.preqInvoicedTotalQuantity = preqInvoicedTotalQuantity; 226 } 227 228 public BigDecimal getPreqUnitPrice() { 229 return preqUnitPrice; 230 } 231 232 public void setPreqUnitPrice(BigDecimal preqUnitPrice) { 233 this.preqUnitPrice = preqUnitPrice; 234 } 235 236 @Override 237 public Class getUseTaxClass() { 238 return CreditMemoItemUseTax.class; 239 } 240 241 public PurchaseOrderItem getPurchaseOrderItem(){ 242 243 PurchaseOrderItem poi = null; 244 //refresh vendor document 245 if (ObjectUtils.isNotNull(this.getPurapDocumentIdentifier())) { 246 if (ObjectUtils.isNull(this.getVendorCreditMemo())) { 247 this.refreshReferenceObject(PurapPropertyConstants.PURAP_DOC); 248 } 249 } 250 251 //if vendor document not null, then attempt to pull PO off of it 252 if (ObjectUtils.isNotNull(getVendorCreditMemo())) { 253 PurchaseOrderDocument purchaseOrderDocument = null; 254 Integer purchaseOrderDocumentId = getVendorCreditMemo().getPurchaseOrderIdentifier(); 255 256 if (getVendorCreditMemo().isSourceDocumentPaymentRequest() && ObjectUtils.isNull(purchaseOrderDocumentId)) { 257 PaymentRequestDocument paymentRequestDocument = SpringContext.getBean(PaymentRequestService.class).getPaymentRequestById(getVendorCreditMemo().getPaymentRequestIdentifier()); 258 purchaseOrderDocumentId = paymentRequestDocument.getPurchaseOrderIdentifier(); 259 } 260 261 // if we found a valid po id number then check it for reopening 262 if (ObjectUtils.isNotNull(purchaseOrderDocumentId)) { 263 purchaseOrderDocument = SpringContext.getBean(PurchaseOrderService.class).getCurrentPurchaseOrder(purchaseOrderDocumentId); 264 } 265 266 //if we have a PO document, get po item 267 if(ObjectUtils.isNotNull(purchaseOrderDocument)){ 268 if (this.getItemType().isLineItemIndicator()) { 269 poi = (PurchaseOrderItem) purchaseOrderDocument.getItem(this.getItemLineNumber().intValue() - 1); 270 } 271 else { 272 poi = (PurchaseOrderItem) SpringContext.getBean(PurapService.class).getBelowTheLineByType(purchaseOrderDocument, this.getItemType()); 273 } 274 } 275 } 276 else { 277 throw new PurError("Credit Memo Object in Purchase Order item line number " + getItemLineNumber() + "or itemType " + getItemTypeCode() + " is null"); 278 } 279 280 return poi; 281 } 282 283 public VendorCreditMemoDocument getVendorCreditMemo() { 284 return super.getPurapDocument(); 285 } 286 287 }