001: /*
002: * Copyright 2006-2007 The Kuali Foundation.
003: *
004: * Licensed under the Educational Community License, Version 1.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/ecl1.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.module.purap.bo;
018:
019: import java.math.BigDecimal;
020: import java.util.ArrayList;
021: import java.util.HashMap;
022: import java.util.List;
023:
024: import org.apache.ojb.broker.PersistenceBroker;
025: import org.apache.ojb.broker.PersistenceBrokerException;
026: import org.kuali.core.util.KualiDecimal;
027: import org.kuali.core.util.ObjectUtils;
028: import org.kuali.kfs.context.SpringContext;
029: import org.kuali.module.purap.PurapConstants;
030: import org.kuali.module.purap.PurapPropertyConstants;
031: import org.kuali.module.purap.document.PaymentRequestDocument;
032: import org.kuali.module.purap.document.PurchaseOrderDocument;
033: import org.kuali.module.purap.exceptions.PurError;
034: import org.kuali.module.purap.service.AccountsPayableService;
035: import org.kuali.module.purap.service.PurapService;
036: import org.kuali.module.purap.util.ExpiredOrClosedAccountEntry;
037: import org.kuali.module.purap.util.PurApItemUtils;
038: import org.kuali.module.purap.util.PurApObjectUtils;
039:
040: /**
041: * Payment Request Item Business Object.
042: */
043: public class PaymentRequestItem extends AccountsPayableItemBase {
044: private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger
045: .getLogger(PaymentRequestItem.class);
046:
047: private BigDecimal purchaseOrderItemUnitPrice;
048: private String purchaseOrderCommodityCode;
049: private KualiDecimal itemOutstandingInvoiceQuantity;
050: private KualiDecimal itemOutstandingInvoiceAmount;
051:
052: private transient PaymentRequestDocument paymentRequest;
053:
054: /**
055: * Default constructor.
056: */
057: public PaymentRequestItem() {
058:
059: }
060:
061: /**
062: * preq item constructor - Delegate
063: *
064: * @param poi - purchase order item
065: * @param preq - payment request document
066: */
067: public PaymentRequestItem(PurchaseOrderItem poi,
068: PaymentRequestDocument preq) {
069: this (poi, preq,
070: new HashMap<String, ExpiredOrClosedAccountEntry>());
071: }
072:
073: /**
074: * Constructs a new payment request item, but also merges expired accounts.
075: *
076: * @param poi - purchase order item
077: * @param preq - payment request document
078: * @param expiredOrClosedAccountList - list of expired or closed accounts to merge
079: */
080: public PaymentRequestItem(
081: PurchaseOrderItem poi,
082: PaymentRequestDocument preq,
083: HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountList) {
084:
085: // copy base attributes w/ extra array of fields not to be copied
086: PurApObjectUtils.populateFromBaseClass(PurApItemBase.class,
087: poi, this , PurapConstants.PREQ_ITEM_UNCOPYABLE_FIELDS);
088:
089: // set up accounts
090: List accounts = new ArrayList();
091: for (PurApAccountingLine account : poi
092: .getSourceAccountingLines()) {
093: PurchaseOrderAccount poa = (PurchaseOrderAccount) account;
094:
095: // check if this account is expired/closed and replace as needed
096: SpringContext.getBean(AccountsPayableService.class)
097: .processExpiredOrClosedAccount(poa,
098: expiredOrClosedAccountList);
099:
100: accounts.add(new PaymentRequestAccount(this , poa));
101: }
102: this .setSourceAccountingLines(accounts);
103:
104: // clear amount and desc on below the line - we probably don't need that null
105: // itemType check but it's there just in case remove if it causes problems
106: // also do this if of type service, kulpurap - 1242
107: if ((ObjectUtils.isNotNull(this .getItemType()) && !this
108: .getItemType().isQuantityBasedGeneralLedgerIndicator())) {
109: // setting unit price to be null to be more consistent with other below the line
110: this .setItemUnitPrice(null);
111:
112: // if below the line item
113: if (!this .getItemType().isItemTypeAboveTheLineIndicator()) {
114: this .setItemDescription("");
115: }
116: }
117:
118: // copy custom
119: this .purchaseOrderItemUnitPrice = poi.getItemUnitPrice();
120: this .purchaseOrderCommodityCode = poi
121: .getPurchaseOrderCommodityCd();
122:
123: // set doc fields
124: this .setPurapDocumentIdentifier(preq
125: .getPurapDocumentIdentifier());
126: this .paymentRequest = preq;
127: }
128:
129: /**
130: * Retreives a purchase order item by inspecting the item type to see if its above the line or below the line and returns the
131: * appropriate type.
132: *
133: * @return - purchase order item
134: */
135: public PurchaseOrderItem getPurchaseOrderItem() {
136: if (ObjectUtils.isNotNull(this .getPurapDocumentIdentifier())) {
137: if (ObjectUtils.isNull(this .getPaymentRequest())) {
138: this
139: .refreshReferenceObject(PurapPropertyConstants.PAYMENT_REQUEST);
140: }
141: }
142: // ideally we should do this a different way - maybe move it all into the service or save this info somehow (make sure and
143: // update though)
144: if (getPaymentRequest() != null) {
145: PurchaseOrderDocument po = getPaymentRequest()
146: .getPurchaseOrderDocument();
147: PurchaseOrderItem poi = null;
148: if (this .getItemType().isItemTypeAboveTheLineIndicator()) {
149: poi = (PurchaseOrderItem) po.getItem(this
150: .getItemLineNumber().intValue() - 1);
151: // throw error if line numbers don't match
152: } else {
153: poi = (PurchaseOrderItem) SpringContext.getBean(
154: PurapService.class).getBelowTheLineByType(po,
155: this .getItemType());
156: }
157: if (poi != null) {
158: return poi;
159: } else {
160: LOG
161: .debug("getPurchaseOrderItem() Returning null because PurchaseOrderItem object for line number"
162: + getItemLineNumber()
163: + "or itemType "
164: + getItemTypeCode() + " is null");
165: return null;
166: }
167: } else {
168:
169: LOG
170: .error("getPurchaseOrderItem() Returning null because paymentRequest object is null");
171: throw new PurError(
172: "Payment Request Object in Purchase Order item line number "
173: + getItemLineNumber() + "or itemType "
174: + getItemTypeCode() + " is null");
175: }
176: }
177:
178: public KualiDecimal getPoOutstandingAmount() {
179: PurchaseOrderItem poi = getPurchaseOrderItem();
180: return this .getPoOutstandingAmount(poi);
181: }
182:
183: private KualiDecimal getPoOutstandingAmount(PurchaseOrderItem poi) {
184: if (poi == null) {
185: return KualiDecimal.ZERO;
186: } else {
187: return poi.getItemOutstandingEncumberedAmount();
188: }
189: }
190:
191: public KualiDecimal getPoOriginalAmount() {
192: PurchaseOrderItem poi = getPurchaseOrderItem();
193: if (poi == null) {
194: return null;
195: } else {
196: return poi.getExtendedPrice();
197: }
198: }
199:
200: /**
201: * Exists due to a setter requirement by the htmlControlAttribute
202: * @deprecated
203: * @param amount - po outstanding amount
204: */
205: public void setPoOutstandingAmount(KualiDecimal amount) {
206: // do nothing
207: }
208:
209: public KualiDecimal getPoOutstandingQuantity() {
210: PurchaseOrderItem poi = getPurchaseOrderItem();
211: if (poi == null) {
212: return null;
213: } else {
214: return poi.getOutstandingQuantity();
215: }
216: }
217:
218: /**
219: * Exists due to a setter requirement by the htmlControlAttribute
220: * @deprecated
221: * @param amount - po outstanding quantity
222: */
223: public void setPoOutstandingQuantity(KualiDecimal qty) {
224: // do nothing
225: }
226:
227: public BigDecimal getPurchaseOrderItemUnitPrice() {
228: return purchaseOrderItemUnitPrice;
229: }
230:
231: public void setPurchaseOrderItemUnitPrice(
232: BigDecimal purchaseOrderItemUnitPrice) {
233: this .purchaseOrderItemUnitPrice = purchaseOrderItemUnitPrice;
234: }
235:
236: public String getPurchaseOrderCommodityCode() {
237: return purchaseOrderCommodityCode;
238: }
239:
240: public void setPurchaseOrderCommodityCode(
241: String purchaseOrderCommodityCode) {
242: this .purchaseOrderCommodityCode = purchaseOrderCommodityCode;
243: }
244:
245: public KualiDecimal getItemOutstandingInvoiceAmount() {
246: return itemOutstandingInvoiceAmount;
247: }
248:
249: public void setItemOutstandingInvoiceAmount(
250: KualiDecimal itemOutstandingInvoiceAmount) {
251: this .itemOutstandingInvoiceAmount = itemOutstandingInvoiceAmount;
252: }
253:
254: public KualiDecimal getItemOutstandingInvoiceQuantity() {
255: return itemOutstandingInvoiceQuantity;
256: }
257:
258: public void setItemOutstandingInvoiceQuantity(
259: KualiDecimal itemOutstandingInvoiceQuantity) {
260: this .itemOutstandingInvoiceQuantity = itemOutstandingInvoiceQuantity;
261: }
262:
263: public PaymentRequestDocument getPaymentRequest() {
264: return paymentRequest;
265: }
266:
267: public void setPaymentRequest(PaymentRequestDocument paymentRequest) {
268: this .paymentRequest = paymentRequest;
269: }
270:
271: public void generateAccountListFromPoItemAccounts(
272: List<PurApAccountingLine> accounts) {
273: for (PurApAccountingLine line : accounts) {
274: PurchaseOrderAccount poa = (PurchaseOrderAccount) line;
275: if (!line.isEmpty()) {
276: getSourceAccountingLines().add(
277: new PaymentRequestAccount(this , poa));
278: }
279: }
280: }
281:
282: /**
283: * @see org.kuali.module.purap.bo.PurApItem#getAccountingLineClass()
284: */
285: public Class getAccountingLineClass() {
286: return PaymentRequestAccount.class;
287: }
288:
289: public boolean isDisplayOnPreq() {
290: PurchaseOrderItem poi = getPurchaseOrderItem();
291: if (ObjectUtils.isNull(poi)) {
292: LOG.debug("poi was null");
293: return false;
294: }
295:
296: // if the po item is not active... skip it
297: if (!poi.isItemActiveIndicator()) {
298: LOG.debug("poi was not active: " + poi.toString());
299: return false;
300: }
301:
302: ItemType poiType = poi.getItemType();
303:
304: if (poiType.isQuantityBasedGeneralLedgerIndicator()) {
305: if (poi.getItemQuantity().isGreaterThan(
306: poi.getItemInvoicedTotalQuantity())) {
307: return true;
308: } else {
309: if (ObjectUtils.isNotNull(this .getItemQuantity())
310: && this .getItemQuantity().isGreaterThan(
311: KualiDecimal.ZERO)) {
312: return true;
313: }
314: }
315:
316: return false;
317: } else { // not quantity based
318: if (poi.getItemOutstandingEncumberedAmount().isGreaterThan(
319: KualiDecimal.ZERO)) {
320: return true;
321: } else {
322: if (PurApItemUtils.isNonZeroExtended(this )) {
323: return true;
324: }
325: return false;
326: }
327:
328: }
329: }
330:
331: /**
332: * sets account line percentage to zero.
333: *
334: * @see org.kuali.module.purap.bo.PurApItem#resetAccount()
335: */
336: @Override
337: public void resetAccount() {
338: super .resetAccount();
339: this .getNewSourceLine()
340: .setAccountLinePercent(new BigDecimal(0));
341: }
342:
343: /**
344: * Refreshes payment request object.
345: *
346: * @see org.kuali.core.bo.PersistableBusinessObjectBase#afterLookup(org.apache.ojb.broker.PersistenceBroker)
347: */
348: @Override
349: public void afterLookup(PersistenceBroker persistenceBroker)
350: throws PersistenceBrokerException {
351: super.afterLookup(persistenceBroker);
352: if (ObjectUtils.isNotNull(this.getPurapDocumentIdentifier())) {
353: if (ObjectUtils.isNull(this.getPaymentRequest())) {
354: this
355: .refreshReferenceObject(PurapPropertyConstants.PAYMENT_REQUEST);
356: }
357: }
358: }
359:
360: }
|