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