View Javadoc

1   /*
2    * Copyright 2006 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.module.purap.document;
17  
18  import org.apache.commons.lang.ArrayUtils;
19  import org.apache.commons.lang.StringUtils;
20  import org.kuali.ole.module.purap.PurapConstants;
21  import org.kuali.ole.module.purap.PurapParameterConstants;
22  import org.kuali.ole.module.purap.PurapPropertyConstants;
23  import org.kuali.ole.module.purap.businessobject.*;
24  import org.kuali.ole.module.purap.document.service.PurapService;
25  import org.kuali.ole.module.purap.service.PurapAccountingService;
26  import org.kuali.ole.module.purap.service.SensitiveDataService;
27  import org.kuali.ole.module.purap.util.PurApRelatedViews;
28  import org.kuali.ole.select.businessobject.OleLicensingRequirement;
29  import org.kuali.ole.select.document.OleInvoiceDocument;
30  import org.kuali.ole.select.service.OleUrlResolver;
31  import org.kuali.ole.sys.OLEConstants.AdHocPaymentIndicator;
32  import org.kuali.ole.sys.businessobject.AccountingLine;
33  import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntry;
34  import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntrySourceDetail;
35  import org.kuali.ole.sys.businessobject.SourceAccountingLine;
36  import org.kuali.ole.sys.context.SpringContext;
37  import org.kuali.ole.sys.document.AccountingDocumentBase;
38  import org.kuali.ole.sys.document.AmountTotaling;
39  import org.kuali.ole.sys.service.UniversityDateService;
40  import org.kuali.ole.vnd.businessobject.VendorAddress;
41  import org.kuali.ole.vnd.businessobject.VendorDetail;
42  import org.kuali.ole.vnd.document.service.VendorService;
43  import org.kuali.rice.core.api.config.property.ConfigContext;
44  import org.kuali.rice.core.api.util.type.KualiDecimal;
45  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
46  import org.kuali.rice.kew.api.WorkflowDocument;
47  import org.kuali.rice.krad.rules.rule.event.ApproveDocumentEvent;
48  import org.kuali.rice.krad.rules.rule.event.KualiDocumentEvent;
49  import org.kuali.rice.krad.rules.rule.event.RouteDocumentEvent;
50  import org.kuali.rice.krad.service.KualiModuleService;
51  import org.kuali.rice.krad.service.ModuleService;
52  import org.kuali.rice.krad.util.NoteType;
53  import org.kuali.rice.krad.util.ObjectUtils;
54  import org.kuali.rice.location.api.LocationConstants;
55  import org.kuali.rice.location.framework.country.CountryEbo;
56  
57  import java.math.BigDecimal;
58  import java.text.MessageFormat;
59  import java.util.*;
60  
61  /**
62   * Base class for Purchasing-Accounts Payable Documents.
63   */
64  public abstract class PurchasingAccountsPayableDocumentBase extends AccountingDocumentBase implements PurchasingAccountsPayableDocument, AmountTotaling {
65  
66      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PurchasingAccountsPayableDocumentBase.class);
67  
68      // SHARED FIELDS BETWEEN REQUISITION, PURCHASE ORDER, PAYMENT REQUEST, AND CREDIT MEMO
69      protected Integer purapDocumentIdentifier;
70      protected Integer vendorHeaderGeneratedIdentifier;
71      protected Integer vendorDetailAssignedIdentifier;
72      protected String vendorCustomerNumber;
73      protected String vendorName;
74      protected String vendorLine1Address;
75      protected String vendorLine2Address;
76      protected String vendorCityName;
77      protected String vendorStateCode;
78      protected String vendorAddressInternationalProvinceName;
79      protected String vendorPostalCode;
80      protected String vendorCountryCode;
81      protected Integer accountsPayablePurchasingDocumentLinkIdentifier;
82      protected boolean useTaxIndicator;
83      protected String vendorAttentionName;
84      protected String accountDistributionMethod;  //code for account distribution method
85      /**
86       * Variable purchaseOrderTypeId added to store order type
87       */
88      protected BigDecimal purchaseOrderTypeId;
89     /* protected boolean licensingRequirementIndicator;*/
90      /*protected String licensingRequirementCode;*/
91  
92      protected String statusCode;
93  
94      // NOT PERSISTED IN DB
95      protected String vendorNumber;
96      protected Integer vendorAddressGeneratedIdentifier;
97      protected Boolean overrideWorkflowButtons = null;
98      protected transient PurApRelatedViews relatedViews;
99      protected boolean sensitive;
100 
101     protected boolean calculated;
102 
103     // COLLECTIONS
104     protected List<PurApItem> items;
105     protected List<SourceAccountingLine> accountsForRouting; // don't use me for anything else!!
106 
107     // REFERENCE OBJECTS
108     protected VendorDetail vendorDetail;
109     protected CountryEbo vendorCountry;
110     protected PurchaseOrderType orderType;
111     protected OleLicensingRequirement licenseReqmt;
112 
113     // STATIC
114     public transient String[] belowTheLineTypes;
115 
116     // workaround for purapOjbCollectionHelper - remove when merged into rice
117     public boolean allowDeleteAwareCollection = true;
118 
119     // license request document number
120     /*public transient String licenseRequestDocNum = null;*/
121     /*private transient OleLicenseRequestView licenseRequestViews = new OleLicenseRequestView();*/
122     private transient OleUrlResolver oleUrlResolver;
123 
124 
125     /*public OleLicenseRequestView getLicenseRequestViews() {
126         return licenseRequestViews;
127     }
128 
129     public void setLicenseRequestViews(OleLicenseRequestView licenseRequestViews) {
130         this.licenseRequestViews = licenseRequestViews;
131     }*/
132 
133     /**
134      * Default constructor to be overridden.
135      */
136     public PurchasingAccountsPayableDocumentBase() {
137         items = new ArrayList();
138     }
139 
140     protected GeneralLedgerPendingEntry getFirstPendingGLEntry() {
141         if (ObjectUtils.isNotNull(getGeneralLedgerPendingEntries()) && !getGeneralLedgerPendingEntries().isEmpty()) {
142             return getGeneralLedgerPendingEntries().get(0);
143         }
144         return null;
145     }
146 
147     public Integer getPostingYearFromPendingGLEntries() {
148         GeneralLedgerPendingEntry glpe = getFirstPendingGLEntry();
149         if (ObjectUtils.isNotNull(glpe)) {
150             return glpe.getUniversityFiscalYear();
151         }
152         return null;
153     }
154 
155     public String getPostingPeriodCodeFromPendingGLEntries() {
156         GeneralLedgerPendingEntry glpe = getFirstPendingGLEntry();
157         if (ObjectUtils.isNotNull(glpe)) {
158             return glpe.getUniversityFiscalPeriodCode();
159         }
160         return null;
161     }
162 
163     public List<SourceAccountingLine> getAccountsForRouting() {
164         if (accountsForRouting == null) {
165             populateAccountsForRouting();
166         }
167         return accountsForRouting;
168     }
169 
170     public void setAccountsForRouting(List<SourceAccountingLine> accountsForRouting) {
171         this.accountsForRouting = accountsForRouting;
172     }
173 
174     /**
175      * Makes sure that accounts for routing has been generated, so that other information can be retrieved from that
176      */
177     protected void populateAccountsForRouting() {
178         SpringContext.getBean(PurapAccountingService.class).updateAccountAmounts(this);
179         setAccountsForRouting(SpringContext.getBean(PurapAccountingService.class).generateSummary(getItems()));
180         // need to refresh to get the references for the searchable attributes (ie status) and for invoking route levels (ie account
181         // objects) -hjs
182         refreshNonUpdateableReferences();
183         for (SourceAccountingLine sourceLine : getAccountsForRouting()) {
184             sourceLine.refreshNonUpdateableReferences();
185         }
186     }
187 
188     public boolean isSensitive() {
189         List<SensitiveData> sensitiveData = SpringContext.getBean(SensitiveDataService.class).getSensitiveDatasAssignedByRelatedDocId(getAccountsPayablePurchasingDocumentLinkIdentifier());
190         if (ObjectUtils.isNotNull(sensitiveData) && !sensitiveData.isEmpty()) {
191             return true;
192         }
193         return false;
194     }
195 
196     /**
197      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument#isInquiryRendered()
198      */
199     @Override
200     public boolean isInquiryRendered() {
201         return isPostingYearPrior();
202     }
203 
204     /**
205      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument#isPostingYearNext()
206      */
207     @Override
208     public boolean isPostingYearNext() {
209         Integer currentFY = SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear();
210         return (getPostingYear().compareTo(currentFY) > 0);
211     }
212 
213     /**
214      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument#isPostingYearPrior()
215      */
216     @Override
217     public boolean isPostingYearPrior() {
218         Integer currentFY = SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear();
219         return (getPostingYear().compareTo(currentFY) < 0);
220     }
221 
222     /**
223      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument#getPostingYearNextOrCurrent()
224      */
225     @Override
226     public Integer getPostingYearNextOrCurrent() {
227         if (isPostingYearNext()) {
228             //FY is set to next; use it
229             return getPostingYear();
230         }
231         //FY is NOT set to next; use CURRENT
232         return SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear();
233     }
234 
235     /**
236      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument#getItemClass()
237      */
238     @Override
239     @SuppressWarnings("rawtypes")
240     public abstract Class getItemClass();
241 
242     @SuppressWarnings("rawtypes")
243     public abstract Class getItemUseTaxClass();
244 
245     /**
246      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument#getPurApSourceDocumentIfPossible()
247      */
248     @Override
249     public abstract PurchasingAccountsPayableDocument getPurApSourceDocumentIfPossible();
250 
251     /**
252      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument#getPurApSourceDocumentLabelIfPossible()
253      */
254     @Override
255     public abstract String getPurApSourceDocumentLabelIfPossible();
256 
257     /**
258      * @see org.kuali.rice.krad.document.DocumentBase#prepareForSave()
259      */
260     @Override
261     public void prepareForSave(KualiDocumentEvent event) {
262         customPrepareForSave(event);
263         super.prepareForSave(event);
264         fixItemReferences();
265     }
266 
267     /**
268      * PURAP documents are all overriding this method to return false because sufficient funds checking should not be performed on
269      * route of any PURAP documents. Only the Purchase Order performs a sufficient funds check and it is manually forced during
270      * routing.
271      *
272      * @see org.kuali.ole.sys.document.GeneralLedgerPostingDocumentBase#documentPerformsSufficientFundsCheck()
273      */
274     @Override
275     public boolean documentPerformsSufficientFundsCheck() {
276         return false;
277     }
278 
279     // for app doc status
280     @Override
281     public boolean isDocumentStoppedInRouteNode(String nodeName) {
282         WorkflowDocument workflowDocument = this.getFinancialSystemDocumentHeader().getWorkflowDocument();
283 
284         Set<String> names = workflowDocument.getCurrentNodeNames();
285         List<String> currentRouteLevels = new ArrayList<String>(names);
286         if (currentRouteLevels.contains(nodeName) && workflowDocument.isApprovalRequested()) {
287             return true;
288         }
289         return false;
290     }
291 
292     /**
293      * Records the specified error message into the Log file and throws a runtime exception.
294      *
295      * @param errorMessage the error message to be logged.
296      */
297     protected void logAndThrowRuntimeException(String errorMessage) {
298         this.logAndThrowRuntimeException(errorMessage, null);
299     }
300 
301     /**
302      * Records the specified error message into the Log file and throws the specified runtime exception.
303      *
304      * @param errorMessage the specified error message.
305      * @param e            the specified runtime exception.
306      */
307     protected void logAndThrowRuntimeException(String errorMessage, Exception e) {
308         if (ObjectUtils.isNotNull(e)) {
309             LOG.error(errorMessage, e);
310             throw new RuntimeException(errorMessage, e);
311         } else {
312             LOG.error(errorMessage);
313             throw new RuntimeException(errorMessage);
314         }
315     }
316 
317     /**
318      * Allows child PO classes to customize the prepareForSave method. Most of the subclasses need to call the super's method to get
319      * the GL entry creation, but they each need to do different things to prepare for those entries to be created. This is only for
320      * PO since it has children classes that need different prep work for GL creation.
321      *
322      * @param event the event involved in this action.
323      */
324     public void customPrepareForSave(KualiDocumentEvent event) {
325         // Need this here so that it happens before the GL work is done
326         SpringContext.getBean(PurapAccountingService.class).updateAccountAmounts(this);
327 
328         if (event instanceof RouteDocumentEvent || event instanceof ApproveDocumentEvent) {
329             if (this instanceof VendorCreditMemoDocument && ((VendorCreditMemoDocument) this).isSourceVendor()) {
330                 return;
331             }
332             if (this instanceof OleInvoiceDocument || this instanceof InvoiceDocument) {
333                 return;
334             }
335             SpringContext.getBean(PurapService.class).calculateTax(this);
336         }
337         // These next 5 lines are temporary changes so that we can use PurApOjbCollectionHelper for release 2.
338         // But these 5 lines will not be necessary anymore if the changes in PurApOjbCollectionHelper is
339         // merge into Rice.
340 //        this.allowDeleteAwareCollection = true;
341 //        DocumentDaoOjb docDao = SpringContext.getBean(DocumentDaoOjb.class);
342         // PurchasingAccountsPayableDocumentBase retrievedDocument = (PurchasingAccountsPayableDocumentBase)
343         // docDao.findByDocumentHeaderId(this.getClass(), this.getDocumentNumber());
344 //        if (retrievedDocument != null) {
345 //            retrievedDocument.allowDeleteAwareCollection = true;
346 //        }
347 //
348 //        SpringContext.getBean(PurApOjbCollectionHelper.class).processCollections(docDao, this, retrievedDocument);
349 //        this.allowDeleteAwareCollection = false;
350 //        if (retrievedDocument != null) {
351 //            retrievedDocument.allowDeleteAwareCollection = false;
352 //        }
353     }
354 
355     /**
356      * @see org.kuali.ole.sys.document.AccountingDocumentBase#buildListOfDeletionAwareLists()
357      */
358     @Override
359     public List buildListOfDeletionAwareLists() {
360         List managedLists = new ArrayList<List>();
361         managedLists.add(getDeletionAwareAccountingLines());
362         if (allowDeleteAwareCollection) {
363             //From now on, the list of accounting lines would have been added when the
364             //super.buildListOfDeletionAwareLists() is executed when it calls getSourceAccountingLines().
365             //So we can remove the old codes that used to exist here to add the accounts to the
366             //managedLists and just use the one from the super.buildListOfDeletionAwareLists()
367             List<PurApItemBase> subManageList = this.getItems();
368             List useTaxItems = new ArrayList();
369             for (PurApItemBase subManage : subManageList) {
370                 useTaxItems.addAll(subManage.getUseTaxItems());
371             }
372 
373             managedLists.add(this.getItems());
374             managedLists.add(useTaxItems);
375         }
376         return managedLists;
377     }
378 
379     /**
380      * Build deletion list of accounting lines for PurAp generic use.
381      *
382      * @return
383      */
384     @SuppressWarnings("rawtypes")
385     protected List getDeletionAwareAccountingLines() {
386         List<PurApAccountingLine> deletionAwareAccountingLines = new ArrayList<PurApAccountingLine>();
387         for (Object itemAsObject : this.getItems()) {
388             final PurApItem item = (PurApItem) itemAsObject;
389             for (PurApAccountingLine accountingLine : item.getSourceAccountingLines()) {
390                 deletionAwareAccountingLines.add(accountingLine);
391             }
392         }
393         return deletionAwareAccountingLines;
394     }
395 
396     /**
397      * @Override public List buildListOfDeletionAwareLists() { List managedLists = new ArrayList(); if (allowDeleteAwareCollection) {
398      * List<PurApAccountingLine> purapAccountsList = new ArrayList<PurApAccountingLine>(); for (Object itemAsObject :
399      * this.getItems()) { final PurApItem item = (PurApItem)itemAsObject;
400      * purapAccountsList.addAll(item.getSourceAccountingLines()); } managedLists.add(purapAccountsList);
401      * managedLists.add(this.getItems()); } return managedLists; }
402      * @see org.kuali.ole.sys.document.AccountingDocumentBase#buildListOfDeletionAwareLists()
403      */
404 
405     @Override
406     public void processAfterRetrieve() {
407         super.processAfterRetrieve();
408 
409         refreshNonUpdateableReferences();
410     }
411 
412     /**
413      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument#addItem(PurApItem item)
414      */
415     @Override
416     public void addItem(PurApItem item) {
417         int itemLinePosition = getItemLinePosition();
418         if (ObjectUtils.isNotNull(item.getItemLineNumber()) && (item.getItemLineNumber() > 0) && (item.getItemLineNumber() <= itemLinePosition)) {
419             itemLinePosition = item.getItemLineNumber().intValue() - 1;
420         }
421 
422         item.setPurapDocumentIdentifier(this.purapDocumentIdentifier);
423         item.setPurapDocument(this);
424 
425         items.add(itemLinePosition, item);
426         renumberItems(itemLinePosition);
427     }
428 
429     /**
430      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument#deleteItem(int lineNum)
431      */
432     @Override
433     public void deleteItem(int lineNum) {
434         if (items.remove(lineNum) == null) {
435             // throw error here
436         }
437         renumberItems(lineNum);
438     }
439 
440     /**
441      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument#renumberItems(int start)
442      */
443     @Override
444     public void renumberItems(int start) {
445         for (int i = start; i < items.size(); i++) {
446             PurApItem item = items.get(i);
447             // only set the item line number for above the line items
448             if (item.getItemType().isLineItemIndicator()) {
449                 item.setItemLineNumber(new Integer(i + 1));
450             }
451         }
452     }
453 
454     /**
455      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument#itemSwap(int positionFrom, int positionTo)
456      */
457     @Override
458     public void itemSwap(int positionFrom, int positionTo) {
459         // if out of range do nothing
460         if ((positionTo < 0) || (positionTo >= getItemLinePosition())) {
461             return;
462         }
463         PurApItem item1 = this.getItem(positionFrom);
464         PurApItem item2 = this.getItem(positionTo);
465         Integer oldFirstPos = item1.getItemLineNumber();
466         // swap line numbers
467         item1.setItemLineNumber(item2.getItemLineNumber());
468         item2.setItemLineNumber(oldFirstPos);
469         // fix ordering in list
470         items.remove(positionFrom);
471         items.add(positionTo, item1);
472     }
473 
474     /**
475      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument#getItemLinePosition()
476      */
477     @Override
478     public int getItemLinePosition() {
479         int belowTheLineCount = 0;
480         for (PurApItem item : items) {
481             if (item.getItemType().isAdditionalChargeIndicator()) {
482                 belowTheLineCount++;
483             }
484         }
485         return items.size() - belowTheLineCount;
486     }
487 
488     /**
489      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument#getItem(int pos)
490      */
491     @Override
492     public PurApItem getItem(int pos) {
493         return items.get(pos);
494     }
495 
496     /**
497      * Iterates through the items of the document and returns the item with the line number equal to the number given, or null if a
498      * match is not found.
499      *
500      * @param lineNumber line number to match on.
501      * @return the PurchasingAp Item if a match is found, else null.
502      */
503     @SuppressWarnings("rawtypes")
504     public PurApItem getItemByLineNumber(int lineNumber) {
505         for (Object element : items) {
506             PurApItem item = (PurApItem) element;
507             if (item.getItemLineNumber().intValue() == lineNumber) {
508                 return item;
509             }
510         }
511         return null;
512     }
513 
514     /**
515      * Find the item in the document via its string identifier.
516      *
517      * @param itemStrID the string identifier of the item being searched for
518      * @return the item being searched for
519      */
520     @SuppressWarnings("rawtypes")
521     public PurApItem getItemByStringIdentifier(String itemStrID) {
522         for (Object element : items) {
523             PurApItem item = (PurApItem) element;
524             if (StringUtils.equalsIgnoreCase(item.getItemIdentifierString(), itemStrID)) {
525                 return item;
526             }
527         }
528         return null;
529     }
530 
531     /**
532      * Find the item in the document via its identifier.
533      *
534      * @param itemID the string identifier of the item being searched for
535      * @return the item being searched for
536      */
537     @SuppressWarnings("rawtypes")
538     public PurApItem getItemByItemIdentifier(Integer itemID) {
539         for (Object element : items) {
540             PurApItem item = (PurApItem) element;
541             if (item.getItemIdentifier() == itemID) {
542                 return item;
543             }
544         }
545         return null;
546     }
547 
548     /**
549      * Overriding the parent method so that we can just set the posting year without the other stuff that the parent does to the
550      * accounting period. We only store the posting year on the doc and don't want the other stuff.
551      *
552      * @see org.kuali.ole.sys.document.LedgerPostingDocumentBase#setPostingYear(java.lang.Integer)
553      */
554     @Override
555     public void setPostingYear(Integer postingYear) {
556         this.postingYear = postingYear;
557     }
558 
559     /**
560      * @see org.kuali.ole.sys.document.AccountingDocumentBase#getTotalDollarAmount()
561      */
562     @Override
563     public KualiDecimal getTotalDollarAmount() {
564         return getTotalDollarAmountAllItems(null);
565     }
566 
567     /**
568      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument#setTotalDollarAmount(KualiDecimal amount)
569      */
570     @Override
571     public void setTotalDollarAmount(KualiDecimal amount) {
572         // do nothing, this is so that the jsp won't complain about totalDollarAmount have no setter method.
573     }
574 
575     /**
576      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument#getTotalDollarAmountAllItems(String[]
577      *      excludedTypes)
578      */
579     @Override
580     public KualiDecimal getTotalDollarAmountAllItems(String[] excludedTypes) {
581         return getTotalDollarAmountWithExclusions(excludedTypes, true);
582     }
583 
584     /**
585      * Computes the total dollar amount of all above the line items.
586      *
587      * @return the total dollar amount of all above the line items.
588      */
589     @Override
590     public KualiDecimal getTotalDollarAmountAboveLineItems() {
591         return getTotalDollarAmountAboveLineItems(null);
592     }
593 
594     /**
595      * Computes the total dollar amount of all above the line items with the specified item types excluded.
596      *
597      * @param excludedTypes the types of items to be excluded.
598      * @return the total dollar amount of all above the line items with the specified item types excluded..
599      */
600     public KualiDecimal getTotalDollarAmountAboveLineItems(String[] excludedTypes) {
601         return getTotalDollarAmountWithExclusions(excludedTypes, false);
602     }
603 
604     /**
605      * Computes the total dollar amount with the specified item types and possibly below the line items excluded.
606      *
607      * @param excludedTypes       the types of items to be excluded.
608      * @param includeBelowTheLine indicates whether below the line items shall be included.
609      * @return the total dollar amount with the specified item types excluded.
610      */
611     public KualiDecimal getTotalDollarAmountWithExclusions(String[] excludedTypes, boolean includeBelowTheLine) {
612         List<PurApItem> itemsForTotal = getItems();
613 
614         return getTotalDollarAmountWithExclusionsSubsetItems(excludedTypes, includeBelowTheLine, itemsForTotal);
615     }
616 
617     /**
618      * This method...
619      *
620      * @param excludedTypes
621      * @param includeBelowTheLine
622      * @param itemsForTotal
623      * @return
624      */
625     protected KualiDecimal getTotalDollarAmountWithExclusionsSubsetItems(String[] excludedTypes, boolean includeBelowTheLine, List<PurApItem> itemsForTotal) {
626         if (excludedTypes == null) {
627             excludedTypes = new String[]{};
628         }
629 
630         KualiDecimal total = new KualiDecimal(BigDecimal.ZERO);
631         for (PurApItem item : itemsForTotal) {
632             item.refreshReferenceObject(PurapPropertyConstants.ITEM_TYPE);
633             ItemType it = item.getItemType();
634             if ((includeBelowTheLine || it.isLineItemIndicator()) && !ArrayUtils.contains(excludedTypes, it.getItemTypeCode())) {
635                 KualiDecimal totalAmount = item.getTotalAmount();
636                 KualiDecimal itemTotal = (totalAmount != null) ? totalAmount : KualiDecimal.ZERO;
637                 total = total.add(itemTotal);
638             }
639         }
640         return total;
641     }
642 
643     @Override
644     public KualiDecimal getTotalDollarAmountForTradeIn() {
645         List<PurApItem> tradeInItems = getTradeInItems();
646         return getTotalDollarAmountWithExclusionsSubsetItems(null, false, tradeInItems);
647     }
648 
649     /**
650      * This method...
651      *
652      * @param tradeInItems
653      */
654     @Override
655     public List<PurApItem> getTradeInItems() {
656         List<PurApItem> tradeInItems = new ArrayList<PurApItem>();
657         for (PurApItem purApItem : (List<PurApItem>) getItems()) {
658             if (purApItem.getItemAssignedToTradeInIndicator()) {
659                 tradeInItems.add(purApItem);
660             }
661         }
662         return tradeInItems;
663     }
664 
665     /**
666      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument#getTotalPreTaxDollarAmount()
667      */
668     @Override
669     public KualiDecimal getTotalPreTaxDollarAmount() {
670         return getTotalPreTaxDollarAmountAllItems(null);
671     }
672 
673     /**
674      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument#setTotalPreTaxDollarAmount(org.kuali.rice.kns.util.KualiDecimal)
675      */
676     @Override
677     public void setTotalPreTaxDollarAmount(KualiDecimal amount) {
678         // do nothing, this is so that the jsp won't complain about totalDollarAmount have no setter method.
679     }
680 
681     /**
682      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument#getTotalPreTaxDollarAmountAllItems(java.lang.String[])
683      */
684     @Override
685     public KualiDecimal getTotalPreTaxDollarAmountAllItems(String[] excludedTypes) {
686         return getTotalPreTaxDollarAmountWithExclusions(excludedTypes, true);
687     }
688 
689     /**
690      * Computes the total dollar amount of all above the line items.
691      *
692      * @return the total dollar amount of all above the line items.
693      */
694     public KualiDecimal getTotalPreTaxDollarAmountAboveLineItems() {
695         return getTotalPreTaxDollarAmountAboveLineItems(null);
696     }
697 
698     /**
699      * Computes the total dollar amount of all above the line items with the specified item types excluded.
700      *
701      * @param excludedTypes the types of items to be excluded.
702      * @return the total dollar amount of all above the line items with the specified item types excluded..
703      */
704     public KualiDecimal getTotalPreTaxDollarAmountAboveLineItems(String[] excludedTypes) {
705         return getTotalPreTaxDollarAmountWithExclusions(excludedTypes, false);
706     }
707 
708     /**
709      * Computes the total dollar amount with the specified item types and possibly below the line items excluded.
710      *
711      * @param excludedTypes       the types of items to be excluded.
712      * @param includeBelowTheLine indicates whether below the line items shall be included.
713      * @return the total dollar amount with the specified item types excluded.
714      */
715     public KualiDecimal getTotalPreTaxDollarAmountWithExclusions(String[] excludedTypes, boolean includeBelowTheLine) {
716         if (excludedTypes == null) {
717             excludedTypes = new String[]{};
718         }
719 
720         KualiDecimal total = new KualiDecimal(BigDecimal.ZERO);
721         for (PurApItem item : (List<PurApItem>) getItems()) {
722             item.refreshReferenceObject(PurapPropertyConstants.ITEM_TYPE);
723             ItemType it = item.getItemType();
724             if ((includeBelowTheLine || it.isLineItemIndicator()) && !ArrayUtils.contains(excludedTypes, it.getItemTypeCode())) {
725                 KualiDecimal extendedPrice = item.getExtendedPrice();
726                 KualiDecimal itemTotal = (extendedPrice != null) ? extendedPrice : KualiDecimal.ZERO;
727                 total = total.add(itemTotal);
728             }
729         }
730         return total;
731     }
732 
733     @Override
734     public KualiDecimal getTotalTaxAmount() {
735         return getTotalTaxAmountAllItems(null);
736     }
737 
738     @Override
739     public void setTotalTaxAmount(KualiDecimal amount) {
740         // do nothing, this is so that the jsp won't complain about totalTaxAmount have no setter method.
741     }
742 
743     @Override
744     public KualiDecimal getTotalTaxAmountAllItems(String[] excludedTypes) {
745         return getTotalTaxAmountWithExclusions(excludedTypes, true);
746     }
747 
748     @Override
749     public KualiDecimal getTotalTaxAmountAboveLineItems() {
750         return getTotalTaxAmountAboveLineItems(null);
751     }
752 
753     @Override
754     public KualiDecimal getTotalTaxAmountAboveLineItems(String[] excludedTypes) {
755         return getTotalTaxAmountWithExclusions(excludedTypes, false);
756     }
757 
758     @Override
759     public KualiDecimal getTotalTaxAmountWithExclusions(String[] excludedTypes, boolean includeBelowTheLine) {
760         if (excludedTypes == null) {
761             excludedTypes = new String[]{};
762         }
763 
764         KualiDecimal total = new KualiDecimal(BigDecimal.ZERO);
765         for (PurApItem item : (List<PurApItem>) getItems()) {
766             item.refreshReferenceObject(PurapPropertyConstants.ITEM_TYPE);
767             ItemType it = item.getItemType();
768             if ((includeBelowTheLine || it.isLineItemIndicator()) && !ArrayUtils.contains(excludedTypes, it.getItemTypeCode())) {
769                 KualiDecimal taxAmount = item.getItemTaxAmount();
770                 KualiDecimal itemTotal = (taxAmount != null) ? taxAmount : KualiDecimal.ZERO;
771                 total = total.add(itemTotal);
772             }
773         }
774         return total;
775     }
776 
777     @Override
778     public boolean isUseTaxIndicator() {
779         return useTaxIndicator;
780     }
781 
782     @Override
783     public void setUseTaxIndicator(boolean useTaxIndicator) {
784         this.useTaxIndicator = useTaxIndicator;
785     }
786 
787     /**
788      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument#templateVendorAddress(VendorAddress)
789      */
790     @Override
791     public void templateVendorAddress(VendorAddress vendorAddress) {
792         if (vendorAddress == null) {
793             return;
794         }
795         this.setVendorLine1Address(vendorAddress.getVendorLine1Address());
796         this.setVendorLine2Address(vendorAddress.getVendorLine2Address());
797         this.setVendorCityName(vendorAddress.getVendorCityName());
798         this.setVendorStateCode(vendorAddress.getVendorStateCode());
799         this.setVendorPostalCode(vendorAddress.getVendorZipCode());
800         this.setVendorCountryCode(vendorAddress.getVendorCountryCode());
801     }
802 
803     /**
804      * Returns the vendor number for this document.
805      *
806      * @return the vendor number for this document.
807      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument#getVendorNumber()
808      */
809     @Override
810     public String getVendorNumber() {
811         if (StringUtils.isNotEmpty(vendorNumber)) {
812             return vendorNumber;
813         } else if (ObjectUtils.isNotNull(vendorDetail)) {
814             return vendorDetail.getVendorNumber();
815         } else {
816             return "";
817         }
818     }
819 
820     @Override
821     public void setVendorNumber(String vendorNumber) {
822         this.vendorNumber = vendorNumber;
823     }
824 
825     public Boolean getOverrideWorkflowButtons() {
826         return overrideWorkflowButtons;
827     }
828 
829     public void setOverrideWorkflowButtons(Boolean overrideWorkflowButtons) {
830         this.overrideWorkflowButtons = overrideWorkflowButtons;
831     }
832 
833     @Override
834     public Integer getVendorHeaderGeneratedIdentifier() {
835         return vendorHeaderGeneratedIdentifier;
836     }
837 
838     @Override
839     public void setVendorHeaderGeneratedIdentifier(Integer vendorHeaderGeneratedIdentifier) {
840         this.vendorHeaderGeneratedIdentifier = vendorHeaderGeneratedIdentifier;
841     }
842 
843     @Override
844     public Integer getVendorDetailAssignedIdentifier() {
845         return vendorDetailAssignedIdentifier;
846     }
847 
848     @Override
849     public void setVendorDetailAssignedIdentifier(Integer vendorDetailAssignedIdentifier) {
850         this.vendorDetailAssignedIdentifier = vendorDetailAssignedIdentifier;
851     }
852 
853     @Override
854     public String getVendorCustomerNumber() {
855         return vendorCustomerNumber;
856     }
857 
858     @Override
859     public void setVendorCustomerNumber(String vendorCustomerNumber) {
860         this.vendorCustomerNumber = vendorCustomerNumber;
861     }
862 
863     @Override
864     public Integer getPurapDocumentIdentifier() {
865         return purapDocumentIdentifier;
866     }
867 
868     @Override
869     public void setPurapDocumentIdentifier(Integer identifier) {
870         this.purapDocumentIdentifier = identifier;
871     }
872 
873     @Override
874     public VendorDetail getVendorDetail() {
875         return vendorDetail;
876     }
877 
878     public void setVendorDetail(VendorDetail vendorDetail) {
879         this.vendorDetail = vendorDetail;
880     }
881 
882     @Override
883     @SuppressWarnings("rawtypes")
884     public List getItems() {
885         return items;
886     }
887 
888     @Override
889     @SuppressWarnings("rawtypes")
890     public void setItems(List items) {
891         this.items = items;
892     }
893 
894     @Override
895     public String getVendorCityName() {
896         return vendorCityName;
897     }
898 
899     @Override
900     public void setVendorCityName(String vendorCityName) {
901         this.vendorCityName = vendorCityName;
902     }
903 
904     @Override
905     public String getVendorCountryCode() {
906         return vendorCountryCode;
907     }
908 
909     @Override
910     public void setVendorCountryCode(String vendorCountryCode) {
911         this.vendorCountryCode = vendorCountryCode;
912     }
913 
914     @Override
915     public String getVendorLine1Address() {
916         return vendorLine1Address;
917     }
918 
919     @Override
920     public void setVendorLine1Address(String vendorLine1Address) {
921         this.vendorLine1Address = vendorLine1Address;
922     }
923 
924     @Override
925     public String getVendorLine2Address() {
926         return vendorLine2Address;
927     }
928 
929     @Override
930     public void setVendorLine2Address(String vendorLine2Address) {
931         this.vendorLine2Address = vendorLine2Address;
932     }
933 
934     @Override
935     public String getVendorName() {
936         return vendorName;
937     }
938 
939     @Override
940     public void setVendorName(String vendorName) {
941         this.vendorName = vendorName;
942     }
943 
944     @Override
945     public String getVendorPostalCode() {
946         return vendorPostalCode;
947     }
948 
949     @Override
950     public void setVendorPostalCode(String vendorPostalCode) {
951         this.vendorPostalCode = vendorPostalCode;
952     }
953 
954     @Override
955     public String getVendorStateCode() {
956         return vendorStateCode;
957     }
958 
959     @Override
960     public void setVendorStateCode(String vendorStateCode) {
961         this.vendorStateCode = vendorStateCode;
962     }
963 
964     @Override
965     public String getVendorAddressInternationalProvinceName() {
966         return vendorAddressInternationalProvinceName;
967     }
968 
969     @Override
970     public void setVendorAddressInternationalProvinceName(String vendorAddressInternationalProvinceName) {
971         this.vendorAddressInternationalProvinceName = vendorAddressInternationalProvinceName;
972     }
973 
974     @Override
975     public Integer getVendorAddressGeneratedIdentifier() {
976         return vendorAddressGeneratedIdentifier;
977     }
978 
979     @Override
980     public void setVendorAddressGeneratedIdentifier(Integer vendorAddressGeneratedIdentifier) {
981         this.vendorAddressGeneratedIdentifier = vendorAddressGeneratedIdentifier;
982     }
983 
984     @Override
985     public Integer getAccountsPayablePurchasingDocumentLinkIdentifier() {
986         return accountsPayablePurchasingDocumentLinkIdentifier;
987     }
988 
989     @Override
990     public void setAccountsPayablePurchasingDocumentLinkIdentifier(Integer accountsPayablePurchasingDocumentLinkIdentifier) {
991         this.accountsPayablePurchasingDocumentLinkIdentifier = accountsPayablePurchasingDocumentLinkIdentifier;
992     }
993 
994     @Override
995     public String[] getBelowTheLineTypes() {
996         if (this.belowTheLineTypes == null) {
997             this.belowTheLineTypes = SpringContext.getBean(PurapService.class).getBelowTheLineForDocument(this);
998         }
999         return belowTheLineTypes;
1000     }
1001 
1002     @Override
1003     public CountryEbo getVendorCountry() {
1004         if (StringUtils.isBlank(vendorCountryCode)) {
1005             vendorCountry = null;
1006         } else {
1007             if (vendorCountry == null || !StringUtils.equals(vendorCountry.getCode(), vendorCountryCode)) {
1008                 ModuleService moduleService = SpringContext.getBean(KualiModuleService.class).getResponsibleModuleService(CountryEbo.class);
1009                 if (moduleService != null) {
1010                     Map<String, Object> keys = new HashMap<String, Object>(1);
1011                     keys.put(LocationConstants.PrimaryKeyConstants.CODE, vendorCountryCode);
1012                     vendorCountry = moduleService.getExternalizableBusinessObject(CountryEbo.class, keys);
1013                 } else {
1014                     throw new RuntimeException("CONFIGURATION ERROR: No responsible module found for EBO class.  Unable to proceed.");
1015                 }
1016             }
1017         }
1018         return vendorCountry;
1019     }
1020 
1021     /**
1022      * Added only to allow for {@link org.kuali.ole.module.purap.util.PurApObjectUtils} class to work correctly.
1023      *
1024      * @deprecated
1025      */
1026     @Deprecated
1027     public void setVendorCountry(CountryEbo vendorCountry) {
1028         this.vendorCountry = vendorCountry;
1029     }
1030 
1031     public String getVendorAttentionName() {
1032         return vendorAttentionName;
1033     }
1034 
1035     public void setVendorAttentionName(String vendorAttentionName) {
1036         this.vendorAttentionName = vendorAttentionName;
1037     }
1038 
1039     /**
1040      * Gets the accountDistributionMethod attribute.
1041      *
1042      * @return Returns the accountDistributionMethod
1043      */
1044 
1045     public String getAccountDistributionMethod() {
1046         return accountDistributionMethod;
1047     }
1048 
1049     /**
1050      * Sets the accountDistributionMethod attribute.
1051      *
1052      * @param accountDistributionMethod The accountDistributionMethod to set.
1053      */
1054     public void setAccountDistributionMethod(String accountDistributionMethod) {
1055         this.accountDistributionMethod = accountDistributionMethod;
1056     }
1057 
1058     /**
1059      * Determines whether the account is debit. It always returns false.
1060      *
1061      * @param financialDocument The document containing the account to be validated.
1062      * @param accountingLine    The account to be validated.
1063      * @return boolean false.
1064      * @see org.kuali.ole.sys.document.validation.AccountingLineRule#isDebit(org.kuali.ole.sys.document.AccountingDocument,
1065      *      org.kuali.ole.sys.businessobject.AccountingLine)
1066      */
1067     @Override
1068     public boolean isDebit(GeneralLedgerPendingEntrySourceDetail postable) {
1069         return false;
1070     }
1071 
1072     public PurApRelatedViews getRelatedViews() {
1073         if (relatedViews == null) {
1074             relatedViews = new PurApRelatedViews(this.documentNumber, this.getAccountsPayablePurchasingDocumentLinkIdentifier());
1075         }
1076         return relatedViews;
1077     }
1078 
1079     public void setRelatedViews(PurApRelatedViews relatedViews) {
1080         this.relatedViews = relatedViews;
1081     }
1082 
1083     @Override
1084     public void refreshNonUpdateableReferences() {
1085         super.refreshNonUpdateableReferences();
1086 
1087         for (PurApItem item : (List<PurApItem>) this.getItems()) {
1088             //refresh the accounts if they do exist...
1089             for (PurApAccountingLine account : item.getSourceAccountingLines()) {
1090                 account.refreshNonUpdateableReferences();
1091             }
1092         }
1093 
1094         fixItemReferences();
1095     }
1096 
1097     /**
1098      * This method fixes the item references in this document if it's new
1099      */
1100     @Override
1101     public void fixItemReferences() {
1102         //fix item and account references in case this is a new doc (since they will be lost)
1103         if (ObjectUtils.isNull(this.purapDocumentIdentifier)) {
1104             for (PurApItem item : (List<PurApItem>) this.getItems()) {
1105                 item.setPurapDocument(this);
1106                 item.fixAccountReferences();
1107             }
1108         }
1109     }
1110 
1111     /**
1112      * Returns the trade in item of the document.
1113      *
1114      * @return
1115      */
1116     @Override
1117     public PurApItem getTradeInItem() {
1118         for (PurApItem item : (List<PurApItem>) getItems()) {
1119             if (item.getItemTypeCode().equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_TRADE_IN_CODE)) {
1120                 return item;
1121             }
1122         }
1123         return null;
1124     }
1125 
1126     /**
1127      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument.getIsATypeOfPurAPRecDoc().
1128      */
1129     @Override
1130     public boolean getIsATypeOfPurAPRecDoc() {
1131         return true;
1132     }
1133 
1134     /**
1135      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument.getIsATypeOfPurDoc().
1136      */
1137     @Override
1138     public boolean getIsATypeOfPurDoc() {
1139         if (this instanceof PurchasingDocumentBase) {
1140             return true;
1141         } else {
1142             return false;
1143         }
1144     }
1145 
1146     /**
1147      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument.getIsATypeOfPODoc().
1148      */
1149     @Override
1150     public boolean getIsATypeOfPODoc() {
1151         if (this instanceof PurchaseOrderDocument) {
1152             return true;
1153         } else {
1154             return false;
1155         }
1156     }
1157 
1158     /**
1159      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument.getIsPODoc().
1160      */
1161     @Override
1162     public boolean getIsPODoc() {
1163         if ((this instanceof PurchaseOrderDocument) &&
1164                 !(this instanceof PurchaseOrderAmendmentDocument) &&
1165                 !(this instanceof PurchaseOrderCloseDocument) &&
1166                 !(this instanceof PurchaseOrderPaymentHoldDocument) &&
1167                 !(this instanceof PurchaseOrderRemoveHoldDocument) &&
1168                 !(this instanceof PurchaseOrderReopenDocument) &&
1169                 !(this instanceof PurchaseOrderRetransmitDocument) &&
1170                 !(this instanceof PurchaseOrderSplitDocument) &&
1171                 !(this instanceof PurchaseOrderVoidDocument)) {
1172             return true;
1173         } else {
1174             return false;
1175         }
1176     }
1177 
1178     /**
1179      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument.getIsATypeOfREQSDoc().
1180      */
1181     @Override
1182     public boolean getIsReqsDoc() {
1183         if (this instanceof RequisitionDocument) {
1184             return true;
1185         } else {
1186             return false;
1187         }
1188     }
1189 
1190     /**
1191      * build document title based on the properties of current document
1192      *
1193      * @param the default document title
1194      * @return the combine information of the given title and additional payment indicators
1195      */
1196     protected String buildDocumentTitle(String title) {
1197         if (this.getVendorDetail() == null) {
1198             return title;
1199         }
1200 
1201         Integer vendorHeaderGeneratedIdentifier = this.getVendorDetail().getVendorHeaderGeneratedIdentifier();
1202         VendorService vendorService = SpringContext.getBean(VendorService.class);
1203 
1204         Object[] indicators = new String[2];
1205 
1206         boolean isEmployeeVendor = vendorService.isVendorInstitutionEmployee(vendorHeaderGeneratedIdentifier);
1207         indicators[0] = isEmployeeVendor ? AdHocPaymentIndicator.EMPLOYEE_VENDOR : AdHocPaymentIndicator.OTHER;
1208 
1209         boolean isVendorForeign = vendorService.isVendorForeign(vendorHeaderGeneratedIdentifier);
1210         indicators[1] = isVendorForeign ? AdHocPaymentIndicator.ALIEN_VENDOR : AdHocPaymentIndicator.OTHER;
1211 
1212         for (Object indicator : indicators) {
1213             if (!AdHocPaymentIndicator.OTHER.equals(indicator)) {
1214                 String titlePattern = title + " [{0}:{1}]";
1215                 return MessageFormat.format(titlePattern, indicators);
1216             }
1217         }
1218 
1219         return title;
1220     }
1221 
1222     /**
1223      * Overridden to return the source lines of all of the items
1224      *
1225      * @see org.kuali.ole.sys.document.AccountingDocumentBase#getSourceAccountingLines()
1226      */
1227     @SuppressWarnings("rawtypes")
1228     @Override
1229     public List getSourceAccountingLines() {
1230         if (ObjectUtils.isNotNull(sourceAccountingLines) && !sourceAccountingLines.isEmpty()) {
1231             // do nothing because acct lines have already been set
1232             return sourceAccountingLines;
1233         } else {
1234             /*
1235              * SpringContext.getBean(PurapAccountingService.class).updateAccountAmounts(this); return
1236              * SpringContext.getBean(PurapAccountingService.class).generateSummary(getItems());
1237             */
1238             List<AccountingLine> sourceAccountingLines = new ArrayList<AccountingLine>();
1239             for (Object itemAsObject : this.getItems()) {
1240                 final PurApItem item = (PurApItem) itemAsObject;
1241                 for (PurApAccountingLine accountingLine : item.getSourceAccountingLines()) {
1242                     // OLEMI-9053: check if the accounting line does not already exist in the list
1243                     // and if so then add to the list. Preventing duplicates
1244                     if (!isDuplicateAccountingLine(sourceAccountingLines, accountingLine)) {
1245                         sourceAccountingLines.add(accountingLine);
1246                     }
1247                 }
1248             }
1249             return sourceAccountingLines;
1250         }
1251     }
1252 
1253     /**
1254      * Helper method to check if the source accounting line is already in the list and if so return true
1255      *
1256      * @param sourceAccountingLines
1257      * @param accountingLine
1258      * @return true if it is a duplicate else return false.
1259      */
1260     protected boolean isDuplicateAccountingLine(List<AccountingLine> sourceAccountingLines,
1261                                                 PurApAccountingLine accountingLine) {
1262         for (AccountingLine sourceLine : sourceAccountingLines) {
1263             PurApAccountingLine purapAccountLine = (PurApAccountingLine) sourceLine;
1264 
1265             if (purapAccountLine.accountStringsAreEqual(accountingLine)) {
1266                 return true;
1267             }
1268         }
1269         return false;
1270     }
1271 
1272     /**
1273      * Helper method to find the matching accountingLines in the list of sourceAccountingLines and sum up the lines amounts.
1274      *
1275      * @param accountingLine
1276      * @return accountTotalGLEntryAmount
1277      */
1278     protected KualiDecimal getAccountTotalGLEntryAmount(AccountingLine matchingAccountingLine) {
1279         KualiDecimal accountTotalGLEntryAmount = KualiDecimal.ZERO;
1280 
1281         for (Object itemAsObject : this.getItems()) {
1282             final PurApItem item = (PurApItem) itemAsObject;
1283             for (PurApAccountingLine accountingLine : item.getSourceAccountingLines()) {
1284                 // OLEMI-9053: check if the accounting line is a duplicate then add the total
1285                 if (accountingLine.accountStringsAreEqual((SourceAccountingLine) matchingAccountingLine)) {
1286                     accountTotalGLEntryAmount = accountTotalGLEntryAmount.add(accountingLine.getAmount());
1287                 }
1288             }
1289         }
1290 
1291         return accountTotalGLEntryAmount;
1292     }
1293 
1294     /**
1295      * Checks whether the related purchase order views need a warning to be displayed, i.e. if at least one of the purchase orders
1296      * has never been opened.
1297      *
1298      * @return true if at least one related purchase order needs a warning; false otherwise
1299      */
1300     public boolean getNeedWarningRelatedPOs() {
1301         List<PurchaseOrderView> poViews = getRelatedViews().getRelatedPurchaseOrderViews();
1302         for (PurchaseOrderView poView : poViews) {
1303             if (poView.getNeedWarning()) {
1304                 return true;
1305             }
1306         }
1307         return false;
1308     }
1309 
1310     /**
1311      * Accounting lines that are read-only should skip validation
1312      *
1313      * @see org.kuali.ole.sys.document.AccountingDocumentBase#getPersistedSourceAccountingLinesForComparison()
1314      */
1315     @SuppressWarnings("rawtypes")
1316     @Override
1317     protected List getPersistedSourceAccountingLinesForComparison() {
1318         LOG.debug("Checking persisted source accounting lines for read-only fields");
1319         List<String> restrictedItemTypesList = new ArrayList<String>();
1320         try {
1321             restrictedItemTypesList = new ArrayList<String>(SpringContext.getBean(ParameterService.class).getParameterValuesAsString(this.getClass(), PurapParameterConstants.PURAP_ITEM_TYPES_RESTRICTING_ACCOUNT_EDIT));
1322         } catch (IllegalArgumentException iae) {
1323             // do nothing, not a problem if no restricted types are defined
1324         }
1325 
1326         PurapAccountingService purApAccountingService = SpringContext.getBean(PurapAccountingService.class);
1327         List persistedSourceLines = new ArrayList();
1328 
1329         for (PurApItem item : (List<PurApItem>) this.getItems()) {
1330             // only check items that already have been persisted since last save
1331             if (ObjectUtils.isNotNull(item.getItemIdentifier())) {
1332                 // Disable validation if the item is read-only
1333                 final boolean isNotReadOnly = !((restrictedItemTypesList != null) && restrictedItemTypesList.contains(item.getItemTypeCode()));
1334                 if (isNotReadOnly) {
1335                     persistedSourceLines.addAll(purApAccountingService.getAccountsFromItem(item));
1336                 }
1337             }
1338         }
1339         return persistedSourceLines;
1340     }
1341 
1342     /**
1343      * Accounting lines that are read-only should skip validation
1344      *
1345      * @see org.kuali.ole.sys.document.AccountingDocumentBase#getSourceAccountingLinesForComparison()
1346      */
1347     @SuppressWarnings("rawtypes")
1348     @Override
1349     protected List getSourceAccountingLinesForComparison() {
1350         LOG.debug("Checking source accounting lines for read-only fields");
1351         List<String> restrictedItemTypesList = new ArrayList<String>();
1352         try {
1353             restrictedItemTypesList = new ArrayList<String>(SpringContext.getBean(ParameterService.class).getParameterValuesAsString(this.getClass(), PurapParameterConstants.PURAP_ITEM_TYPES_RESTRICTING_ACCOUNT_EDIT));
1354         } catch (IllegalArgumentException iae) {
1355             // do nothing, not a problem if no restricted types are defined
1356         }
1357         PurapAccountingService purApAccountingService = SpringContext.getBean(PurapAccountingService.class);
1358         List currentSourceLines = new ArrayList();
1359         for (PurApItem item : (List<PurApItem>) this.getItems()) {
1360             // Disable validation if the item is read-only
1361             final boolean isNotReadOnly = !((restrictedItemTypesList != null) && restrictedItemTypesList.contains(item.getItemTypeCode()));
1362             if (isNotReadOnly) {
1363                 currentSourceLines.addAll(item.getSourceAccountingLines());
1364             }
1365         }
1366         return currentSourceLines;
1367     }
1368 
1369     /**
1370      * Gets the statusCode attribute.
1371      *
1372      * @return Returns the statusCode
1373      */
1374 
1375     public String getStatusCode() {
1376         return statusCode;
1377     }
1378 
1379     /**
1380      * Sets the statusCode attribute.
1381      *
1382      * @param statusCode The statusCode to set.
1383      */
1384     public void setStatusCode(String statusCode) {
1385         this.statusCode = statusCode;
1386     }
1387 
1388     /**
1389      * Gets the calculated attribute.
1390      *
1391      * @return Returns the calculated
1392      */
1393 
1394     @Override
1395     public boolean isCalculated() {
1396         return calculated;
1397     }
1398 
1399     /**
1400      * Sets the calculated attribute.
1401      *
1402      * @param calculated The calculated to set.
1403      */
1404     @Override
1405     public void setCalculated(boolean calculated) {
1406         this.calculated = calculated;
1407     }
1408 
1409     /**
1410      * @return
1411      */
1412     public BigDecimal getPurchaseOrderTypeId() {
1413         return purchaseOrderTypeId;
1414     }
1415 
1416     public void setPurchaseOrderTypeId(BigDecimal purchaseOrderTypeId) {
1417         this.purchaseOrderTypeId = purchaseOrderTypeId;
1418     }
1419 
1420     public void setPurchaseOrderTypeId(String purchaseOrderType) {
1421         Map orderTypeMap = new HashMap();
1422         String orderType = null;
1423         if (purchaseOrderType.equalsIgnoreCase("firm_fixed_ybp")) {
1424             orderType = PurapConstants.ORDER_TYPE_FIRM;
1425         } else if (purchaseOrderType.equalsIgnoreCase("standing")) {
1426             orderType = PurapConstants.ORDER_TYPE_STANDING;
1427             ;
1428         } else if (purchaseOrderType.equalsIgnoreCase("approval")) {
1429             orderType = PurapConstants.ORDER_TYPE_APPROVAL;
1430             ;
1431         } else if (purchaseOrderType.equalsIgnoreCase("subscription")) {
1432             orderType = PurapConstants.ORDER_TYPE_SUBSCRIPTION;
1433             ;
1434         }
1435 
1436         if (orderType != null) {
1437             orderTypeMap.put("purchaseOrderType", orderType);
1438             Collection<PurchaseOrderType> purchaseOrderTypeCollection = getBusinessObjectService().findMatching(PurchaseOrderType.class, orderTypeMap);
1439             for (PurchaseOrderType purchaseOrderTypeValue : purchaseOrderTypeCollection) {
1440                 BigDecimal id = purchaseOrderTypeValue.getPurchaseOrderTypeId();
1441                 this.purchaseOrderTypeId = id;
1442             }
1443         } else {
1444             this.purchaseOrderTypeId = new BigDecimal(purchaseOrderType);
1445         }
1446 
1447     }
1448 
1449 
1450     public PurchaseOrderType getOrderType() {
1451         return orderType;
1452     }
1453 
1454     public void setOrderType(PurchaseOrderType orderType) {
1455         this.orderType = orderType;
1456     }
1457 
1458     /*public boolean isLicensingRequirementIndicator() {
1459         return licensingRequirementIndicator;
1460     }
1461 
1462     public void setLicensingRequirementIndicator(boolean licensingRequirementIndicator) {
1463         this.licensingRequirementIndicator = licensingRequirementIndicator;
1464     }*/
1465 
1466    /* public String getLicensingRequirementCode() {
1467         return licensingRequirementCode;
1468     }
1469 
1470     public void setLicensingRequirementCode(String licensingRequirementCode) {
1471         this.licensingRequirementCode = licensingRequirementCode;
1472     }*/
1473 
1474 
1475    /* public OleLicensingRequirement getLicenseReqmt() {
1476         return licenseReqmt;
1477     }
1478 
1479     public void setLicenseReqmt(OleLicensingRequirement licenseReqmt) {
1480         this.licenseReqmt = licenseReqmt;
1481     }*/
1482 
1483     /*@Override
1484     public void setLicenseRequestDocNum(String licenseRequestDocNum) {
1485         this.licenseRequestDocNum = licenseRequestDocNum;
1486     }*/
1487 
1488     /**
1489      * This method gets the licenseRequest document number for the corresponding requisition document
1490      *
1491      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument#getLicenseRequestDocnum()
1492      * @return licenseRequestDocNum
1493      */
1494     /*@Override
1495     public String getLicenseRequestDocNum() {
1496         String reqDocNum = "";
1497         String licenseRequestDocNum = "";
1498         if(this instanceof RequisitionDocument) {
1499             reqDocNum = this.getDocumentNumber();
1500         }
1501         try {
1502             *//*
1503              * OleWebServiceProvider oleWebServiceProvider = (OleWebServiceProvider)
1504              * GlobalResourceLoader.getService(OLEConstants.OLE_WEB_SERVICE_PROVIDER); OleLicenseRequestWebService
1505              * oleLicenseRequestWebService = (OleLicenseRequestWebService) oleWebServiceProvider.
1506              * getService("org.kuali.ole.select.document.service.OleLicenseRequestWebService", "oleLicenseRequestWebService",
1507              * getLicenseURL());
1508              *//*
1509             // String licenseRequestDocNum = oleLicenseRequestWebService.getLicenseRequestDocNumber(reqDocNum);
1510 
1511             // Modified for Jira OLE -3991
1512             if (reqDocNum != null || !reqDocNum.isEmpty()) {
1513                 Map docNum = new HashMap();
1514                 docNum.put(OLEConstants.LicenseRequest.REQUISITIONS_DOC_NUMBER, reqDocNum);
1515                 OleLicenseRequestDetails oleLicenseRequestDetails = new OleLicenseRequestDetails();
1516                 List<OleLicenseRequestDetails> oleLicenseRequestDetailsList = (List<OleLicenseRequestDetails>) getBusinessObjectService()
1517                         .findMatching(OleLicenseRequestDetails.class, docNum);
1518                 if (oleLicenseRequestDetailsList.size() > 0) {
1519                     oleLicenseRequestDetails = oleLicenseRequestDetailsList.get(0);
1520                     licenseRequestDocNum = oleLicenseRequestDetails.getLicenseRequestDocNumber() != null
1521                             && !oleLicenseRequestDetails.getLicenseRequestDocNumber().isEmpty() ? oleLicenseRequestDetails
1522                             .getLicenseRequestDocNumber() : "";
1523                 }
1524 
1525             }
1526             return licenseRequestDocNum;
1527         } catch ( Exception ex ) {
1528             LOG.error( "Unable to access OleLicenseRequestWebService @ URL: " + getLicenseURL() + " for document # " + reqDocNum, ex );
1529             return "";
1530         }
1531     }*/
1532 
1533     /**
1534      * This method returns the licenserequest web service url
1535      *
1536      * @return url
1537      */
1538     public String getLicenseURL() {
1539         return ConfigContext.getCurrentContextConfig().getProperty("license.web.service.url");
1540 
1541         //	String environment = SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(OLEConstants.ENVIRONMENT_KEY);
1542         //    String url  = SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(environment + "."+OLEConstants.LICENSE_WEB_SERVICE_URL);
1543         //    return url;
1544     }
1545 
1546     public void setOleUrlResolver(OleUrlResolver oleUrlResolver) {
1547         this.oleUrlResolver = oleUrlResolver;
1548     }
1549 
1550 
1551     @Override
1552     public NoteType getNoteType() {
1553         return NoteType.BUSINESS_OBJECT;
1554     }
1555 }