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 static org.kuali.rice.kns.util.KualiDecimal.ZERO; 020 021 import java.math.BigDecimal; 022 import java.util.ArrayList; 023 import java.util.LinkedHashMap; 024 import java.util.List; 025 026 import org.apache.commons.lang.StringUtils; 027 import org.kuali.kfs.module.purap.PurapConstants; 028 import org.kuali.kfs.module.purap.PurapPropertyConstants; 029 import org.kuali.kfs.module.purap.document.PurchaseOrderDocument; 030 import org.kuali.kfs.module.purap.document.service.PurchaseOrderService; 031 import org.kuali.kfs.sys.context.SpringContext; 032 import org.kuali.rice.kns.service.SequenceAccessorService; 033 import org.kuali.rice.kns.util.KualiDecimal; 034 import org.kuali.rice.kns.util.ObjectUtils; 035 036 /** 037 * Purchase Order Item Business Object. 038 */ 039 public class PurchaseOrderItem extends PurchasingItemBase { 040 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PurchaseOrderItem.class); 041 042 private String documentNumber; 043 private KualiDecimal itemInvoicedTotalQuantity; 044 private KualiDecimal itemInvoicedTotalAmount; 045 private KualiDecimal itemReceivedTotalQuantity; 046 private KualiDecimal itemOutstandingEncumberedQuantity; 047 private KualiDecimal itemOutstandingEncumberedAmount; 048 private boolean itemActiveIndicator = true; 049 private KualiDecimal itemDamagedTotalQuantity; 050 051 private PurchaseOrderDocument purchaseOrder; 052 053 // Not persisted to DB 054 private boolean itemSelectedForRetransmitIndicator; 055 private boolean movingToSplit; 056 057 /** 058 * Default constructor. 059 */ 060 public PurchaseOrderItem() { 061 062 } 063 064 /** 065 * Constructor. 066 * 067 * @param ri - Requisition Item 068 * @param po - Purchase Order Document 069 */ 070 public PurchaseOrderItem(RequisitionItem ri, PurchaseOrderDocument po, RequisitionCapitalAssetItem reqCamsItem) { 071 super(); 072 073 this.setPurchaseOrder(po); 074 SequenceAccessorService sas = SpringContext.getBean(SequenceAccessorService.class); 075 Integer itemIdentifier = sas.getNextAvailableSequenceNumber("PO_ITM_ID", PurchaseOrderDocument.class).intValue(); 076 this.setItemIdentifier(itemIdentifier); 077 this.setItemLineNumber(ri.getItemLineNumber()); 078 this.setItemUnitOfMeasureCode(ri.getItemUnitOfMeasureCode()); 079 this.setItemQuantity(ri.getItemQuantity()); 080 this.setItemCatalogNumber(ri.getItemCatalogNumber()); 081 this.setItemDescription(ri.getItemDescription()); 082 this.setItemUnitPrice(ri.getItemUnitPrice()); 083 this.setItemAuxiliaryPartIdentifier(ri.getItemAuxiliaryPartIdentifier()); 084 this.setItemAssignedToTradeInIndicator(ri.getItemAssignedToTradeInIndicator()); 085 this.setItemTaxAmount( ri.getItemTaxAmount() ); 086 087 //copy use tax items over, and blank out keys (useTaxId and itemIdentifier) 088 for (PurApItemUseTax useTaxItem : ri.getUseTaxItems()) { 089 PurchaseOrderItemUseTax newItemUseTax = new PurchaseOrderItemUseTax(useTaxItem); 090 newItemUseTax.setItemIdentifier(itemIdentifier); 091 this.getUseTaxItems().add(newItemUseTax); 092 093 } 094 095 this.setExternalOrganizationB2bProductReferenceNumber(ri.getExternalOrganizationB2bProductReferenceNumber()); 096 this.setExternalOrganizationB2bProductTypeName(ri.getExternalOrganizationB2bProductTypeName()); 097 098 this.setItemReceivedTotalQuantity(ZERO); 099 this.setItemDamagedTotalQuantity(ZERO); 100 101 this.setItemTypeCode(ri.getItemTypeCode()); 102 103 if (ri.getSourceAccountingLines() != null && ri.getSourceAccountingLines().size() > 0 && 104 !StringUtils.equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_ORDER_DISCOUNT_CODE,ri.getItemType().getItemTypeCode())) { 105 List accounts = new ArrayList(); 106 for (PurApAccountingLine account : ri.getSourceAccountingLines()) { 107 PurchaseOrderAccount poAccount = new PurchaseOrderAccount(account); 108 poAccount.setPurchaseOrderItem(this); 109 accounts.add(poAccount); 110 } 111 this.setSourceAccountingLines(accounts); 112 } 113 // By default, set the item active indicator to true. 114 // In amendment, the user can set it to false when they click on 115 // the inactivate button. 116 this.setItemActiveIndicator(true); 117 118 this.setPurchasingCommodityCode(ri.getPurchasingCommodityCode()); 119 this.setCommodityCode(getCommodityCode()); 120 121 // If the RequisitionItem has a CapitalAssetItem, create a new PurchasingCapitalAssetItem and add it to the PO. 122 if( ObjectUtils.isNotNull(reqCamsItem) ) { 123 PurchaseOrderCapitalAssetItem newPOCapitalAssetItem = new PurchaseOrderCapitalAssetItem(reqCamsItem, itemIdentifier); 124 po.getPurchasingCapitalAssetItems().add(newPOCapitalAssetItem); 125 } 126 } 127 128 public boolean isItemActiveIndicator() { 129 return itemActiveIndicator; 130 } 131 132 // public String getItemActiveIndicator() { 133 // return (new Boolean(itemActiveIndicator)).toString(); 134 // } 135 136 public void setItemActiveIndicator(boolean itemActiveIndicator) { 137 this.itemActiveIndicator = itemActiveIndicator; 138 } 139 140 public KualiDecimal getItemInvoicedTotalAmount() { 141 return itemInvoicedTotalAmount; 142 } 143 144 public void setItemInvoicedTotalAmount(KualiDecimal itemInvoicedTotalAmount) { 145 this.itemInvoicedTotalAmount = itemInvoicedTotalAmount; 146 } 147 148 public KualiDecimal getItemInvoicedTotalQuantity() { 149 return itemInvoicedTotalQuantity; 150 } 151 152 public void setItemInvoicedTotalQuantity(KualiDecimal itemInvoicedTotalQuantity) { 153 this.itemInvoicedTotalQuantity = itemInvoicedTotalQuantity; 154 } 155 156 public KualiDecimal getItemOutstandingEncumberedQuantity() { 157 return itemOutstandingEncumberedQuantity; 158 } 159 160 public void setItemOutstandingEncumberedQuantity(KualiDecimal itemOutstandingEncumberedQuantity) { 161 this.itemOutstandingEncumberedQuantity = itemOutstandingEncumberedQuantity; 162 } 163 164 public KualiDecimal getItemOutstandingEncumberedAmount() { 165 return itemOutstandingEncumberedAmount; 166 } 167 168 public void setItemOutstandingEncumberedAmount(KualiDecimal itemOutstandingEncumbranceAmount) { 169 this.itemOutstandingEncumberedAmount = itemOutstandingEncumbranceAmount; 170 } 171 172 public KualiDecimal getItemReceivedTotalQuantity() { 173 return itemReceivedTotalQuantity; 174 } 175 176 public void setItemReceivedTotalQuantity(KualiDecimal itemReceivedTotalQuantity) { 177 this.itemReceivedTotalQuantity = itemReceivedTotalQuantity; 178 } 179 180 /** 181 * Gets the itemDamagedTotalQuantity attribute. 182 * @return Returns the itemDamagedTotalQuantity. 183 */ 184 public KualiDecimal getItemDamagedTotalQuantity() { 185 return itemDamagedTotalQuantity; 186 } 187 188 /** 189 * Sets the itemDamagedTotalQuantity attribute value. 190 * @param itemDamagedTotalQuantity The itemDamagedTotalQuantity to set. 191 */ 192 public void setItemDamagedTotalQuantity(KualiDecimal itemDamagedTotalQuantity) { 193 this.itemDamagedTotalQuantity = itemDamagedTotalQuantity; 194 } 195 196 public PurchaseOrderDocument getPurchaseOrder() { 197 if (ObjectUtils.isNull(purchaseOrder)) { 198 refreshReferenceObject(PurapPropertyConstants.PURAP_DOC); 199 } 200 return super.getPurapDocument(); 201 } 202 203 public void setPurchaseOrder(PurchaseOrderDocument purchaseOrder) { 204 setPurapDocument(purchaseOrder); 205 } 206 207 public String getDocumentNumber() { 208 return documentNumber; 209 } 210 211 public void setDocumentNumber(String documentNumber) { 212 this.documentNumber = documentNumber; 213 } 214 215 public boolean isItemSelectedForRetransmitIndicator() { 216 return itemSelectedForRetransmitIndicator; 217 } 218 219 public void setItemSelectedForRetransmitIndicator(boolean itemSelectedForRetransmitIndicator) { 220 this.itemSelectedForRetransmitIndicator = itemSelectedForRetransmitIndicator; 221 } 222 223 public boolean isMovingToSplit() { 224 return movingToSplit; 225 } 226 227 public void setMovingToSplit(boolean movingToSplit) { 228 this.movingToSplit = movingToSplit; 229 } 230 231 /** 232 * @see org.kuali.rice.kns.bo.BusinessObjectBase#toStringMapper() 233 */ 234 @Override 235 protected LinkedHashMap toStringMapper() { 236 LinkedHashMap m = new LinkedHashMap(); 237 m.put("documentNumber", this.documentNumber); 238 if (this.getItemIdentifier() != null) { 239 m.put("itemIdentifier", this.getItemIdentifier().toString()); 240 } 241 return m; 242 } 243 244 /** 245 * @see org.kuali.kfs.module.purap.businessobject.PurApItem#getAccountingLineClass() 246 */ 247 public Class getAccountingLineClass() { 248 return PurchaseOrderAccount.class; 249 } 250 251 /** 252 * 253 * This method returns the total item paid amount 254 * @return 255 */ 256 public KualiDecimal getItemPaidAmount() { 257 if (!(this.isItemActiveIndicator())) { 258 return KualiDecimal.ZERO; 259 } 260 return this.getItemInvoicedTotalAmount(); 261 } 262 263 public KualiDecimal getItemEncumbranceRelievedAmount() { 264 // check that it is active else return zero 265 if (this == null || !this.isItemActiveIndicator()) { 266 return KualiDecimal.ZERO; 267 } 268 // setup outstanding amount and get totalEncumberance from this.getExtendedCost() 269 KualiDecimal outstandingAmount = KualiDecimal.ZERO; 270 KualiDecimal totalEncumberance = this.getTotalAmount(); 271 272 ItemType iT = this.getItemType(); 273 // if service add the po outstanding amount to outstanding amount 274 if (iT.isAmountBasedGeneralLedgerIndicator()) { 275 outstandingAmount = outstandingAmount.add(this.getItemOutstandingEncumberedAmount()); 276 } 277 else { 278 // else add outstanding quantity * unit price 279 BigDecimal qty = new BigDecimal(this.getOutstandingQuantity().toString()); 280 outstandingAmount = outstandingAmount.add(new KualiDecimal(this.getItemUnitPrice().multiply(qty).setScale(KualiDecimal.SCALE, KualiDecimal.ROUND_BEHAVIOR))); 281 282 KualiDecimal itemTaxAmount = this.getItemTaxAmount() == null ? ZERO : this.getItemTaxAmount(); 283 KualiDecimal outstandingTaxAmount = new KualiDecimal(qty).divide(this.getItemQuantity()).multiply(itemTaxAmount); 284 outstandingAmount = outstandingAmount.add(outstandingTaxAmount); 285 } 286 287 // return the total encumbrance subtracted by the outstanding amount from above 288 return totalEncumberance.subtract(outstandingAmount); 289 } 290 291 /** 292 * Exists due to a setter requirement by the htmlControlAttribute 293 * @deprecated 294 * @param amount - outstanding quantity 295 */ 296 public void setOutstandingQuantity(){ 297 // do nothing 298 } 299 300 public KualiDecimal getOutstandingQuantity() { 301 KualiDecimal outstandingQuantity = (this.getItemQuantity() != null) ? this.getItemQuantity() : KualiDecimal.ZERO; 302 KualiDecimal invoicedQuantity = (this.getItemInvoicedTotalQuantity() != null) ? this.getItemInvoicedTotalQuantity() : KualiDecimal.ZERO; 303 return outstandingQuantity.subtract(invoicedQuantity); 304 } 305 306 public boolean isCanInactivateItem() { 307 if (versionNumber == null) { 308 // don't allow newly added item to be inactivatable. 309 return false; 310 } 311 else if (versionNumber != null && itemActiveIndicator && !getPurchaseOrder().getContainsUnpaidPaymentRequestsOrCreditMemos()) { 312 return true; 313 } 314 return false; 315 } 316 317 /** 318 * Override the method in PurApItemBase so that if the item is 319 * not eligible to be displayed in the account summary tab, 320 * which is if the item is inactive, we'll return null and 321 * the item won't be added to the list of account summary. 322 * 323 * @see org.kuali.kfs.module.purap.businessobject.PurApItemBase#getSummaryItem() 324 */ 325 @Override 326 public PurApSummaryItem getSummaryItem() { 327 if (!this.itemActiveIndicator) { 328 return null; 329 } 330 else { 331 return super.getSummaryItem(); 332 } 333 } 334 335 public boolean isNewUnorderedItem(){ 336 return SpringContext.getBean(PurchaseOrderService.class).isNewUnorderedItem(this); 337 } 338 339 @Override 340 public boolean isNewItemForAmendment() { 341 return SpringContext.getBean(PurchaseOrderService.class).isNewItemForAmendment(this); 342 } 343 344 @Override 345 public Class getUseTaxClass() { 346 return PurchaseOrderItemUseTax.class; 347 } 348 }