001/*
002 * Copyright 2011 The Kuali Foundation.
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.ole.select.document;
017
018import org.apache.commons.lang.ArrayUtils;
019import org.apache.commons.lang.StringEscapeUtils;
020import org.apache.commons.lang.StringUtils;
021import org.kuali.ole.docstore.common.client.DocstoreClientLocator;
022import org.kuali.ole.docstore.common.document.Bib;
023import org.kuali.ole.docstore.common.document.BibMarc;
024import org.kuali.ole.DocumentUniqueIDPrefix;
025import org.kuali.ole.gl.service.SufficientFundsService;
026import org.kuali.ole.module.purap.PurapConstants;
027import org.kuali.ole.module.purap.PurapConstants.InvoiceStatuses;
028import org.kuali.ole.module.purap.PurapParameterConstants;
029import org.kuali.ole.module.purap.PurapPropertyConstants;
030import org.kuali.ole.module.purap.PurapWorkflowConstants;
031import org.kuali.ole.module.purap.businessobject.*;
032import org.kuali.ole.module.purap.document.InvoiceDocument;
033import org.kuali.ole.module.purap.document.PurchaseOrderDocument;
034import org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument;
035import org.kuali.ole.module.purap.document.service.AccountsPayableService;
036import org.kuali.ole.module.purap.document.service.InvoiceService;
037import org.kuali.ole.module.purap.document.service.PurapService;
038import org.kuali.ole.module.purap.document.validation.event.AttributedContinuePurapEvent;
039import org.kuali.ole.module.purap.service.PurapAccountingService;
040import org.kuali.ole.module.purap.util.ExpiredOrClosedAccountEntry;
041import org.kuali.ole.module.purap.util.SummaryAccount;
042import org.kuali.ole.select.OleSelectConstant;
043import org.kuali.ole.select.bo.OLELinkPurapDonor;
044import org.kuali.ole.select.businessobject.*;
045import org.kuali.ole.select.document.service.OleInvoiceService;
046import org.kuali.ole.select.document.service.impl.OleInvoiceFundCheckServiceImpl;
047import org.kuali.ole.select.form.OLEInvoiceForm;
048import org.kuali.ole.select.service.BibInfoService;
049import org.kuali.ole.select.service.BibInfoWrapperService;
050import org.kuali.ole.select.service.FileProcessingService;
051import org.kuali.ole.select.service.impl.BibInfoServiceImpl;
052import org.kuali.ole.sys.OLEConstants;
053import org.kuali.ole.sys.OLEPropertyConstants;
054import org.kuali.ole.sys.businessobject.Bank;
055import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntry;
056import org.kuali.ole.sys.businessobject.SourceAccountingLine;
057import org.kuali.ole.sys.businessobject.SufficientFundsItem;
058import org.kuali.ole.sys.context.SpringContext;
059import org.kuali.ole.sys.service.BankService;
060import org.kuali.ole.sys.service.GeneralLedgerPendingEntryService;
061import org.kuali.ole.sys.service.UniversityDateService;
062import org.kuali.ole.vnd.VendorConstants;
063import org.kuali.ole.vnd.businessobject.OleCurrencyType;
064import org.kuali.ole.vnd.businessobject.OleExchangeRate;
065import org.kuali.ole.vnd.businessobject.VendorAddress;
066import org.kuali.ole.vnd.document.service.VendorService;
067import org.kuali.rice.core.api.config.property.ConfigContext;
068import org.kuali.rice.core.api.config.property.ConfigurationService;
069import org.kuali.rice.core.api.datetime.DateTimeService;
070import org.kuali.rice.core.api.util.type.KualiDecimal;
071import org.kuali.rice.coreservice.framework.parameter.ParameterService;
072import org.kuali.rice.kew.api.KewApiConstants;
073import org.kuali.rice.kew.api.KewApiServiceLocator;
074import org.kuali.rice.kew.api.WorkflowDocument;
075import org.kuali.rice.kew.api.action.ActionRequestType;
076import org.kuali.rice.kew.api.action.ActionTaken;
077import org.kuali.rice.kew.api.action.RoutingReportCriteria;
078import org.kuali.rice.kew.api.exception.WorkflowException;
079import org.kuali.rice.kew.framework.postprocessor.DocumentRouteLevelChange;
080import org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange;
081import org.kuali.rice.kim.api.identity.Person;
082import org.kuali.rice.kim.api.identity.PersonService;
083import org.kuali.rice.kim.api.identity.principal.Principal;
084import org.kuali.rice.kim.api.services.IdentityManagementService;
085import org.kuali.rice.kim.api.services.KimApiServiceLocator;
086import org.kuali.rice.krad.bo.Note;
087import org.kuali.rice.krad.document.Copyable;
088import org.kuali.rice.krad.exception.ValidationException;
089import org.kuali.rice.krad.rules.rule.event.DocumentEvent;
090import org.kuali.rice.krad.rules.rule.event.DocumentEventBase;
091import org.kuali.rice.krad.service.BusinessObjectService;
092import org.kuali.rice.krad.service.DocumentService;
093import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
094import org.kuali.rice.krad.util.GlobalVariables;
095import org.kuali.rice.krad.util.ObjectUtils;
096import org.kuali.rice.krad.workflow.service.WorkflowDocumentService;
097
098import java.math.BigDecimal;
099import java.math.RoundingMode;
100import java.util.*;
101
102/**
103 * This class is the document class for Ole Payment Request
104 */
105
106public class OleInvoiceDocument extends InvoiceDocument implements Copyable {
107
108    private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(OleInvoiceDocument.class);
109
110    private Integer invoiceTypeId;
111    private Integer invoiceSubTypeId;
112    private String vendorId;
113    private String invoiceTypeHdnId;
114    private String invoiceSubTypeHdnId;
115    private String acquisitionUnit;
116    private String empty;
117    protected transient List<SummaryAccount> summaryAccounts;
118    private boolean sfcFlag;
119    private String invoiceItemTotal;
120    private String invoiceForeignItemTotal;
121    private String invoiceAmount;
122    private boolean baSfcFlag;
123    private boolean validationFlag;
124    private boolean blanketApproveValidationFlag;
125    private boolean blanketApproveSubscriptionDateValidationFlag;
126    private boolean subscriptionDateValidationFlag;
127    private String purchaseOrderDocumentNums;
128    private boolean duplicateApproveFlag = false;
129    private boolean blanketApproveFlag=true;
130    private boolean overviewFlag = true;
131    private boolean vendorInfoFlag = true;
132    private boolean invoiceInfoFlag = true;
133    private boolean processItemFlag = false;
134    private boolean processTitlesFlag = false;
135    private boolean currentItemsFlag = false;
136
137
138    private boolean additionalChargesFlag = false;
139    private boolean accountSummaryFlag = false;
140    private boolean notesAndAttachmentFlag = false;
141    private boolean adHocRecipientsFlag = false;
142    private boolean routeLogFlag = false;
143    private boolean routeLogDisplayFlag = false;
144    private boolean unsaved = false;
145    private boolean canClose = false;
146
147    private String cloneDebitInvoice;
148    private boolean cloneFlag = false;
149    private boolean amountExceeds = false;
150    private String exceedsEncumbranceTitle;
151    private String exceedsEncumbranceExtendedCost;
152    private String exceedsEncumbranceListPrice;
153    private boolean amountExceedsForBlanketApprove;
154    private boolean itemSign;
155
156    private String vendorLink;
157    private boolean foreignCurrencyFlag=false;
158    private Long invoiceCurrencyTypeId;
159    private String invoiceCurrencyType;
160    private OleCurrencyType oleCurrencyType;
161    private boolean currencyOverrideFlag = false;
162    private String currencyOverrideMessage;
163    private String invoiceCurrencyExchangeRate;
164    private boolean dbRetrieval= false;
165    private boolean enableCurrentItems = false;
166    private String foreignVendorAmount;
167    private String foreignInvoiceAmount;
168
169    public boolean isBlanketApproveFlag() {
170        return blanketApproveFlag;
171    }
172    private boolean currencyTypeIndicator = true;
173
174    public void setBlanketApproveFlag(boolean blanketApproveFlag) {
175        this.blanketApproveFlag = blanketApproveFlag;
176    }
177
178    private List<OlePaymentRequestDocument> paymentRequestDocuments = new ArrayList<OlePaymentRequestDocument>();
179
180    public boolean isCanClose() {
181        return canClose;
182    }
183
184    public void setCanClose(boolean canClose) {
185        this.canClose = canClose;
186    }
187
188    public boolean isUnsaved() {
189        return unsaved;
190    }
191
192    public void setUnsaved(boolean unsaved) {
193        this.unsaved = unsaved;
194    }
195
196    private boolean duplicateFlag = false;
197
198
199    private BigDecimal priorTotal = new BigDecimal(0);
200
201    public String getAcquisitionUnit() {
202        return acquisitionUnit;
203    }
204
205    public void setAcquisitionUnit(String acquisitionUnit) {
206        this.acquisitionUnit = acquisitionUnit;
207    }
208
209    public BigDecimal getPriorTotal() {
210        return priorTotal;
211    }
212
213    public void setPriorTotal(BigDecimal priorTotal) {
214        this.priorTotal = priorTotal;
215    }
216
217    public String getEmpty() {
218        return empty;
219    }
220
221    public void setEmpty(String empty) {
222        this.empty = empty;
223    }
224
225    // NOT PERSISTED IN DB
226    //private String invoiceType;
227    // private String invoiceSubType;
228
229    // REFERENCE OBJECTS
230    private OleInvoiceSubType oleInvoiceSubType;
231    private OleInvoiceType oleInvoiceType;
232
233    // Prorating Additional charges
234    private boolean prorateQty;
235    private boolean prorateDollar;
236    private boolean prorateManual;
237    private boolean noProrate;
238
239    private String prorateBy;
240
241    private BigDecimal foreignVendorInvoiceAmount;
242
243    private BigDecimal purchaseOrderTypeId;
244    private PurchaseOrderType orderType;
245    private static transient BibInfoService bibInfoService;
246    private String paymentMethodIdentifier;
247    private Integer paymentMethodId;
248    private OlePaymentMethod paymentMethod;
249    private String vendorFaxNumber;
250
251    protected Integer accountsPayablePurchasingDocumentLinkIdentifier;
252    protected List<PurchasingAccountsPayableDocument> purchaseOrders;
253
254
255    private String invoicedGrandTotal;
256    private String invoicedItemTotal;
257    //private boolean invoiceModified;
258    private String searchResultInvoiceDate;
259    private String searchResultInvoicePayDate;
260    private boolean offsetAccountIndicator;
261
262    public boolean isNoProrate() {
263        return noProrate;
264    }
265
266    public void setNoProrate(boolean noProrate) {
267        this.noProrate = noProrate;
268    }
269
270    @SuppressWarnings("rawtypes")
271    public List getPurchaseOrders() {
272        return purchaseOrders;
273    }
274
275    @SuppressWarnings("rawtypes")
276    public void setPurchaseOrders(List purchaseOrders) {
277        this.purchaseOrders = purchaseOrders;
278    }
279
280    public String getVendorFaxNumber() {
281        return vendorFaxNumber;
282    }
283
284    public void setVendorFaxNumber(String vendorFaxNumber) {
285        this.vendorFaxNumber = vendorFaxNumber;
286    }
287
288    public String getPaymentMethodIdentifier() {
289        return paymentMethodIdentifier;
290    }
291
292    public void setPaymentMethodIdentifier(String paymentMethodIdentifier) {
293        this.paymentMethodIdentifier = paymentMethodIdentifier;
294    }
295
296    public String getVendorId() {
297        return vendorId;
298    }
299
300    public void setVendorId(String vendorId) {
301        this.vendorId = vendorId;
302    }
303
304    public String getInvoiceSubTypeHdnId() {
305        return invoiceSubTypeHdnId;
306    }
307
308    public void setInvoiceSubTypeHdnId(String invoiceSubTypeHdnId) {
309        this.invoiceSubTypeHdnId = invoiceSubTypeHdnId;
310    }
311
312    //Overview
313    private String documentYear;
314    private String documentTotalAmount;
315
316    //Additional Items
317    /*List<OLEInvoiceAdditionalItem> additionalItems = new ArrayList<OLEInvoiceAdditionalItem>();*/
318
319    public String getDocumentYear() {
320        return documentYear;
321    }
322
323    public void setDocumentYear(String documentYear) {
324        this.documentYear = documentYear;
325    }
326
327    public String getDocumentTotalAmount() {
328        if (!isDbRetrieval()) {
329            this.documentTotalAmount = this.getTotalDollarAmount().toString();
330        }
331        return documentTotalAmount;
332        //return this.getTotalDollarAmount().toString();
333    }
334
335    public void setDocumentTotalAmount(String documentTotalAmount) {
336        this.documentTotalAmount = documentTotalAmount;
337    }
338
339    /*public List<OLEInvoiceAdditionalItem> getAdditionalItems() {
340        return additionalItems;
341    }
342
343    public void setAdditionalItems(List<OLEInvoiceAdditionalItem> additionalItems) {
344        this.additionalItems = additionalItems;
345    }*/
346
347    private List<OlePurchaseOrderItem> purchaseOrderItems = new ArrayList<OlePurchaseOrderItem>();
348
349
350    public List<OlePurchaseOrderItem> getPurchaseOrderItems() {
351        return purchaseOrderItems;
352    }
353
354    public void setPurchaseOrderItems(List<OlePurchaseOrderItem> purchaseOrderItems) {
355        this.purchaseOrderItems = purchaseOrderItems;
356    }
357
358    public Integer getPaymentMethodId() {
359        return paymentMethodId;
360    }
361
362    public void setPaymentMethodId(Integer paymentMethodId) {
363        this.paymentMethodId = paymentMethodId;
364    }
365
366    public OlePaymentMethod getPaymentMethod() {
367        return paymentMethod;
368    }
369
370    public void setPaymentMethod(OlePaymentMethod paymentMethod) {
371        this.paymentMethod = paymentMethod;
372    }
373
374    public static BibInfoService getBibInfoService() {
375        if (bibInfoService == null) {
376            bibInfoService = SpringContext.getBean(BibInfoServiceImpl.class);
377        }
378        return bibInfoService;
379    }
380
381    @Override
382    public BigDecimal getPurchaseOrderTypeId() {
383        return purchaseOrderTypeId;
384    }
385
386    @Override
387    public void setPurchaseOrderTypeId(BigDecimal purchaseOrderTypeId) {
388        this.purchaseOrderTypeId = purchaseOrderTypeId;
389    }
390
391    @Override
392    public PurchaseOrderType getOrderType() {
393        return orderType;
394    }
395
396    @Override
397    public Integer getAccountsPayablePurchasingDocumentLinkIdentifier() {
398        return accountsPayablePurchasingDocumentLinkIdentifier;
399    }
400
401    @Override
402    public void setAccountsPayablePurchasingDocumentLinkIdentifier(Integer accountsPayablePurchasingDocumentLinkIdentifier) {
403        this.accountsPayablePurchasingDocumentLinkIdentifier = accountsPayablePurchasingDocumentLinkIdentifier;
404    }
405
406    @Override
407    public void setOrderType(PurchaseOrderType orderType) {
408        this.orderType = orderType;
409    }
410
411    public Integer getInvoiceTypeId() {
412        return invoiceTypeId;
413    }
414
415    public void setInvoiceTypeId(Integer invoiceTypeId) {
416        this.invoiceTypeId = invoiceTypeId;
417    }
418
419    public String getInvoiceTypeHdnId() {
420        return invoiceTypeHdnId;
421    }
422
423    public void setInvoiceTypeHdnId(String invoiceTypeHdnId) {
424        this.invoiceTypeHdnId = invoiceTypeHdnId;
425    }
426
427    public Integer getInvoiceSubTypeId() {
428        return invoiceSubTypeId;
429    }
430
431    public void setInvoiceSubTypeId(Integer invoiceSubTypeId) {
432        this.invoiceSubTypeId = invoiceSubTypeId;
433    }
434
435    public String getInvoiceType() {
436        return invoiceType;
437    }
438
439    public void setInvoiceType(String invoiceType) {
440        this.invoiceType = invoiceType;
441    }
442
443
444    public String getInvoiceSubType() {
445        return invoiceSubType;
446    }
447
448    public void setInvoiceSubType(String invoiceSubType) {
449        this.invoiceSubType = invoiceSubType;
450    }
451
452    public OleInvoiceSubType getOleInvoiceSubType() {
453        return oleInvoiceSubType;
454    }
455
456    public void setOleInvoiceSubType(OleInvoiceSubType oleInvoiceSubType) {
457        this.oleInvoiceSubType = oleInvoiceSubType;
458    }
459
460    public OleInvoiceType getOleInvoiceType() {
461        return oleInvoiceType;
462    }
463
464    public void setOleInvoiceType(OleInvoiceType oleInvoiceType) {
465        this.oleInvoiceType = oleInvoiceType;
466    }
467
468    public boolean isProrateQty() {
469        return prorateQty;
470    }
471
472    public void setProrateQty(boolean prorateQty) {
473        this.prorateQty = prorateQty;
474    }
475
476    public boolean isProrateDollar() {
477        return prorateDollar;
478    }
479
480    public void setProrateDollar(boolean prorateDollar) {
481        this.prorateDollar = prorateDollar;
482    }
483
484    public boolean isProrateManual() {
485        return prorateManual;
486    }
487
488    public void setProrateManual(boolean prorateManual) {
489        this.prorateManual = prorateManual;
490    }
491
492    public boolean isAmountExceeds() {
493        return amountExceeds;
494    }
495
496    public void setAmountExceeds(boolean amountExceeds) {
497        this.amountExceeds = amountExceeds;
498    }
499
500    public String getExceedsEncumbranceTitle() {
501        return exceedsEncumbranceTitle;
502    }
503
504    public void setExceedsEncumbranceTitle(String exceedsEncumbranceTitle) {
505        this.exceedsEncumbranceTitle = exceedsEncumbranceTitle;
506    }
507
508    public String getExceedsEncumbranceExtendedCost() {
509        return exceedsEncumbranceExtendedCost;
510    }
511
512    public void setExceedsEncumbranceExtendedCost(String exceedsEncumbranceExtendedCost) {
513        this.exceedsEncumbranceExtendedCost = exceedsEncumbranceExtendedCost;
514    }
515
516    public String getExceedsEncumbranceListPrice() {
517        return exceedsEncumbranceListPrice;
518    }
519
520    public void setExceedsEncumbranceListPrice(String exceedsEncumbranceListPrice) {
521        this.exceedsEncumbranceListPrice = exceedsEncumbranceListPrice;
522    }
523
524    public boolean isAmountExceedsForBlanketApprove() {
525        return amountExceedsForBlanketApprove;
526    }
527
528    public void setAmountExceedsForBlanketApprove(boolean amountExceedsForBlanketApprove) {
529        this.amountExceedsForBlanketApprove = amountExceedsForBlanketApprove;
530    }
531
532    private static transient ConfigurationService kualiConfigurationService;
533    private static transient BibInfoWrapperService bibInfoWrapperService;
534    private static transient FileProcessingService fileProcessingService;
535    private static transient BusinessObjectService businessObjectService;
536    private static transient VendorService vendorService;
537    private static transient InvoiceService invoiceService;
538    private static transient OleInvoiceService oleInvoiceService;
539    private static transient PurapService purapService;
540    private static transient AccountsPayableService accountsPayableService;
541    private static transient IdentityManagementService identityManagementService;
542    private static transient WorkflowDocumentService workflowDocumentService;
543
544    //Proforma
545    private boolean proformaIndicator;
546
547    public static WorkflowDocumentService getWorkflowDocumentService() {
548        if (workflowDocumentService == null) {
549            workflowDocumentService = SpringContext.getBean(WorkflowDocumentService.class);
550        }
551        return workflowDocumentService;
552    }
553
554    public static void setWorkflowDocumentService(WorkflowDocumentService workflowDocumentService) {
555        OleInvoiceDocument.workflowDocumentService = workflowDocumentService;
556    }
557
558    public static InvoiceService getInvoiceService() {
559        if (invoiceService == null) {
560            invoiceService = SpringContext.getBean(InvoiceService.class);
561        }
562        return invoiceService;
563    }
564
565    public static void setInvoiceService(InvoiceService invoiceService) {
566        OleInvoiceDocument.invoiceService = invoiceService;
567    }
568
569    public static VendorService getVendorService() {
570        if (vendorService == null) {
571            vendorService = SpringContext.getBean(VendorService.class);
572        }
573        return vendorService;
574    }
575
576    public static void setVendorService(VendorService vendorService) {
577        OleInvoiceDocument.vendorService = vendorService;
578    }
579
580    public static PurapService getPurapService() {
581        if (purapService == null) {
582            purapService = SpringContext.getBean(PurapService.class);
583        }
584        return purapService;
585    }
586
587    public static void setPurapService(PurapService purapService) {
588        OleInvoiceDocument.purapService = purapService;
589    }
590
591    public static OleInvoiceService getOleInvoiceService() {
592        if (oleInvoiceService == null) {
593            oleInvoiceService = SpringContext.getBean(OleInvoiceService.class);
594        }
595        return oleInvoiceService;
596    }
597
598    public static void setOleInvoiceService(OleInvoiceService oleInvoiceService) {
599        OleInvoiceDocument.oleInvoiceService = oleInvoiceService;
600    }
601
602    public static IdentityManagementService getIdentityManagementService() {
603        if (identityManagementService == null) {
604            identityManagementService = SpringContext.getBean(IdentityManagementService.class);
605        }
606        return identityManagementService;
607    }
608
609    public static void setIdentityManagementService(IdentityManagementService identityManagementService) {
610        OleInvoiceDocument.identityManagementService = identityManagementService;
611    }
612
613    public static AccountsPayableService getAccountsPayableService() {
614        if (accountsPayableService == null) {
615            accountsPayableService = SpringContext.getBean(AccountsPayableService.class);
616        }
617        return accountsPayableService;
618    }
619
620    public static void setAccountsPayableService(AccountsPayableService accountsPayableService) {
621        OleInvoiceDocument.accountsPayableService = accountsPayableService;
622    }
623
624    public static ConfigurationService getConfigurationService() {
625        if (kualiConfigurationService == null) {
626            kualiConfigurationService = SpringContext.getBean(ConfigurationService.class);
627        }
628        return kualiConfigurationService;
629    }
630
631    public static void setConfigurationService(ConfigurationService kualiConfigurationService) {
632        OleInvoiceDocument.kualiConfigurationService = kualiConfigurationService;
633    }
634
635    public static BibInfoWrapperService getBibInfoWrapperService() {
636        if (bibInfoWrapperService == null) {
637            bibInfoWrapperService = SpringContext.getBean(BibInfoWrapperService.class);
638        }
639        return bibInfoWrapperService;
640    }
641
642    public static void setBibInfoWrapperService(BibInfoWrapperService bibInfoWrapperService) {
643        OleInvoiceDocument.bibInfoWrapperService = bibInfoWrapperService;
644    }
645
646
647    public static FileProcessingService getFileProcessingService() {
648        if (fileProcessingService == null) {
649            fileProcessingService = SpringContext.getBean(FileProcessingService.class);
650        }
651        return fileProcessingService;
652    }
653
654    public static void setFileProcessingService(FileProcessingService fileProcessingService) {
655        OleInvoiceDocument.fileProcessingService = fileProcessingService;
656    }
657
658    public static DateTimeService getDateTimeService() {
659        if (dateTimeService == null) {
660            dateTimeService = SpringContext.getBean(DateTimeService.class);
661        }
662        return dateTimeService;
663    }
664
665    public static void setDateTimeService(DateTimeService dateTimeService) {
666        OleInvoiceDocument.dateTimeService = dateTimeService;
667    }
668
669    @Override
670    public BusinessObjectService getBusinessObjectService() {
671        if (businessObjectService == null) {
672            businessObjectService = SpringContext.getBean(BusinessObjectService.class);
673        }
674        return businessObjectService;
675    }
676
677    public void setBusinessObjectService(BusinessObjectService businessObjectService) {
678        this.businessObjectService = businessObjectService;
679    }
680
681    /**
682     * Default constructor.
683     */
684    public OleInvoiceDocument() {
685        super();
686        /*this.setProrateBy(OLEConstants.PRORATE_BY_DOLLAR);
687        this.setProrateDollar(true);*/
688    }
689
690    public void initiateDocument() throws WorkflowException {
691        super.initiateDocument();
692        OleInvoiceItem item;
693        this.setUseTaxIndicator(false);
694        String[] collapseSections = getOleInvoiceService().getDefaultCollapseSections();
695        this.setOverviewFlag(getOleInvoiceService().canCollapse(OLEConstants.OVERVIEW_SECTION, collapseSections));
696        this.setVendorInfoFlag(getOleInvoiceService().canCollapse(OLEConstants.VENDOR_INFO_SECTION, collapseSections));
697        this.setInvoiceInfoFlag(getOleInvoiceService().canCollapse(OLEConstants.INVOICE_INFO_SECTION, collapseSections));
698        this.setProcessTitlesFlag(getOleInvoiceService().canCollapse(OLEConstants.PROCESS_TITLES_SECTION, collapseSections));
699        this.setCurrentItemsFlag(getOleInvoiceService().canCollapse(OLEConstants.CURRENT_ITEM_SECTION, collapseSections));
700        this.setAdditionalChargesFlag(getOleInvoiceService().canCollapse(OLEConstants.ADDITIONAL_CHARGES_SECTION, collapseSections));
701        this.setAccountSummaryFlag(getOleInvoiceService().canCollapse(OLEConstants.ACCOUNT_SUMMARY_SECTION, collapseSections));
702        this.setAdHocRecipientsFlag(getOleInvoiceService().canCollapse(OLEConstants.ADHOC_RECIPIENT_SECTION, collapseSections));
703        this.setRouteLogFlag(getOleInvoiceService().canCollapse(OLEConstants.ROUTE_LOG_SECTION, collapseSections));
704        this.setNotesAndAttachmentFlag(getOleInvoiceService().canCollapse(OLEConstants.NOTES_AND_ATTACH_SECTION, collapseSections));
705
706        if (this.getItems() == null || this.getItems().size() == 0) {
707            this.items = new ArrayList<>();
708            SpringContext.getBean(PurapService.class).addBelowLineItems(this);
709            List<OleInvoiceItem> oleInvItems = this.getItems();
710            for (OleInvoiceItem oleInvoiceItem : oleInvItems) {
711                oleInvoiceItem.setPostingYear(SpringContext.getBean(UniversityDateService.class).getCurrentUniversityDate().getUniversityFiscalYear());
712            }
713        }
714    }
715
716    /**
717     * This method is overridden to populate Ole InvoiceDocument from PurchaseOrder Document
718     *
719     * @see org.kuali.ole.module.purap.document.InvoiceDocument#populateInvoiceFromPurchaseOrder(org.kuali.ole.module.purap.document.PurchaseOrderDocument, java.util.HashMap)
720     */
721    @Override
722    public void populateInvoiceFromPurchaseOrder(PurchaseOrderDocument po, HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountList) {
723        LOG.debug("Inside populateInvoiceFromPurchaseOrder method of OleInvoice Document");
724        this.setPaymentMethodId(po.getVendorDetail().getPaymentMethodId());
725        this.setPurchaseOrderIdentifier(po.getPurapDocumentIdentifier());
726        this.getDocumentHeader().setOrganizationDocumentNumber(po.getDocumentHeader().getOrganizationDocumentNumber());
727        this.setPostingYear(po.getPostingYear());
728        this.setReceivingDocumentRequiredIndicator(po.isReceivingDocumentRequiredIndicator());
729        this.setUseTaxIndicator(po.isUseTaxIndicator());
730        this.setInvoicePositiveApprovalIndicator(po.isPaymentRequestPositiveApprovalIndicator());
731        this.setVendorCustomerNumber(po.getVendorCustomerNumber());
732
733        if (po.getPurchaseOrderCostSource() != null) {
734            this.setInvoiceCostSource(po.getPurchaseOrderCostSource());
735            this.setInvoiceCostSourceCode(po.getPurchaseOrderCostSourceCode());
736        }
737
738        if (po.getVendorShippingPaymentTerms() != null) {
739            this.setVendorShippingPaymentTerms(po.getVendorShippingPaymentTerms());
740            this.setVendorShippingPaymentTermsCode(po.getVendorShippingPaymentTermsCode());
741        }
742
743        if (po.getVendorPaymentTerms() != null) {
744            this.setVendorPaymentTermsCode(po.getVendorPaymentTermsCode());
745            this.setVendorPaymentTerms(po.getVendorPaymentTerms());
746        }
747
748        if (po.getRecurringPaymentType() != null) {
749            this.setRecurringPaymentType(po.getRecurringPaymentType());
750            this.setRecurringPaymentTypeCode(po.getRecurringPaymentTypeCode());
751        }
752
753        Bank defaultBank = SpringContext.getBean(BankService.class).getDefaultBankByDocType(this.getClass());
754        if (defaultBank != null) {
755            this.setBankCode(defaultBank.getBankCode());
756            this.setBank(defaultBank);
757        }
758        this.setVendorHeaderGeneratedIdentifier(po.getVendorHeaderGeneratedIdentifier());
759        this.setVendorDetailAssignedIdentifier(po.getVendorDetailAssignedIdentifier());
760        this.setVendorCustomerNumber(po.getVendorCustomerNumber());
761        this.setVendorName(po.getVendorName());
762
763        // set original vendor
764        this.setOriginalVendorHeaderGeneratedIdentifier(po.getVendorHeaderGeneratedIdentifier());
765        this.setOriginalVendorDetailAssignedIdentifier(po.getVendorDetailAssignedIdentifier());
766
767        // set alternate vendor info as well
768        this.setAlternateVendorHeaderGeneratedIdentifier(po.getAlternateVendorHeaderGeneratedIdentifier());
769        this.setAlternateVendorDetailAssignedIdentifier(po.getAlternateVendorDetailAssignedIdentifier());
770
771        // populate preq vendor address with the default remit address type for the vendor if found
772        String userCampus = GlobalVariables.getUserSession().getPerson().getCampusCode();
773        VendorAddress vendorAddress = getVendorService().getVendorDefaultAddress(po.getVendorHeaderGeneratedIdentifier(), po.getVendorDetailAssignedIdentifier(), VendorConstants.AddressTypes.REMIT, userCampus);
774        if (vendorAddress != null) {
775            this.templateVendorAddress(vendorAddress);
776            this.setVendorAddressGeneratedIdentifier(vendorAddress.getVendorAddressGeneratedIdentifier());
777            setVendorAttentionName(StringUtils.defaultString(vendorAddress.getVendorAttentionName()));
778        } else {
779            // set address from PO
780            this.setVendorAddressGeneratedIdentifier(po.getVendorAddressGeneratedIdentifier());
781            this.setVendorLine1Address(po.getVendorLine1Address());
782            this.setVendorLine2Address(po.getVendorLine2Address());
783            this.setVendorCityName(po.getVendorCityName());
784            this.setVendorAddressInternationalProvinceName(po.getVendorAddressInternationalProvinceName());
785            this.setVendorStateCode(po.getVendorStateCode());
786            this.setVendorPostalCode(po.getVendorPostalCode());
787            this.setVendorCountryCode(po.getVendorCountryCode());
788
789            boolean blankAttentionLine = StringUtils.equalsIgnoreCase(
790                    "Y",
791                    SpringContext.getBean(ParameterService.class).getParameterValueAsString(
792                            PurapConstants.PURAP_NAMESPACE, "Document",
793                            PurapParameterConstants.BLANK_ATTENTION_LINE_FOR_PO_TYPE_ADDRESS));
794
795            if (blankAttentionLine) {
796                setVendorAttentionName(StringUtils.EMPTY);
797            } else {
798                setVendorAttentionName(StringUtils.defaultString(po.getVendorAttentionName()));
799            }
800        }
801
802        this.setInvoicePayDate(getInvoiceService().calculatePayDate(this.getInvoiceDate(), this.getVendorPaymentTerms()));
803
804        if (getInvoiceService().encumberedItemExistsForInvoicing(po)) {
805            for (OlePurchaseOrderItem poi : (List<OlePurchaseOrderItem>) po.getItems()) {
806                // check to make sure it's eligible for payment (i.e. active and has encumbrance available
807                if (getDocumentSpecificService().poItemEligibleForAp(this, poi)) {
808                    OleInvoiceItem invoiceItem = new OleInvoiceItem(poi, this, expiredOrClosedAccountList);
809                    invoiceItem.setReceivingDocumentRequiredIndicator(po.isReceivingDocumentRequiredIndicator());
810                    this.getItems().add(invoiceItem);
811                    PurchasingCapitalAssetItem purchasingCAMSItem = po.getPurchasingCapitalAssetItemByItemIdentifier(poi.getItemIdentifier());
812                    if (purchasingCAMSItem != null) {
813                        invoiceItem.setCapitalAssetTransactionTypeCode(purchasingCAMSItem.getCapitalAssetTransactionTypeCode());
814                    }
815
816                    /*
817                    // copy usetaxitems over
818                    invoiceItem.getUseTaxItems().clear();
819                    for (PurApItemUseTax useTax : poi.getUseTaxItems()) {
820                        invoiceItem.getUseTaxItems().add(useTax);
821                    }
822                    */
823                }
824            }
825        }
826
827        // add missing below the line
828        getPurapService().addBelowLineItems(this);
829        this.setAccountsPayablePurchasingDocumentLinkIdentifier(po.getAccountsPayablePurchasingDocumentLinkIdentifier());
830
831        //fix up below the line items
832        getInvoiceService().removeIneligibleAdditionalCharges(this);
833
834        this.fixItemReferences();
835        this.refreshNonUpdateableReferences();
836    }
837
838    @Override
839    public Class getItemClass() {
840        return OleInvoiceItem.class;
841    }
842
843    @Override
844    public PurApAccountingLine getFirstAccount() {
845        // loop through items, and pick the first item
846        if ((getItems() != null) && (!getItems().isEmpty())) {
847            OleInvoiceItem itemToUse = null;
848            for (Iterator iter = getItems().iterator(); iter.hasNext(); ) {
849                OleInvoiceItem item = (OleInvoiceItem) iter.next();
850                if ((item.isConsideredEntered()) && ((item.getSourceAccountingLines() != null) && (!item.getSourceAccountingLines().isEmpty()))) {
851                    // accounting lines are not empty so pick the first account
852                    PurApAccountingLine accountLine = item.getSourceAccountingLine(0);
853                    accountLine.refreshNonUpdateableReferences();
854                    return accountLine;
855                }
856                /*
857                if (((item.getExtendedPrice() != null) && item.getExtendedPrice().compareTo(BigDecimal.ZERO) > 0) && ((item.getAccounts() != null) && (!item.getAccounts().isEmpty()))) {
858                    // accounting lines are not empty so pick the first account
859               List accts = (List)item.getAccounts();
860               InvoiceAccount accountLine = (InvoiceAccount)accts.get(0);
861                    return accountLine.getFinancialChartOfAccountsCode() + "-" + accountLine.getAccountNumber();
862                }
863                */
864            }
865        }
866        return null;
867
868    }
869
870    @Override
871    public PurApItem getItem(int pos) {
872        OleInvoiceItem item = (OleInvoiceItem) super.getItem(pos);
873        if (item.getInvoice() == null) {
874            item.setInvoice(this);
875        }
876        return item;
877    }
878
879   /* @Override
880    public void processAfterRetrieve() {
881        super.processAfterRetrieve();
882    }*/
883
884    public void loadInvoiceDocument() {
885    try {
886     //   super.processAfterRetrieve();
887        LOG.debug("###########inside OleInvoiceDocument processAfterRetrieve###########");
888
889        if (this.getPaymentMethodId() != null) {
890                OlePaymentMethod olePaymentMethod = KRADServiceLocatorWeb.getLegacyDataAdapter()
891                        .findBySinglePrimaryKey(OlePaymentMethod.class, this.getPaymentMethodId());
892                this.setPaymentMethod(olePaymentMethod);
893                this.setPaymentMethodIdentifier(this.getPaymentMethodId().toString());
894            }
895            if (this.getInvoiceTypeId() != null) {
896                this.setInvoiceTypeHdnId(this.getInvoiceTypeId().toString());
897            }
898            if (this.getInvoiceSubTypeId() != null) {
899                this.setInvoiceSubTypeHdnId(this.getInvoiceSubTypeId().toString());
900            }
901            if (this.getVendorInvoiceAmount() != null) {
902                this.setInvoiceAmount(this.getVendorInvoiceAmount().toString());
903            }
904        if (this.getForeignVendorInvoiceAmount() != null) {
905            this.setForeignInvoiceAmount(this.getForeignVendorInvoiceAmount().toString());
906        }
907            List<BigDecimal> newUnitPriceList = new ArrayList<BigDecimal>();
908            BigDecimal newUnitPrice = new BigDecimal(0);
909            BigDecimal hundred = new BigDecimal(100);
910            List<OleInvoiceItem> item = this.getItems();
911            String titleId = null;
912            //int itemCount = 0;
913            String itemDescription = "";
914        BigDecimal exchangeRate = new BigDecimal("0");
915        if (this.getInvoiceCurrencyTypeId() != null) {
916            OleCurrencyType oleCurrencyType = SpringContext.getBean(BusinessObjectService.class)
917                    .findBySinglePrimaryKey(OleCurrencyType.class, this.getInvoiceCurrencyTypeId());
918            this.setOleCurrencyType(oleCurrencyType);
919            this.setInvoiceCurrencyType(this.getInvoiceCurrencyTypeId().toString());
920            if ( oleCurrencyType.getCurrencyType().equalsIgnoreCase(OleSelectConstant.CURRENCY_TYPE_NAME) ){
921                currencyTypeIndicator=true;
922                this.setForeignCurrencyFlag(false);
923            } else {
924                currencyTypeIndicator=false;
925                this.setForeignCurrencyFlag(true);
926            }
927        } else {
928            if ( this.getVendorDetail() !=null && this.getVendorDetail().getCurrencyType() != null ){
929                if(this.getVendorDetail().getCurrencyType().getCurrencyType().equalsIgnoreCase(OleSelectConstant.CURRENCY_TYPE_NAME)){
930                    currencyTypeIndicator=true;
931                    this.setForeignCurrencyFlag(false);
932                    this.setInvoiceCurrencyType(this.getVendorDetail().getCurrencyType().getCurrencyTypeId().toString());
933                }
934                else{
935                    currencyTypeIndicator=false;
936                    this.setForeignCurrencyFlag(true);
937                    this.setInvoiceCurrencyType(this.getVendorDetail().getCurrencyType().getCurrencyTypeId().toString());
938                }
939            }
940        }
941
942        if (this.getInvoiceCurrencyTypeId() != null && (!currencyTypeIndicator) ){
943            if (StringUtils.isBlank(this.getInvoiceCurrencyExchangeRate())) {
944                exchangeRate = SpringContext.getBean(OleInvoiceService.class).getExchangeRate(this.getInvoiceCurrencyType()).getExchangeRate();
945                this.setInvoiceCurrencyExchangeRate(exchangeRate.toString());
946                //    items.setItemExchangeRate(new KualiDecimal(exchangeRate));
947                //    items.setExchangeRate(exchangeRate.toString());
948            }
949        }
950
951            for (int i = 0; item.size() > i; i++) {
952                OleInvoiceItem items = (OleInvoiceItem) this.getItem(i);
953            if (this.getInvoiceCurrencyTypeId() != null) {
954                items.setItemCurrencyType(oleCurrencyType.getCurrencyType());
955                items.setInvoicedCurrency(oleCurrencyType.getCurrencyType());
956            } else {
957                if (this.getVendorDetail() !=null && this.getVendorDetail().getCurrencyType() != null ){
958                    items.setItemCurrencyType(this.getVendorDetail().getCurrencyType().getCurrencyType());
959                    items.setInvoicedCurrency(this.getVendorDetail().getCurrencyType().getCurrencyType());
960                }
961            }
962
963            if (this.getInvoiceCurrencyTypeId() != null && (!currencyTypeIndicator) ){
964                if (StringUtils.isNotBlank(this.getInvoiceCurrencyExchangeRate())) {
965                    try {
966                        //          Double.parseDouble(this.getInvoiceCurrencyExchangeRate());
967                        items.setItemExchangeRate(new KualiDecimal(this.getInvoiceCurrencyExchangeRate()));
968                        items.setExchangeRate(this.getInvoiceCurrencyExchangeRate());
969                    }
970                    catch (NumberFormatException nfe) {
971                        throw new RuntimeException("Invalid Exchange Rate", nfe);
972                    }
973                }   else {
974                    items.setItemExchangeRate(new KualiDecimal(exchangeRate));
975                    items.setExchangeRate(exchangeRate.toString());
976                }
977                if (items.getItemExchangeRate() != null && items.getItemForeignUnitCost() != null) {
978                    items.setItemUnitCostUSD(new KualiDecimal(items.getItemForeignUnitCost().bigDecimalValue().divide(new BigDecimal(items.getExchangeRate()), 4, BigDecimal.ROUND_HALF_UP)));
979                    items.setItemUnitPrice(items.getItemForeignUnitCost().bigDecimalValue().divide(new BigDecimal(items.getExchangeRate()), 4, BigDecimal.ROUND_HALF_UP));
980                    items.setItemListPrice(items.getItemUnitCostUSD());
981                    items.setExtendedPrice(items.calculateExtendedPrice());
982                }
983                //this.setForeignVendorInvoiceAmount(this.getVendorInvoiceAmount().bigDecimalValue().multiply(tempOleExchangeRate.getExchangeRate()));
984            }
985
986                if (LOG.isDebugEnabled()) {
987                    LOG.debug("Title id while retriving ------>" + items.getItemTitleId());
988                }
989                if (items.getItemTitleId() != null) {
990                    DocstoreClientLocator docstoreClientLocator = new DocstoreClientLocator();
991                    Bib bib = new BibMarc();
992                    if (items.getItemTitleId() != null && items.getItemTitleId() != "") {
993                        bib = docstoreClientLocator.getDocstoreClient().retrieveBib(items.getItemTitleId());
994                    }
995                    items.setBibUUID(bib.getId());
996                    items.setDocFormat(DocumentUniqueIDPrefix.getBibFormatType(items.getItemTitleId()));
997
998                    itemDescription = ((bib.getTitle() != null && !bib.getTitle().isEmpty()) ? bib.getTitle().trim() + ", " : "")
999                            + ((bib.getAuthor() != null && !bib
1000                            .getAuthor().isEmpty()) ? bib.getAuthor().trim() + ", "
1001                            : "")
1002                            + ((bib.getPublisher() != null && !bib
1003                            .getPublisher().isEmpty()) ? bib.getPublisher().trim()
1004                            + ", " : "")
1005                            + ((bib.getIsbn() != null && !bib.getIsbn()
1006                            .isEmpty()) ? bib.getIsbn().trim() + ", " : "");
1007                    if (itemDescription != null && !(itemDescription.equals(""))) {
1008                        itemDescription = itemDescription.substring(0, itemDescription.lastIndexOf(","));
1009                        StringEscapeUtils stringEscapeUtils = new StringEscapeUtils();
1010                        itemDescription = stringEscapeUtils.unescapeXml(itemDescription);
1011                        items.setItemDescription(itemDescription);
1012                    }
1013                    HashMap<String, String> queryMap = new HashMap<String, String>();
1014                    if (items.getPoItemIdentifier() != null) {
1015                        queryMap.put(OLEConstants.OleCopy.PO_ITM_ID, items.getPoItemIdentifier().toString());
1016                        List<OLELinkPurapDonor> oleLinkPurapDonorList = (List<OLELinkPurapDonor>) KRADServiceLocatorWeb.getLegacyDataAdapter().findMatching(OLELinkPurapDonor.class, queryMap);
1017                        if (oleLinkPurapDonorList != null) {
1018                            items.setOleDonors(oleLinkPurapDonorList);
1019                        oleLinkPurapDonorList.clear();
1020                        }
1021                    }
1022                }
1023                if ((items.getItemType().isQuantityBasedGeneralLedgerIndicator())) {
1024                    if (items.getItemDiscount() == null) {
1025                        items.setItemDiscount(KualiDecimal.ZERO);
1026                    }
1027
1028                    if (items.getItemListPrice() == null) {
1029                        items.setItemListPrice(KualiDecimal.ZERO);
1030                    }
1031
1032                    /*   if (items.getItemDiscountType() != null && items.getItemDiscountType().equalsIgnoreCase(OleSelectConstant.DISCOUNT_TYPE_PERCENTAGE)) {
1033                       newUnitPrice = (hundred.subtract(items.getItemDiscount().bigDecimalValue())).divide(hundred).multiply(items.getItemListPrice().bigDecimalValue());
1034                   } else {
1035                       newUnitPrice = items.getItemListPrice().bigDecimalValue().subtract(items.getItemDiscount().bigDecimalValue());
1036                   }
1037                   items.setItemSurcharge(items.getItemUnitPrice().subtract(newUnitPrice).setScale(4, RoundingMode.HALF_UP));*/
1038                }
1039            }
1040            if (this.getVendorHeaderGeneratedIdentifier() != null && this.getVendorDetailAssignedIdentifier() != null) {
1041                this.setVendorId(this.getVendorHeaderGeneratedIdentifier().toString() + "-" + this.getVendorDetailAssignedIdentifier().toString());
1042            }
1043
1044            if (this.getProrateBy() != null) {
1045                this.setProrateQty(this.getProrateBy().equals(OLEConstants.PRORATE_BY_QTY));
1046                this.setProrateManual(this.getProrateBy().equals(OLEConstants.MANUAL_PRORATE));
1047                this.setProrateDollar(this.getProrateBy().equals(OLEConstants.PRORATE_BY_DOLLAR));
1048                this.setNoProrate(this.getProrateBy().equals(OLEConstants.NO_PRORATE));
1049            }
1050        } catch (Exception e) {
1051            LOG.error("Exception during processAfterRetrieve in OleInvoiceDocument "+e);
1052            throw new RuntimeException(e);
1053        }
1054    }
1055
1056    /**
1057     * This method is overrided to create POA from new Line Item of Invoice
1058     *
1059     * @see org.kuali.ole.module.purap.document.InvoiceDocument#doRouteStatusChange(org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange)
1060     */
1061    @Override
1062    public void doRouteStatusChange(DocumentRouteStatusChange statusChangeEvent) {
1063        LOG.debug("doRouteStatusChange() started");
1064
1065        super.doRouteStatusChange(statusChangeEvent);
1066        try {
1067            // DOCUMENT PROCESSED
1068            if (this.getDocumentHeader().getWorkflowDocument().isProcessed()) {
1069                if (!InvoiceStatuses.APPDOC_AUTO_APPROVED.equals(getApplicationDocumentStatus())) {
1070                    //delete unentered items and update po totals and save po
1071                    getOleInvoiceService().completePaymentDocument(this);
1072                    this.setApplicationDocumentStatus(PurapConstants.InvoiceStatuses.APPDOC_DEPARTMENT_APPROVED);
1073                    if (this.getImmediatePaymentIndicator()) {
1074                        this.setInvoicePayDate(new java.sql.Date(this.getAccountsPayableApprovalTimestamp().getTime()));
1075                    }
1076                    /*if(this.getImmediatePaymentIndicator()) {
1077                        this.setInvoicePayDate(new java.sql.Date(this.getAccountsPayableApprovalTimestamp().getTime()));
1078                    }*/
1079                    populateDocumentForRouting();
1080                    getPurapService().saveDocumentNoValidation(this);
1081                    SpringContext.getBean(OleInvoiceService.class).createPaymentRequestOrCreditMemoDocument(this);
1082                    //SpringContext.getBean(OleInvoiceService.class).createPaymentRequest(this);
1083                    return;
1084                }
1085            }
1086            /* else if (this.getFinancialSystemDocumentHeader().getWorkflowDocument().isFinal())  {
1087                if(this.getImmediatePaymentIndicator()) {
1088                    this.setInvoicePayDate(new java.sql.Date(this.getAccountsPayableApprovalTimestamp().getTime()));
1089                }
1090                SpringContext.getBean(OleInvoiceService.class).createPaymentRequestOrCreditMemoDocument(this);
1091            }*/
1092
1093            // DOCUMENT DISAPPROVED
1094            else if (this.getDocumentHeader().getWorkflowDocument().isDisapproved()) {
1095                // String nodeName =
1096                // getWorkflowDocumentService().getCurrentRouteLevelName(getDocumentHeader().getWorkflowDocument());
1097                String nodeName = getDocumentHeader().getWorkflowDocument().getCurrentNodeNames().iterator().next();
1098                HashMap<String, String> disApprovedStatusMap = PurapConstants.InvoiceStatuses
1099                        .getInvoiceAppDocDisapproveStatuses();
1100                // NodeDetails currentNode = NodeDetailEnum.getNodeDetailEnumByName(nodeName);
1101                // STATUS_ORDER currentNode = STATUS_ORDER.getByStatusCode(nodeName);
1102                if (ObjectUtils.isNotNull(nodeName)) {
1103                    String newStatusCode = disApprovedStatusMap.get(nodeName);
1104                    // currentNode.getDisapprovedStatusCode();
1105                    if ((StringUtils.isBlank(newStatusCode))
1106                            && ((InvoiceStatuses.APPDOC_INITIATE.equals(getApplicationDocumentStatus())) || (InvoiceStatuses.APPDOC_IN_PROCESS
1107                            .equals(getApplicationDocumentStatus())))) {
1108                        newStatusCode = InvoiceStatuses.APPDOC_CANCELLED_IN_PROCESS;
1109                    }
1110                    if (StringUtils.isNotBlank(newStatusCode)) {
1111                        getAccountsPayableService().cancelAccountsPayableDocument(this, nodeName);
1112                        return;
1113                    }
1114                }
1115                logAndThrowRuntimeException("No status found to set for document being disapproved in node '" + nodeName + "'");
1116            }
1117            // DOCUMENT CANCELED
1118            else if (this.getDocumentHeader().getWorkflowDocument().isCanceled()) {
1119                // String currentNodeName =
1120                // getWorkflowDocumentService().getCurrentRouteLevelName(this.getDocumentHeader().getWorkflowDocument());
1121                // NodeDetails currentNode = NodeDetailEnum.getNodeDetailEnumByName(currentNodeName);
1122                String nodeName = getDocumentHeader().getWorkflowDocument().getCurrentNodeNames().iterator().next();
1123                HashMap<String, String> disApprovedStatusMap = PurapConstants.InvoiceStatuses
1124                        .getInvoiceAppDocDisapproveStatuses();
1125                if (ObjectUtils.isNotNull(nodeName)) {
1126                    // String cancelledStatusCode = currentNode.getDisapprovedStatusCode();
1127                    String cancelledStatusCode = disApprovedStatusMap.get(nodeName);
1128                    if (StringUtils.isNotBlank(cancelledStatusCode)) {
1129                        this.setApplicationDocumentStatus(cancelledStatusCode);
1130                        getPurapService().saveDocumentNoValidation(this);
1131                        return;
1132                    }
1133                }
1134                logAndThrowRuntimeException("No status found to set for document being canceled in node '" + nodeName
1135                        + "'");
1136            }
1137        } catch (Exception e) {
1138            logAndThrowRuntimeException("Error saving routing data while saving document with id " + getDocumentNumber(), e);
1139        }
1140    }
1141
1142    /**
1143     * Sends FYI workflow request to the given user on this document.
1144     *
1145     * @param workflowDocument the associated workflow document.
1146     * @param userNetworkId    the network ID of the user to be sent to.
1147     * @param annotation       the annotation notes contained in this document.
1148     * @param responsibility   the responsibility specified in the request.
1149     * @throws org.kuali.rice.kew.api.exception.WorkflowException
1150     *
1151     */
1152    public void appSpecificRouteDocumentToUser(WorkflowDocument workflowDocument, String userNetworkId,
1153                                               String annotation, String responsibility) throws WorkflowException {
1154        if (ObjectUtils.isNotNull(workflowDocument)) {
1155            String annotationNote = (ObjectUtils.isNull(annotation)) ? "" : annotation;
1156            String responsibilityNote = (ObjectUtils.isNull(responsibility)) ? "" : responsibility;
1157            String currentNodeName = getCurrentRouteNodeName(workflowDocument);
1158            Principal principal = getIdentityManagementService().getPrincipalByPrincipalName(userNetworkId);
1159            workflowDocument.adHocToPrincipal(ActionRequestType.FYI, currentNodeName, annotationNote,
1160                    principal.getPrincipalId(), responsibilityNote, true);
1161        }
1162    }
1163
1164    /**
1165     * Returns the name of the current route node.
1166     *
1167     * @param wd the current workflow document.
1168     * @return the name of the current route node.
1169     * @throws org.kuali.rice.kew.api.exception.WorkflowException
1170     *
1171     */
1172    protected String getCurrentRouteNodeName(WorkflowDocument wd) throws WorkflowException {
1173        // String[] nodeNames = wd.getNodeNames();
1174        Set<String> nodeNameSet = wd.getNodeNames();
1175        String[] nodeNames = (String[]) nodeNameSet.toArray(); // Here it fails.
1176
1177        if ((nodeNames == null) || (nodeNames.length == 0)) {
1178            return null;
1179        } else {
1180            return nodeNames[0];
1181        }
1182    }
1183
1184    public BigDecimal getForeignVendorInvoiceAmount() {
1185        return foreignVendorInvoiceAmount;
1186    }
1187
1188    public void setForeignVendorInvoiceAmount(BigDecimal foreignVendorInvoiceAmount) {
1189        this.foreignVendorInvoiceAmount = foreignVendorInvoiceAmount;
1190    }
1191
1192    /**
1193     * This method is used to get the bibedtior creat url from propertie file
1194     *
1195     * @return Bibeditor creat url string
1196     */
1197    public String getBibeditorCreateURL() {
1198        String bibeditorCreateURL = getConfigurationService().getPropertyValueAsString(
1199                OLEConstants.BIBEDITOR_CREATE_URL_KEY);
1200        return bibeditorCreateURL;
1201    }
1202
1203    /**
1204     * This method is used to get the bibedtior edit url from propertie file
1205     *
1206     * @return Bibeditor edit url string
1207     */
1208    public String getBibeditorEditURL() {
1209        String bibeditorEditURL = getConfigurationService().getPropertyValueAsString(OLEConstants.BIBEDITOR_URL_KEY);
1210        return bibeditorEditURL;
1211    }
1212
1213    /**
1214     * This method is used to get the bibedtior view url from propertie file
1215     *
1216     * @return Bibeditor view url string
1217     */
1218    public String getBibeditorViewURL() {
1219        String bibeditorViewURL = getConfigurationService().getPropertyValueAsString(OLEConstants.DOCSTORE_APP_URL_KEY);
1220        return bibeditorViewURL;
1221    }
1222
1223    /**
1224     * This method is used to get the directory path where the marc xml files need to be created
1225     *
1226     * @return Directory path string
1227     */
1228    public String getMarcXMLFileDirLocation() throws Exception {
1229        String externaleDirectory = getFileProcessingService().getMarcXMLFileDirLocation();
1230        return externaleDirectory;
1231    }
1232
1233    @Override
1234    public void prepareForSave(DocumentEvent event) {
1235        // TODO Auto-generated method stub
1236        // first populate, then call super
1237        if (event instanceof AttributedContinuePurapEvent) {
1238            SpringContext.getBean(OleInvoiceService.class).populateInvoice(this);
1239        }
1240        if(this.getVendorPaymentTermsCode() != null && this.getVendorPaymentTermsCode().isEmpty()) {
1241            this.setVendorPaymentTermsCode(null);
1242        }
1243        super.prepareForSave(event);
1244        try {
1245            if (this.proformaIndicator && !this.immediatePaymentIndicator) {
1246                this.setImmediatePaymentIndicator(true);
1247            }
1248            LOG.debug("###########Inside OleInvoiceDocument " + "repareForSave###########");
1249            List<OleInvoiceItem> items = new ArrayList<OleInvoiceItem>();
1250            items = this.getItems();
1251            Iterator iterator = items.iterator();
1252            HashMap dataMap = new HashMap();
1253            String titleId;
1254            while (iterator.hasNext()) {
1255                LOG.debug("###########inside prepareForSave item loop###########");
1256                Object object = iterator.next();
1257                if (object instanceof OleInvoiceItem) {
1258                    LOG.debug("###########inside prepareForSave ole payment request item###########");
1259                    OleInvoiceItem singleItem = (OleInvoiceItem) object;
1260                    if (StringUtils.isNotBlank(this.invoiceCurrencyType)) {
1261                        this.setInvoiceCurrencyTypeId(new Long(this.getInvoiceCurrencyType()));
1262                        String currencyType = SpringContext.getBean(OleInvoiceService.class).getCurrencyType(this.getInvoiceCurrencyType());
1263                        if (StringUtils.isNotBlank(currencyType)) {
1264                            if(!currencyType.equalsIgnoreCase(OleSelectConstant.CURRENCY_TYPE_NAME)) {
1265                                if (StringUtils.isNotBlank(this.getInvoiceCurrencyExchangeRate())) {
1266                                    try {
1267                                        Double.parseDouble(this.getInvoiceCurrencyExchangeRate());
1268                                        singleItem.setItemExchangeRate(new KualiDecimal(this.getInvoiceCurrencyExchangeRate()));
1269                                        singleItem.setExchangeRate(this.getInvoiceCurrencyExchangeRate());
1270                                    }
1271                                    catch (NumberFormatException nfe) {
1272                                        throw new RuntimeException("Invalid Exchange Rate", nfe);
1273                                    }
1274                                }   else {
1275                                    BigDecimal exchangeRate = SpringContext.getBean(OleInvoiceService.class).getExchangeRate(this.getInvoiceCurrencyType()).getExchangeRate();
1276                                    this.setInvoiceCurrencyExchangeRate(exchangeRate.toString());
1277                                    singleItem.setItemExchangeRate(new KualiDecimal(exchangeRate));
1278                                    singleItem.setExchangeRate(exchangeRate.toString());
1279                                }
1280                                this.setVendorInvoiceAmount(this.getForeignVendorInvoiceAmount() != null ?
1281                                        new KualiDecimal(this.getForeignVendorInvoiceAmount().divide(new BigDecimal(singleItem.getExchangeRate()), 4, RoundingMode.HALF_UP)) : null);
1282                            }
1283                        }
1284                    }
1285                    setItemDescription(singleItem);
1286                    Map<String, String> copyCriteria = new HashMap<String, String>();
1287                    if (singleItem.getPaidCopies().size() <= 0 && singleItem.getPoItemIdentifier() != null && (this.getPurapDocumentIdentifier() != null && singleItem.getItemIdentifier() != null)) {
1288                        copyCriteria.put("poItemId", singleItem.getPoItemIdentifier().toString());
1289                        List<OleCopy> copies = (List<OleCopy>) KRADServiceLocatorWeb.getLegacyDataAdapter().findMatching(OleCopy.class, copyCriteria);
1290                        if (copies.size() > 0) {
1291                            List<OLEPaidCopy> paidCopies = new ArrayList<OLEPaidCopy>();
1292                            for (OleCopy copy : copies) {
1293                                OLEPaidCopy paidCopy = new OLEPaidCopy();
1294                                paidCopy.setCopyId(copy.getCopyId());
1295                                paidCopy.setInvoiceItemId(this.getPurapDocumentIdentifier());
1296                                paidCopy.setInvoiceIdentifier(singleItem.getItemIdentifier());
1297                                //copy.getOlePaidCopies().add(paidCopy);
1298                                paidCopies.add(paidCopy);
1299                            }
1300                            KRADServiceLocatorWeb.getLegacyDataAdapter().save(paidCopies);
1301                            singleItem.setPaidCopies(paidCopies);
1302                        }
1303                    }
1304                }
1305            }
1306        } catch (Exception e) {
1307            LOG.error("Exception during prepareForSave() in OleInvoiceDocument", e);
1308            throw new RuntimeException(e);
1309        }
1310    }
1311
1312    /* @Override
1313        public KualiDecimal getGrandTotal() {
1314            if ((this.prorateBy != null) && (this.prorateBy.equals(OLEConstants.PRORATE_BY_QTY) || this.prorateBy.equals(OLEConstants.PRORATE_BY_DOLLAR) || this.prorateBy.equals(OLEConstants.MANUAL_PRORATE))) {
1315                return this.getGrandPreTaxTotal().add(this.getGrandTaxAmount());
1316            } else {
1317                return super.getGrandTotal();
1318            }
1319        }
1320
1321        @Override
1322        public KualiDecimal getGrandTotalExcludingDiscount() {
1323            String[] discountCode = new String[]{PurapConstants.ItemTypeCodes.ITEM_TYPE_PMT_TERMS_DISCOUNT_CODE};
1324            if ((this.prorateBy != null)
1325                    && (this.prorateBy.equals(OLEConstants.PRORATE_BY_QTY)
1326                    || this.prorateBy.equals(OLEConstants.PRORATE_BY_DOLLAR) || this.prorateBy
1327                    .equals(OLEConstants.MANUAL_PRORATE))) {
1328                return this.getTotalDollarAmountWithExclusions(discountCode, false);
1329            } else {
1330                return this.getTotalDollarAmountWithExclusions(discountCode, true);
1331            }
1332        }
1333
1334        @Override
1335        public KualiDecimal getTotalDollarAmountAllItems(String[] excludedTypes) {
1336            if ((this.prorateBy != null)
1337                    && (this.prorateBy.equals(OLEConstants.PRORATE_BY_QTY)
1338                    || this.prorateBy.equals(OLEConstants.PRORATE_BY_DOLLAR) || this.prorateBy
1339                    .equals(OLEConstants.MANUAL_PRORATE))) {
1340                return getTotalDollarAmountWithExclusions(excludedTypes, false);
1341            } else {
1342                return getTotalDollarAmountWithExclusions(excludedTypes, true);
1343            }
1344        }
1345
1346        @Override
1347        public KualiDecimal getGrandPreTaxTotalExcludingDiscount() {
1348            String[] discountCode = new String[]{PurapConstants.ItemTypeCodes.ITEM_TYPE_PMT_TERMS_DISCOUNT_CODE};
1349            if ((this.prorateBy != null)
1350                    && (this.prorateBy.equals(OLEConstants.PRORATE_BY_QTY)
1351                    || this.prorateBy.equals(OLEConstants.PRORATE_BY_DOLLAR) || this.prorateBy
1352                    .equals(OLEConstants.MANUAL_PRORATE))) {
1353                return this.getTotalPreTaxDollarAmountWithExclusions(discountCode, false);
1354            } else {
1355                return this.getTotalPreTaxDollarAmountWithExclusions(discountCode, true);
1356            }
1357        }
1358
1359        @Override
1360        public KualiDecimal getGrandTaxAmountExcludingDiscount() {
1361            String[] discountCode = new String[]{PurapConstants.ItemTypeCodes.ITEM_TYPE_PMT_TERMS_DISCOUNT_CODE};
1362            if ((this.prorateBy != null)
1363                    && (this.prorateBy.equals(OLEConstants.PRORATE_BY_QTY)
1364                    || this.prorateBy.equals(OLEConstants.PRORATE_BY_DOLLAR) || this.prorateBy
1365                    .equals(OLEConstants.MANUAL_PRORATE))) {
1366                return this.getTotalTaxAmountWithExclusions(discountCode, false);
1367            } else {
1368                return this.getTotalTaxAmountWithExclusions(discountCode, true);
1369            }
1370        }
1371
1372        @Override
1373        public KualiDecimal getTotalPreTaxDollarAmountAllItems(String[] excludedTypes) {
1374            if ((this.prorateBy != null)
1375                    && (this.prorateBy.equals(OLEConstants.PRORATE_BY_QTY)
1376                    || this.prorateBy.equals(OLEConstants.PRORATE_BY_DOLLAR) || this.prorateBy
1377                    .equals(OLEConstants.MANUAL_PRORATE))) {
1378                return getTotalPreTaxDollarAmountWithExclusions(excludedTypes, false);
1379            } else {
1380                return getTotalPreTaxDollarAmountWithExclusions(excludedTypes, true);
1381            }
1382        }
1383
1384        @Override
1385        public KualiDecimal getTotalPreTaxDollarAmountAboveLineItems() {
1386            if ((this.prorateBy != null) && (this.prorateBy.equals(OLEConstants.PRORATE_BY_QTY) || this.prorateBy.equals(OLEConstants.PRORATE_BY_DOLLAR) || this.prorateBy.equals(OLEConstants.MANUAL_PRORATE))) {
1387                KualiDecimal addChargeItem = KualiDecimal.ZERO;
1388                KualiDecimal lineItemPreTaxTotal = KualiDecimal.ZERO;
1389                KualiDecimal prorateSurcharge = KualiDecimal.ZERO;
1390                List<OleInvoiceItem> item = this.getItems();
1391                for (OleInvoiceItem items : item) {
1392                    if (items.getItemType().isQuantityBasedGeneralLedgerIndicator() && items.getExtendedPrice() != null && items.getExtendedPrice().compareTo(KualiDecimal.ZERO) != 0) {
1393                        if (items.getItemSurcharge() != null) {
1394                            prorateSurcharge = new KualiDecimal(items.getItemSurcharge());
1395                        }
1396                        addChargeItem = addChargeItem.add(items.getExtendedPrice().subtract(prorateSurcharge.multiply(items.getItemQuantity())));
1397                    }
1398                }
1399                lineItemPreTaxTotal = addChargeItem;
1400                return lineItemPreTaxTotal;
1401            } else {
1402                return super.getTotalPreTaxDollarAmountAboveLineItems();
1403            }
1404        }
1405    */
1406
1407    /**
1408     * This method is used to check the status of the document for displaying view and edit buttons in line item
1409     *
1410     * @return boolean
1411     */
1412    public boolean getIsSaved() {
1413        if (this.getDocumentHeader().getWorkflowDocument().isSaved()
1414                || this.getDocumentHeader().getWorkflowDocument().isInitiated()) {
1415            return true;
1416        }
1417        return false;
1418    }
1419
1420    private void setItemDescription(OleInvoiceItem singleItem) throws Exception {
1421        if (singleItem.getOleOrderRecord() != null) {
1422            Map<String, ?> bibAssociatedFieldValuesMap = singleItem.getOleOrderRecord().getOleBibRecord().getBibAssociatedFieldsValueMap();
1423            List titleList = (List) bibAssociatedFieldValuesMap.get("Title_search");
1424            String title = titleList != null && !titleList.isEmpty() ? (String) (titleList).get(0) : null;
1425            List authorList = (List) bibAssociatedFieldValuesMap.get("Author_search");
1426            String author = authorList != null && !authorList.isEmpty() ? (String) (authorList).get(0) : null;
1427            List publisherList = (List) bibAssociatedFieldValuesMap.get("Publisher_search");
1428            String publisher = publisherList != null && !publisherList.isEmpty() ? (String) (publisherList).get(0) : null;
1429            List isbnList = (List) bibAssociatedFieldValuesMap.get("020a");
1430            String isbn = isbnList != null && !isbnList.isEmpty() ? (String) (isbnList).get(0) : null;
1431
1432            singleItem.setBibUUID(singleItem.getOleOrderRecord().getOleBibRecord().getBibUUID());
1433            singleItem.setItemDescription(title + "," + author + "," + publisher + "," + isbn);
1434        }
1435    }
1436
1437    public String getProrateBy() {
1438        return prorateBy;
1439    }
1440
1441    public void setProrateBy(String prorateBy) {
1442        this.prorateBy = prorateBy;
1443    }
1444
1445    /**
1446     * This method returns the boolean if the proforma indicator is selected
1447     *
1448     * @return proformaIndicator
1449     */
1450    public boolean isProformaIndicator() {
1451        return proformaIndicator;
1452    }
1453
1454    /**
1455     * This method sets the proforma Indicator
1456     *
1457     * @param proformaIndicator
1458     */
1459
1460    public void setProformaIndicator(boolean proformaIndicator) {
1461        this.proformaIndicator = proformaIndicator;
1462    }
1463
1464    /**
1465     * Payment Request needs to wait for receiving if the receiving requirements have NOT been met.
1466     *
1467     * @return
1468     */
1469    @Override
1470    protected boolean shouldWaitForReceiving() {
1471        // only require if PO was marked to require receiving
1472        Boolean invReceiveInd = false;
1473        //List<OleInvoiceItem> invItem = (List<OleInvoiceItem>) this.getItems();
1474        for (OleInvoiceItem invoiceItem : (List<OleInvoiceItem>) this.getItems()) {
1475            if (invoiceItem.isReceivingDocumentRequiredIndicator()) {
1476                invReceiveInd = true;
1477                break;
1478            }
1479        }
1480
1481
1482        if (invReceiveInd && !this.proformaIndicator) {
1483            return !isReceivingRequirementMet();
1484        }
1485
1486        //receiving is not required or has already been fulfilled, no need to stop for routing
1487        return false;
1488    }
1489
1490    /**
1491     * Provides answers to the following splits: PurchaseWasReceived VendorIsEmployeeOrNonResidentAlien
1492     *
1493     * @see org.kuali.ole.sys.document.FinancialSystemTransactionalDocumentBase#answerSplitNodeQuestion(String)
1494     */
1495    @Override
1496    public boolean answerSplitNodeQuestion(String nodeName) throws UnsupportedOperationException {
1497        if (nodeName.equals(OLEConstants.HAS_VENDOR_DEPOSIT_ACCOUNT)) {
1498            return hasVendorDepositAccount();
1499        }
1500        if (nodeName.equals(OLEConstants.OleInvoice.HAS_INVOICE_TYPE)) {
1501            return hasInvoiceType();
1502        }
1503        if (nodeName.equals(OLEConstants.OleInvoice.HAS_PREPAID_INVOICE_TYPE)) {
1504            return hasPrepaidInvoiceType();
1505        }
1506        if (nodeName.equals(OLEConstants.OleInvoice.HAS_PAYMENT_METHOD)) {
1507            return hasPaymentMethod();
1508        }
1509        if (nodeName.equals(PurapWorkflowConstants.BUDGET_REVIEW_REQUIRED)) {
1510            return isBudgetReviewRequired();
1511        }
1512        if (nodeName.equals(PurapWorkflowConstants.REQUIRES_IMAGE_ATTACHMENT)) {
1513            return requiresAccountsPayableReviewRouting();
1514        }
1515        if (nodeName.equals(PurapWorkflowConstants.PURCHASE_WAS_RECEIVED)) {
1516            return shouldWaitForReceiving();
1517        }
1518        if (nodeName.equals(PurapWorkflowConstants.VENDOR_IS_EMPLOYEE_OR_NON_RESIDENT_ALIEN)) {
1519            return isVendorEmployeeOrNonResidentAlien();
1520        }
1521        if (nodeName.equals(OLEConstants.REQUIRES_SEPARATION_OF_DUTIES)) {
1522            return isSeparationOfDutiesReviewRequired();
1523        }
1524
1525        if (nodeName.equals(PurapWorkflowConstants.NOTIFY_BUDGET_REVIEW)) {
1526            return isNotificationRequired();
1527        }
1528        throw new UnsupportedOperationException("Cannot answer split question for this node you call \"" + nodeName + "\"");
1529    }
1530
1531    private boolean hasInvoiceType() {
1532        if (this.getInvoiceTypeId() != null) {
1533            return true;
1534        }
1535        return false;
1536    }
1537
1538    private boolean hasVendorDepositAccount() {
1539        if (this.getPaymentMethodIdentifier() != null) {
1540            String paymentType = SpringContext.getBean(OleInvoiceService.class).getPaymentMethodType(this.getPaymentMethodIdentifier());
1541            if (paymentType.equals("Deposit")) {
1542                return true;
1543            }
1544        }
1545        return false;
1546    }
1547
1548    private boolean hasPrepaidInvoiceType() {
1549        if (this.getInvoiceTypeId() != null) {
1550            Map<String, String> invoiceMap = new HashMap<String, String>();
1551            invoiceMap.put("invoiceTypeId", this.getInvoiceTypeId().toString());
1552            OleInvoiceType invoiceType = KRADServiceLocatorWeb.getLegacyDataAdapter().findByPrimaryKey(OleInvoiceType.class,
1553                    invoiceMap);
1554            if (invoiceType != null &&
1555                    invoiceType.getInvoiceType().equals("Prepay") ||
1556                    invoiceType.getInvoiceType().equals("Deposit")) {
1557                return true;
1558            }
1559        }
1560        return false;
1561    }
1562
1563    private boolean hasPaymentMethod() {
1564        if (this.getPaymentMethodId() != null) {
1565            return true;
1566        }
1567        return false;
1568    }
1569
1570    public Set<Person> getAllPriorApprovers() throws WorkflowException {
1571        PersonService personService = KimApiServiceLocator.getPersonService();
1572        List<ActionTaken> actionsTaken = getDocumentHeader().getWorkflowDocument().getActionsTaken();
1573        Set<String> principalIds = new HashSet<String>();
1574        Set<Person> persons = new HashSet<Person>();
1575
1576        for (ActionTaken actionTaken : actionsTaken) {
1577            if (KewApiConstants.ACTION_TAKEN_APPROVED_CD.equals(actionTaken.getActionTaken())) {
1578                String principalId = actionTaken.getPrincipalId();
1579                if (!principalIds.contains(principalId)) {
1580                    principalIds.add(principalId);
1581                    persons.add(personService.getPerson(principalId));
1582                }
1583            }
1584        }
1585        return persons;
1586    }
1587
1588    protected boolean isSeparationOfDutiesReviewRequired() {
1589        try {
1590            Set<Person> priorApprovers = getAllPriorApprovers();
1591
1592            // The initiator cannot be the approver
1593            String initiatorPrincipalId = getDocumentHeader().getWorkflowDocument().getInitiatorPrincipalId();
1594            Person initiator = SpringContext.getBean(PersonService.class).getPerson(initiatorPrincipalId);
1595            // If there is only one approver, and that approver is also the initiator, then Separation of Duties is required.
1596            boolean priorApproverIsInitiator = priorApprovers.contains(initiator);
1597            boolean onlyOneApprover = (priorApprovers.size() == 1);
1598            if (priorApproverIsInitiator && onlyOneApprover) {
1599                return true;
1600            }
1601
1602            // if there are more than 0 prior approvers which means there had been at least another approver than the current approver
1603            // then no need for separation of duties
1604            if (priorApprovers.size() > 0) {
1605                return false;
1606            }
1607        } catch (WorkflowException we) {
1608            LOG.error("Exception while attempting to retrieve all prior approvers from workflow: " + we);
1609        }
1610        return false;
1611    }
1612
1613    public boolean isBudgetReviewRequired() {
1614
1615        OleInvoiceFundCheckServiceImpl oleInvoiceFundCheckServiceImpl = new OleInvoiceFundCheckServiceImpl();
1616        boolean required = false;
1617        if ((SpringContext.getBean(OleInvoiceService.class).getPaymentMethodType(this.getPaymentMethodIdentifier())).equals(OLEConstants.DEPOSIT)) {
1618            return false;
1619        }
1620        // if document's fiscal year is less than or equal to the current fiscal year
1621        if (SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear().compareTo(getPostingYear()) >= 0) {
1622            List<SourceAccountingLine> sourceAccountingLineList = this.getSourceAccountingLines();
1623            for (SourceAccountingLine accLine : sourceAccountingLineList) {
1624                String chart = accLine.getAccount().getChartOfAccountsCode();
1625                String account = accLine.getAccount().getAccountNumber();
1626                String sfCode = accLine.getAccount().getAccountSufficientFundsCode();
1627                Map<String, Object> key = new HashMap<String, Object>();
1628                key.put(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, chart);
1629                key.put(OLEPropertyConstants.ACCOUNT_NUMBER, account);
1630                OleSufficientFundCheck oleSufficientFundCheck = KRADServiceLocatorWeb.getLegacyDataAdapter().findByPrimaryKey(
1631                        OleSufficientFundCheck.class, key);
1632               /* List<GeneralLedgerPendingEntry> pendingEntries = getPendingLedgerEntriesForSufficientFundsChecking();
1633                for (GeneralLedgerPendingEntry glpe : pendingEntries) {
1634                    glpe.getChartOfAccountsCode();
1635                }*/
1636                SpringContext.getBean(GeneralLedgerPendingEntryService.class).generateGeneralLedgerPendingEntries(this);
1637                KRADServiceLocatorWeb.getLegacyDataAdapter().save(getGeneralLedgerPendingEntries());
1638
1639                if (oleSufficientFundCheck != null) {
1640                    String option = oleSufficientFundCheck.getNotificationOption() != null ? oleSufficientFundCheck
1641                            .getNotificationOption() : "";
1642                    if (option.equals(OLEPropertyConstants.BUD_REVIEW)) {
1643                        /*List<GeneralLedgerPendingEntry> pendingEntries = getPendingLedgerEntriesForSufficientFundsChecking();
1644                        for (GeneralLedgerPendingEntry glpe : pendingEntries) {
1645                            glpe.getChartOfAccountsCode();
1646                        }
1647                        SpringContext.getBean(GeneralLedgerPendingEntryService.class).generateGeneralLedgerPendingEntries(this);
1648                        KRADServiceLocatorWeb.getLegacyDataAdapter().save(getGeneralLedgerPendingEntries());*/
1649
1650                        required = oleInvoiceFundCheckServiceImpl.hasSufficientFundCheckRequired(accLine);
1651                        SpringContext.getBean(GeneralLedgerPendingEntryService.class).delete(getDocumentNumber());
1652/*                        SpringContext.getBean(GeneralLedgerPendingEntryService.class).delete(getDocumentNumber());*/
1653                        return required;
1654                    }
1655                }
1656            }
1657        }
1658        SpringContext.getBean(GeneralLedgerPendingEntryService.class).delete(getDocumentNumber());
1659        /*SpringContext.getBean(GeneralLedgerPendingEntryService.class).delete(getDocumentNumber());*/
1660        return required;
1661        // get list of sufficientfundItems
1662
1663        // delete and recreate the GL entries for this document so they do not get included in the SF check
1664        // This is *NOT* ideal. The SF service needs to be updated to allow it to provide the current
1665        // document number so that it can be exlcuded from pending entry checks.
1666        //   List<GeneralLedgerPendingEntry> pendingEntries = getPendingLedgerEntriesForSufficientFundsChecking();
1667        // dumb loop to just force OJB to load the objects. Otherwise, the proxy object above
1668        // only gets resolved *after* the delete below and no SF check happens.
1669        // for (GeneralLedgerPendingEntry glpe : pendingEntries) {
1670        // glpe.getChartOfAccountsCode();
1671        // }
1672        // SpringContext.getBean(GeneralLedgerPendingEntryService.class).delete(getDocumentNumber());
1673        // List<SufficientFundsItem> fundsItems = SpringContext.getBean(SufficientFundsService.class)
1674        //.checkSufficientFundsForPREQ(pendingEntries);
1675
1676        //if (fundsItems.size() > 0) {
1677        //return true;
1678        //}
1679
1680
1681        //return false;
1682    }
1683
1684    private boolean isNotificationRequired() {
1685        OleInvoiceFundCheckServiceImpl oleInvoiceFundCheckServiceImpl = new OleInvoiceFundCheckServiceImpl();
1686        if ((SpringContext.getBean(OleInvoiceService.class).getPaymentMethodType(this.getPaymentMethodIdentifier())).equals(OLEConstants.DEPOSIT)) {
1687            return false;
1688        }
1689        List<SourceAccountingLine> sourceAccountingLineList = this.getSourceAccountingLines();
1690        boolean sufficientFundCheck = false;
1691        for (SourceAccountingLine accLine : sourceAccountingLineList) {
1692            Map searchMap = new HashMap();
1693            String notificationOption = null;
1694            Map<String, Object> key = new HashMap<String, Object>();
1695            String chartCode = accLine.getChartOfAccountsCode();
1696            String accNo = accLine.getAccountNumber();
1697            String objectCd = accLine.getFinancialObjectCode();
1698            key.put(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, chartCode);
1699            key.put(OLEPropertyConstants.ACCOUNT_NUMBER, accNo);
1700            OleSufficientFundCheck account = KRADServiceLocatorWeb.getLegacyDataAdapter().findByPrimaryKey(
1701                    OleSufficientFundCheck.class, key);
1702            if (account != null) {
1703                notificationOption = account.getNotificationOption();
1704            }
1705            if (notificationOption != null && notificationOption.equals(OLEPropertyConstants.NOTIFICATION)) {
1706                sufficientFundCheck = oleInvoiceFundCheckServiceImpl.hasSufficientFundCheckRequired(accLine);
1707                return sufficientFundCheck;
1708            }
1709        }
1710        return sufficientFundCheck;
1711    }
1712
1713    @Override
1714    protected void populateAccountsForRouting() {
1715
1716        // if(this.getDocumentHeader().ge)
1717        List<SufficientFundsItem> fundsItems = new ArrayList<SufficientFundsItem>();
1718        try {
1719            // String nodeName =
1720            // SpringContext.getBean(WorkflowDocumentService.class).getCurrentRouteLevelName(getFinancialSystemDocumentHeader().getWorkflowDocument());
1721            String nodeName = getFinancialSystemDocumentHeader().getWorkflowDocument().getCurrentNodeNames().iterator()
1722                    .next();
1723            if (nodeName != null
1724                    && (nodeName.equalsIgnoreCase(PurapWorkflowConstants.BUDGET_NODE) || nodeName
1725                    .equalsIgnoreCase(PurapWorkflowConstants.BUDGET_REVIEW_REQUIRED))) {
1726                if (SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear()
1727                        .compareTo(getPostingYear()) >= 0) {
1728
1729                    SpringContext.getBean(GeneralLedgerPendingEntryService.class).generateGeneralLedgerPendingEntries(
1730                            this);
1731                    KRADServiceLocatorWeb.getLegacyDataAdapter().save(getGeneralLedgerPendingEntries());
1732
1733                    List<GeneralLedgerPendingEntry> pendingEntries = getPendingLedgerEntriesForSufficientFundsChecking();
1734                    for (GeneralLedgerPendingEntry glpe : pendingEntries) {
1735                        glpe.getChartOfAccountsCode();
1736                    }
1737
1738                    fundsItems = SpringContext.getBean(SufficientFundsService.class).checkSufficientFundsForInvoice(pendingEntries);
1739
1740/*
1741                    SpringContext.getBean(GeneralLedgerPendingEntryService.class).generateGeneralLedgerPendingEntries(
1742                            this);
1743                    KRADServiceLocatorWeb.getLegacyDataAdapter().save(getGeneralLedgerPendingEntries());
1744
1745                    fundsItems = SpringContext.getBean(SufficientFundsService.class).checkSufficientFundsForInvoice(
1746                            pendingEntries);
1747*/
1748
1749                }
1750                SpringContext.getBean(PurapAccountingService.class).updateAccountAmounts(this);
1751                if (accountsForRouting == null) {
1752                    accountsForRouting = (SpringContext.getBean(PurapAccountingService.class).generateSummary(getItems()));
1753                }
1754                String documentFiscalYearString = this.getPostingYear().toString();
1755                List<String> fundsItemList = new ArrayList<String>();
1756                for (SufficientFundsItem fundsItem : fundsItems) {
1757                    fundsItemList.add(fundsItem.getAccount().getChartOfAccountsCode());
1758                }
1759                if (accountsForRouting != null) {
1760                    for (Iterator accountsForRoutingIter = accountsForRouting.iterator(); accountsForRoutingIter.hasNext(); ) {
1761                        if (!(fundsItemList.contains(((SourceAccountingLine) accountsForRoutingIter.next())
1762                                .getChartOfAccountsCode()))) {
1763                            accountsForRoutingIter.remove();
1764                        }
1765                    }
1766
1767/*                SpringContext.getBean(GeneralLedgerPendingEntryService.class).delete(getDocumentNumber());*/
1768                    setAccountsForRouting(accountsForRouting);
1769                }
1770                // need to refresh to get the references for the searchable attributes (ie status) and for invoking route levels (ie
1771                // account
1772                // objects) -hjs
1773                refreshNonUpdateableReferences();
1774                for (SourceAccountingLine sourceLine : getAccountsForRouting()) {
1775                    sourceLine.refreshNonUpdateableReferences();
1776                }
1777            } else {
1778                super.populateAccountsForRouting();
1779            }
1780            SpringContext.getBean(GeneralLedgerPendingEntryService.class).delete(getDocumentNumber());
1781        } catch (Exception e) {
1782            logAndThrowRuntimeException("Error in populateAccountsForRouting while submitting document with id "
1783                    + getDocumentNumber(), e);
1784        }
1785
1786    }
1787
1788    /**
1789     * @see org.kuali.rice.krad.document.DocumentBase#doRouteLevelChange(org.kuali.rice.kew.framework.postprocessor.DocumentRouteLevelChange)
1790     */
1791    @Override
1792    public void doRouteLevelChange(DocumentRouteLevelChange levelChangeEvent) {
1793
1794        super.doRouteLevelChange(levelChangeEvent);
1795        try {
1796            String newNodeName = levelChangeEvent.getNewNodeName();
1797            List<String> desiredActions = new ArrayList<String>(2);
1798            RoutingReportCriteria.Builder reportCriteria = RoutingReportCriteria.Builder
1799                    .createByDocumentIdAndTargetNodeName(getDocumentNumber(), newNodeName);
1800            desiredActions.add(ActionRequestType.APPROVE.getCode());
1801            desiredActions.add(ActionRequestType.FYI.getCode());
1802            desiredActions.add(ActionRequestType.COMPLETE.getCode());
1803            if (KewApiServiceLocator.getWorkflowDocumentActionsService().documentWillHaveAtLeastOneActionRequest(
1804                    reportCriteria.build(), desiredActions, false)) {
1805                if (StringUtils.isNotBlank(newNodeName)) {
1806                    if (StringUtils.isNotBlank(newNodeName)) {
1807                        if (newNodeName.equalsIgnoreCase(PurapWorkflowConstants.BUDGET_NODE)
1808                                || newNodeName.equalsIgnoreCase(PurapWorkflowConstants.FYI_BUDGET)) {
1809                            String note = "";
1810                            if (newNodeName.equalsIgnoreCase(PurapWorkflowConstants.BUDGET_NODE)) {
1811                                note = OLEConstants.SufficientFundCheck.INV_NOTE;
1812                            }
1813                            if (newNodeName.equalsIgnoreCase(PurapWorkflowConstants.FYI_BUDGET)) {
1814                                note = OLEConstants.SufficientFundCheck.FYI_NOTE;
1815                            }
1816                            DocumentService documentService = SpringContext.getBean(DocumentService.class);
1817                            Note apoNote = documentService.createNoteFromDocument(this, note);
1818                            this.addNote(apoNote);
1819                            documentService.saveDocumentNotes(this);
1820                        }
1821                    }
1822                }
1823            }
1824        } catch (Exception e) {
1825            String errorMsg = "Workflow Error found checking actions requests on document with id "
1826                    + getDocumentNumber() + ". *** WILL NOT UPDATE PURAP STATUS ***";
1827            LOG.error(errorMsg, e);
1828        }
1829    }
1830
1831    private OleInvoiceDocument invoiceDocumentObject;
1832
1833    public OleInvoiceDocument getInvoiceDocumentObject() {
1834        return invoiceDocumentObject;
1835    }
1836
1837    public void setInvoiceDocumentObject(OleInvoiceDocument invoiceDocumentObject) {
1838        this.invoiceDocumentObject = invoiceDocumentObject;
1839    }
1840
1841
1842    private String invoiceNumber;
1843    //private String paymentAttachmentIndicator;
1844    private String invoicePaymentClassification;
1845    private String invoiceVendorAmount;
1846    private String invoiceExtractDate;
1847    private String invoiceProcessedDate;
1848    private String invoiceType;
1849    private String invoiceSubType;
1850    private String invoiceBankCode;
1851    //private Date invoicePayDate;
1852    private String invoicePayDateCheck;
1853    private String vendorAmount;
1854    private String itemTotal;
1855    private String foreignItemTotal;
1856    private String grantTotal;
1857    private String foreignGrandTotal;
1858
1859    private String invoicedForeignItemTotal;
1860    private String invoicedForeignGrandTotal;
1861
1862    public String getInvoicePayDateCheck() {
1863        return invoicePayDateCheck;
1864    }
1865
1866    public void setInvoicePayDateCheck(String invoicePayDateCheck) {
1867        this.invoicePayDateCheck = invoicePayDateCheck;
1868    }
1869
1870
1871    public String getInvoiceNumber() {
1872        return invoiceNumber;
1873    }
1874
1875    public void setInvoiceNumber(String invoiceNumber) {
1876        this.invoiceNumber = invoiceNumber;
1877    }
1878
1879
1880    public String getInvoicePaymentClassification() {
1881        return invoicePaymentClassification;
1882    }
1883
1884    public void setInvoicePaymentClassification(String invoicePaymentClassification) {
1885        this.invoicePaymentClassification = invoicePaymentClassification;
1886    }
1887
1888    public String getInvoiceVendorAmount() {
1889        return invoiceVendorAmount;
1890    }
1891
1892    public void setInvoiceVendorAmount(String invoiceVendorAmount) {
1893        this.invoiceVendorAmount = invoiceVendorAmount;
1894    }
1895
1896    public String getInvoiceExtractDate() {
1897        return invoiceExtractDate;
1898    }
1899
1900    public void setInvoiceExtractDate(String invoiceExtractDate) {
1901        this.invoiceExtractDate = invoiceExtractDate;
1902    }
1903
1904    public String getInvoiceProcessedDate() {
1905        return invoiceProcessedDate;
1906    }
1907
1908    public void setInvoiceProcessedDate(String invoiceProcessedDate) {
1909        this.invoiceProcessedDate = invoiceProcessedDate;
1910    }
1911
1912    public String getInvoiceBankCode() {
1913        return invoiceBankCode;
1914    }
1915
1916    public void setInvoiceBankCode(String invoiceBankCode) {
1917        this.invoiceBankCode = invoiceBankCode;
1918    }
1919
1920
1921    private String poId;
1922
1923    public String getPoId() {
1924        return poId;
1925    }
1926
1927    public void setPoId(String poId) {
1928        this.poId = poId;
1929    }
1930
1931
1932    public String getInvoiceCostSourceCode() {
1933        return invoiceCostSourceCode;
1934    }
1935
1936    public void setInvoiceCostSourceCode(String invoiceCostSourceCode) {
1937        this.invoiceCostSourceCode = invoiceCostSourceCode;
1938    }
1939
1940    public Integer getVendorHeaderGeneratedIdentifier() {
1941        return vendorHeaderGeneratedIdentifier;
1942    }
1943
1944    public void setVendorHeaderGeneratedIdentifier(Integer vendorHeaderGeneratedIdentifier) {
1945        this.vendorHeaderGeneratedIdentifier = vendorHeaderGeneratedIdentifier;
1946    }
1947
1948    public List<SummaryAccount> getSummaryAccounts() {
1949        if (summaryAccounts == null) {
1950            refreshAccountSummmary();
1951        }
1952        return summaryAccounts;
1953    }
1954
1955    public void setSummaryAccounts(List<SummaryAccount> summaryAccounts) {
1956        this.summaryAccounts = summaryAccounts;
1957    }
1958
1959    public void clearSummaryAccounts() {
1960        summaryAccounts = new ArrayList<SummaryAccount>();
1961    }
1962
1963    /**
1964     * Updates the summaryAccounts that are contained in the form. Currently we are only calling this on load and when
1965     * refreshAccountSummary is called.
1966     */
1967    public void refreshAccountSummmary() {
1968        clearSummaryAccounts();
1969        summaryAccounts.addAll(SpringContext.getBean(PurapAccountingService.class).generateSummaryAccounts(this));
1970    }
1971
1972    public boolean isSfcFlag() {
1973        return sfcFlag;
1974    }
1975
1976    public void setSfcFlag(boolean sfcFlag) {
1977        this.sfcFlag = sfcFlag;
1978    }
1979
1980    public String getInvoiceItemTotal() {
1981        // if (this.invoiceItemTotal == null || this.invoiceItemTotal.isEmpty() || this.invoiceItemTotal.equalsIgnoreCase("0.00")) {
1982        BigDecimal addChargeItem = BigDecimal.ZERO;
1983        List<OleInvoiceItem> item = this.getItems();
1984        for (OleInvoiceItem invoiceditem : item) {
1985            if (invoiceditem.getItemType().isAdditionalChargeIndicator() && invoiceditem.getExtendedPrice() != null) {
1986                addChargeItem = addChargeItem.add(invoiceditem.getExtendedPrice().bigDecimalValue());
1987            }
1988        }
1989        return (this.getTotalDollarAmount().subtract(new KualiDecimal(addChargeItem)).toString());
1990
1991        /* }
1992       return invoiceItemTotal;*/
1993    }
1994
1995    public void setInvoiceItemTotal(String invoiceItemTotal) {
1996        this.invoiceItemTotal = invoiceItemTotal;
1997    }
1998
1999    public String getInvoiceForeignItemTotal() {
2000        BigDecimal addChargeItem = BigDecimal.ZERO;
2001        List<OleInvoiceItem> item = this.getItems();
2002        for (OleInvoiceItem invoicedItem : item) {
2003            if (invoicedItem.getItemType().isAdditionalChargeIndicator() && invoicedItem.getItemUnitPrice() != null) {
2004                addChargeItem = addChargeItem.add(invoicedItem.getItemUnitPrice());
2005            }
2006        }
2007        return (this.getTotalDollarAmount().subtract(new KualiDecimal(addChargeItem)).toString());
2008    }
2009
2010    public void setInvoiceForeignItemTotal(String invoiceForeignItemTotal) {
2011        this.invoiceForeignItemTotal = invoiceForeignItemTotal;
2012    }
2013
2014    public String getVendorAmount() {
2015        if (vendorAmount != null && !vendorAmount.isEmpty()) {
2016            return vendorAmount;
2017        } else {
2018            vendorAmount = this.getInvoiceAmount();
2019            if (vendorAmount != null && vendorAmount.contains("-")) {
2020                vendorAmount = vendorAmount.replace("-", "");
2021                vendorAmount = "(" + vendorAmount + ")";
2022            }
2023            return vendorAmount;
2024        }
2025    }
2026
2027    public void setVendorAmount(String vendorAmount) {
2028        this.vendorAmount = vendorAmount;
2029        if (vendorAmount.contains("(") || vendorAmount.contains(")")) {
2030            vendorAmount = vendorAmount.replace("(", "");
2031            vendorAmount = vendorAmount.replace(")", "");
2032            vendorAmount = "-" + vendorAmount;
2033            this.vendorAmount = vendorAmount;
2034        }
2035        if (vendorAmount != null && new KualiDecimal(vendorAmount).isLessThan(KualiDecimal.ZERO)) {
2036            this.setInvoiceAmount(vendorAmount);
2037            vendorAmount = vendorAmount.replace("-", "");
2038            vendorAmount = "(" + vendorAmount + ")";
2039            this.vendorAmount = vendorAmount;
2040        } else {
2041            this.setInvoiceAmount(vendorAmount);
2042            this.vendorAmount = vendorAmount;
2043        }
2044    }
2045
2046    public String getForeignVendorAmount() {
2047        if (foreignVendorAmount != null && !foreignVendorAmount.isEmpty()) {
2048            return foreignVendorAmount;
2049        } else {
2050            foreignVendorAmount = this.getForeignVendorInvoiceAmount() != null ? this.getForeignVendorInvoiceAmount().toString() : null;
2051            if (foreignVendorAmount != null && foreignVendorAmount.contains("-")) {
2052                foreignVendorAmount = foreignVendorAmount.replace("-", "");
2053                foreignVendorAmount = "(" + foreignVendorAmount + ")";
2054            }
2055            return foreignVendorAmount;
2056        }
2057    }
2058
2059    public void setForeignVendorAmount(String foreignVendorAmount) {
2060        this.foreignVendorAmount = foreignVendorAmount;
2061        if (foreignVendorAmount.contains("(") || foreignVendorAmount.contains(")")) {
2062            foreignVendorAmount = foreignVendorAmount.replace("(", "");
2063            foreignVendorAmount = foreignVendorAmount.replace(")", "");
2064            foreignVendorAmount = "-" + foreignVendorAmount;
2065            this.foreignVendorAmount = foreignVendorAmount;
2066        }
2067        if (foreignVendorAmount != null && new KualiDecimal(foreignVendorAmount).isLessThan(KualiDecimal.ZERO)) {
2068            this.setForeignInvoiceAmount(foreignVendorAmount);
2069            foreignVendorAmount = foreignVendorAmount.replace("-", "");
2070            foreignVendorAmount = "(" + foreignVendorAmount + ")";
2071            this.foreignVendorAmount = foreignVendorAmount;
2072        } else {
2073            this.setForeignInvoiceAmount(foreignVendorAmount);
2074            this.foreignVendorAmount = foreignVendorAmount;
2075        }
2076    }
2077
2078    public String getForeignInvoiceAmount() {
2079        return foreignInvoiceAmount;
2080    }
2081
2082    public void setForeignInvoiceAmount(String foreignInvoiceAmount) {
2083        this.foreignInvoiceAmount = foreignInvoiceAmount;
2084    }
2085
2086    public String getInvoiceAmount() {
2087        return invoiceAmount;
2088    }
2089
2090    public void setInvoiceAmount(String invoiceAmount) {
2091        this.invoiceAmount = invoiceAmount;
2092    }
2093
2094    public boolean isBaSfcFlag() {
2095        return baSfcFlag;
2096    }
2097
2098    public void setBaSfcFlag(boolean baSfcFlag) {
2099        this.baSfcFlag = baSfcFlag;
2100    }
2101
2102    /**
2103     * This method calculates the grand Total
2104     *
2105     * @param includeBelowTheLine
2106     * @param itemsForTotal
2107     * @return
2108     */
2109    protected KualiDecimal getInvoicedTotalWithAllItems(boolean includeBelowTheLine, List<OleInvoiceItem> itemsForTotal) {
2110
2111        BigDecimal total = BigDecimal.ZERO;
2112        for (OleInvoiceItem item : itemsForTotal) {
2113            item.refreshReferenceObject(PurapPropertyConstants.ITEM_TYPE);
2114            ItemType it = item.getItemType();
2115            if (includeBelowTheLine || it.isLineItemIndicator()) {
2116                BigDecimal totalAmount = item.getInvoiceTotalAmount();
2117                BigDecimal itemTotal = (totalAmount != null) ? totalAmount : BigDecimal.ZERO;
2118                if (item.isDebitItem()) {
2119                    total = total.add(itemTotal);
2120                } else {
2121                    total = total.subtract(itemTotal);
2122                }
2123                /*if (item.getItemDiscount() != null) {
2124                    total = total.subtract(item.getItemDiscount());
2125                }*/
2126            }
2127        }
2128        return new KualiDecimal(total);
2129    }
2130
2131    protected KualiDecimal getInvoicedForeignTotalWithAllItems(boolean includeBelowTheLine, List<OleInvoiceItem> itemsForTotal) {
2132
2133        KualiDecimal total = new KualiDecimal(BigDecimal.ZERO);
2134        for (OleInvoiceItem item : itemsForTotal) {
2135            item.refreshReferenceObject(PurapPropertyConstants.ITEM_TYPE);
2136            ItemType it = item.getItemType();
2137            if (includeBelowTheLine || it.isLineItemIndicator()) {
2138                KualiDecimal totalAmount = item.getForeignTotalAmount();
2139                KualiDecimal itemTotal = (totalAmount != null) ? totalAmount : KualiDecimal.ZERO;
2140                if (item.isDebitItem()) {
2141                    total = total.add(itemTotal);
2142                } else {
2143                    total = total.subtract(itemTotal);
2144                }
2145            }
2146        }
2147        return total;
2148    }
2149
2150    public String getInvoicedItemTotal() {
2151        KualiDecimal total = getInvoicedTotalWithAllItems(false, this.getItems());
2152        if (this.isItemSign()) {
2153            if (total.isLessThan(KualiDecimal.ZERO)) {
2154                total = total;
2155            }
2156        }
2157        return total != null ? total.toString() : "0";
2158    }
2159
2160    public void setInvoicedItemTotal(String invoicedItemTotal) {
2161        this.invoicedItemTotal = invoicedItemTotal;
2162    }
2163
2164    public String getInvoicedForeignItemTotal() {
2165        KualiDecimal foreignItemTotal = getInvoicedForeignTotalWithAllItems(false, this.getItems());
2166       /* if (this.isItemSign()) {
2167            if (foreignItemTotal.isLessThan(KualiDecimal.ZERO)) {
2168                foreignItemTotal = foreignItemTotal;
2169            }
2170        } */
2171        return foreignItemTotal != null ? foreignItemTotal.toString() : "0";
2172    }
2173
2174    public void setInvoicedForeignItemTotal(String invoicedForeignItemTotal) {
2175        this.invoicedForeignItemTotal = invoicedForeignItemTotal;
2176    }
2177
2178    public String getItemTotal() {
2179        if(!this.isDbRetrieval()){
2180            itemTotal = this.getInvoicedItemTotal();
2181        }
2182        if (itemTotal != null && !itemTotal.contains("(")
2183                && new KualiDecimal(itemTotal).isLessThan(KualiDecimal.ZERO)) {
2184            itemTotal = itemTotal.replace("-", "");
2185            itemTotal = "(" + itemTotal + ")";
2186        }
2187        return itemTotal;
2188    }
2189
2190    public void setItemTotal(String itemTotal) {
2191        this.itemTotal = itemTotal;
2192    }
2193
2194    public String getForeignItemTotal() {
2195        if(!this.isDbRetrieval()){
2196            foreignItemTotal = this.getInvoicedForeignItemTotal();
2197        }
2198        if (foreignItemTotal != null && !foreignItemTotal.contains("(")
2199                && new KualiDecimal(foreignItemTotal).isLessThan(KualiDecimal.ZERO)) {
2200            foreignItemTotal = foreignItemTotal.replace("-", "");
2201            foreignItemTotal = "(" + foreignItemTotal + ")";
2202        }
2203        return foreignItemTotal;
2204    }
2205
2206    public void setForeignItemTotal(String foreignItemTotal) {
2207        this.foreignItemTotal = foreignItemTotal;
2208    }
2209
2210    public String getGrantTotal() {
2211        if(!this.isDbRetrieval()){
2212            grantTotal = this.getInvoicedGrandTotal();
2213        }
2214        if (grantTotal != null &&  !grantTotal.contains("(")
2215                && new KualiDecimal(grantTotal).isLessThan(KualiDecimal.ZERO)) {
2216            grantTotal = grantTotal.replace("-", "");
2217            grantTotal = "(" + grantTotal + ")";
2218        }
2219        return grantTotal;
2220    }
2221
2222    public void setGrantTotal(String grantTotal) {
2223        this.grantTotal = grantTotal;
2224    }
2225
2226    public String getForeignGrandTotal() {
2227        if(!this.isDbRetrieval()){
2228            foreignGrandTotal = this.getInvoicedForeignGrandTotal();
2229        }
2230        if (foreignGrandTotal != null &&  !foreignGrandTotal.contains("(")
2231                && new KualiDecimal(foreignGrandTotal).isLessThan(KualiDecimal.ZERO)) {
2232            foreignGrandTotal = foreignGrandTotal.replace("-", "");
2233            foreignGrandTotal = "(" + foreignGrandTotal + ")";
2234        }
2235        return foreignGrandTotal;
2236    }
2237
2238    public void setForeignGrandTotal(String foreignGrandTotal) {
2239        this.foreignGrandTotal = foreignGrandTotal;
2240    }
2241
2242    public String getInvoicedGrandTotal() {
2243        KualiDecimal total = getInvoicedTotalWithAllItems(true, this.getItems());
2244      /*  if (this.isItemSign()) {
2245            if (total.isLessThan(KualiDecimal.ZERO)) {
2246                total = total;
2247            }
2248        } */
2249        return total != null ? total.toString() : "0";
2250    }
2251
2252    public void setInvoicedGrandTotal(String invoicedGrandTotal) {
2253        this.invoicedGrandTotal = invoicedGrandTotal;
2254    }
2255
2256    public String getInvoicedForeignGrandTotal() {
2257        KualiDecimal total = getInvoicedForeignTotalWithAllItems(true, this.getItems());
2258       /* if (this.isItemSign()) {
2259            if (total.isLessThan(KualiDecimal.ZERO)) {
2260                total = total;
2261            }
2262        } */
2263        for (OleInvoiceItem item : (List<OleInvoiceItem>)this.getItems()) {
2264            if (!item.getItemType().getItemTypeCode().equalsIgnoreCase(PurapConstants.ItemTypeCodes.ITEM_TYPE_ITEM_CODE)
2265                    && item.getAdditionalForeignUnitCost() != null) {
2266                total = total.add(new KualiDecimal(item.getAdditionalForeignUnitCost()));
2267            }
2268            else if (!item.getItemType().getItemTypeCode().equalsIgnoreCase(PurapConstants.ItemTypeCodes.ITEM_TYPE_ITEM_CODE)
2269                    && item.getItemForeignUnitCost() != null) {
2270                total = total.add(item.getItemForeignUnitCost());
2271            }
2272        }
2273
2274        return total != null ? total.toString() : "0";
2275    }
2276    public void setInvoicedForeignGrandTotal(String invoicedForeignGrandTotal) {
2277        this.invoicedForeignGrandTotal = invoicedForeignGrandTotal;
2278    }
2279
2280    public boolean isValidationFlag() {
2281        return validationFlag;
2282    }
2283
2284    public void setValidationFlag(boolean validationFlag) {
2285        this.validationFlag = validationFlag;
2286    }
2287
2288    public boolean isBlanketApproveValidationFlag() {
2289        return blanketApproveValidationFlag;
2290    }
2291
2292    public void setBlanketApproveValidationFlag(boolean blanketApproveValidationFlag) {
2293        this.blanketApproveValidationFlag = blanketApproveValidationFlag;
2294    }
2295
2296    public String getPurchaseOrderDocumentNums() {
2297        return purchaseOrderDocumentNums;
2298    }
2299
2300    public void setPurchaseOrderDocumentNums(String purchaseOrderDocumentNums) {
2301        this.purchaseOrderDocumentNums = purchaseOrderDocumentNums;
2302    }
2303
2304    /*public boolean isInvoiceModified() {
2305        return invoiceModified;
2306    }
2307
2308    public void setInvoiceModified(boolean invoiceModified) {
2309        this.invoiceModified = invoiceModified;
2310    }*/
2311
2312    public boolean isOverviewFlag() {
2313        return overviewFlag;
2314    }
2315
2316    public void setOverviewFlag(boolean overviewFlag) {
2317        this.overviewFlag = overviewFlag;
2318    }
2319
2320    public boolean isVendorInfoFlag() {
2321        return vendorInfoFlag;
2322    }
2323
2324    public void setVendorInfoFlag(boolean vendorInfoFlag) {
2325        this.vendorInfoFlag = vendorInfoFlag;
2326    }
2327
2328    public boolean isInvoiceInfoFlag() {
2329        return invoiceInfoFlag;
2330    }
2331
2332    public void setInvoiceInfoFlag(boolean invoiceInfoFlag) {
2333        this.invoiceInfoFlag = invoiceInfoFlag;
2334    }
2335
2336    public boolean isProcessItemFlag() {
2337        return processItemFlag;
2338    }
2339
2340    public void setProcessItemFlag(boolean processItemFlag) {
2341        this.processItemFlag = processItemFlag;
2342    }
2343
2344    public boolean isProcessTitlesFlag() {
2345        return processTitlesFlag;
2346    }
2347
2348    public void setProcessTitlesFlag(boolean processTitlesFlag) {
2349        this.processTitlesFlag = processTitlesFlag;
2350    }
2351
2352    public boolean isCurrentItemsFlag() {
2353        return currentItemsFlag;
2354    }
2355
2356    public void setCurrentItemsFlag(boolean currentItemsFlag) {
2357        this.currentItemsFlag = currentItemsFlag;
2358    }
2359
2360    public boolean isAdditionalChargesFlag() {
2361        return additionalChargesFlag;
2362    }
2363
2364    public void setAdditionalChargesFlag(boolean additionalChargesFlag) {
2365        this.additionalChargesFlag = additionalChargesFlag;
2366    }
2367
2368    public boolean isAccountSummaryFlag() {
2369        return accountSummaryFlag;
2370    }
2371
2372    public void setAccountSummaryFlag(boolean accountSummaryFlag) {
2373        this.accountSummaryFlag = accountSummaryFlag;
2374    }
2375
2376    public boolean isNotesAndAttachmentFlag() {
2377        return notesAndAttachmentFlag;
2378    }
2379
2380    public void setNotesAndAttachmentFlag(boolean notesAndAttachmentFlag) {
2381        this.notesAndAttachmentFlag = notesAndAttachmentFlag;
2382    }
2383
2384    public boolean isAdHocRecipientsFlag() {
2385        return adHocRecipientsFlag;
2386    }
2387
2388    public void setAdHocRecipientsFlag(boolean adHocRecipientsFlag) {
2389        this.adHocRecipientsFlag = adHocRecipientsFlag;
2390    }
2391
2392    public boolean isRouteLogFlag() {
2393        return routeLogFlag;
2394    }
2395
2396    public void setRouteLogFlag(boolean routeLogFlag) {
2397        this.routeLogFlag = routeLogFlag;
2398    }
2399
2400    public boolean isRouteLogDisplayFlag() {
2401        return routeLogDisplayFlag;
2402    }
2403
2404    public void setRouteLogDisplayFlag(boolean routeLogDisplayFlag) {
2405        this.routeLogDisplayFlag = routeLogDisplayFlag;
2406    }
2407
2408
2409    /**
2410     * Performs logic needed to copy Invoice Document.
2411     */
2412    @Override
2413    public void toCopy() throws WorkflowException, ValidationException {
2414        super.toCopy();
2415        String[] collapseSections = getOleInvoiceService().getDefaultCollapseSections();
2416        this.setOverviewFlag(getOleInvoiceService().canCollapse(OLEConstants.OVERVIEW_SECTION, collapseSections));
2417        this.setVendorInfoFlag(getOleInvoiceService().canCollapse(OLEConstants.VENDOR_INFO_SECTION, collapseSections));
2418        this.setInvoiceInfoFlag(getOleInvoiceService().canCollapse(OLEConstants.INVOICE_INFO_SECTION, collapseSections));
2419        this.setProcessTitlesFlag(getOleInvoiceService().canCollapse(OLEConstants.PROCESS_TITLES_SECTION, collapseSections));
2420        this.setCurrentItemsFlag(getOleInvoiceService().canCollapse(OLEConstants.CURRENT_ITEM_SECTION, collapseSections));
2421        this.setAdditionalChargesFlag(getOleInvoiceService().canCollapse(OLEConstants.ADDITIONAL_CHARGES_SECTION, collapseSections));
2422        this.setAccountSummaryFlag(getOleInvoiceService().canCollapse(OLEConstants.ACCOUNT_SUMMARY_SECTION, collapseSections));
2423        this.setAdHocRecipientsFlag(getOleInvoiceService().canCollapse(OLEConstants.ADHOC_RECIPIENT_SECTION, collapseSections));
2424        this.setRouteLogFlag(getOleInvoiceService().canCollapse(OLEConstants.ROUTE_LOG_SECTION, collapseSections));
2425        this.setNotesAndAttachmentFlag(getOleInvoiceService().canCollapse(OLEConstants.NOTES_AND_ATTACH_SECTION, collapseSections));
2426        // Clear related views
2427        this.setAccountsPayablePurchasingDocumentLinkIdentifier(null);
2428        this.setRelatedViews(null);
2429        this.setInvoiceNumber("");
2430        this.setNoteLine1Text("");
2431
2432        Person currentUser = GlobalVariables.getUserSession().getPerson();
2433        this.setPurapDocumentIdentifier(null);
2434
2435        // Set req status to INPR.
2436        //for app doc status
2437        updateAndSaveAppDocStatus(InvoiceStatuses.APPDOC_INITIATE);
2438        this.setPostingYear(SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear());
2439
2440        for (Iterator iter = this.getItems().iterator(); iter.hasNext(); ) {
2441            OleInvoiceItem item = (OleInvoiceItem) iter.next();
2442            item.setPurapDocumentIdentifier(null);
2443            item.setItemIdentifier(null);
2444            if (this.getCloneDebitInvoice().equalsIgnoreCase("true")) {
2445                item.setDebitItem(true);
2446                item.setInvoiceListPrice(item.getItemListPrice().abs().toString());
2447            } else {
2448                item.setDebitItem(false);
2449                item.setInvoiceListPrice(item.getItemListPrice().negated().toString());
2450            }
2451            for (Iterator acctIter = item.getSourceAccountingLines().iterator(); acctIter.hasNext(); ) {
2452                InvoiceAccount account = (InvoiceAccount) acctIter.next();
2453                account.setAccountIdentifier(null);
2454                account.setItemIdentifier(null);
2455                account.setObjectId(null);
2456                account.setVersionNumber(null);
2457            }
2458            item.setPaidCopies(new ArrayList<OLEPaidCopy>());
2459        }
2460        SpringContext.getBean(PurapService.class).addBelowLineItems(this);
2461        this.refreshNonUpdateableReferences();
2462    }
2463
2464    /**
2465     * Checks whether copying of this document should be allowed. Copying is not allowed if this is a B2B requistion, and more than
2466     * a set number of days have passed since the document's creation.
2467     *
2468     * @return True if copying of this requisition is allowed.
2469     */
2470    @Override
2471    public boolean getAllowsCopy() {
2472        //boolean allowsCopy = super.getAllowsCopy();
2473        boolean allowsCopy = true;
2474        return allowsCopy;
2475    }
2476
2477    /**
2478     * This method returns the duplicateFlag indicator
2479     *
2480     * @return duplicateFlag
2481     */
2482    public boolean isDuplicateFlag() {
2483        return duplicateFlag;
2484    }
2485
2486    /**
2487     * This method sets the duplicateFlag
2488     *
2489     * @param duplicateFlag
2490     */
2491    public void setDuplicateFlag(boolean duplicateFlag) {
2492        this.duplicateFlag = duplicateFlag;
2493    }
2494
2495    public String getSearchResultInvoiceDate() {
2496        return searchResultInvoiceDate;
2497    }
2498
2499    public void setSearchResultInvoiceDate(String searchResultInvoiceDate) {
2500        this.searchResultInvoiceDate = searchResultInvoiceDate;
2501    }
2502
2503    public String getSearchResultInvoicePayDate() {
2504        return searchResultInvoicePayDate;
2505    }
2506
2507    public void setSearchResultInvoicePayDate(String searchResultInvoicePayDate) {
2508        this.searchResultInvoicePayDate = searchResultInvoicePayDate;
2509    }
2510
2511    public boolean isDuplicateApproveFlag() {
2512        return duplicateApproveFlag;
2513    }
2514
2515    public void setDuplicateApproveFlag(boolean duplicateApproveFlag) {
2516        this.duplicateApproveFlag = duplicateApproveFlag;
2517    }
2518
2519    public String getCloneDebitInvoice() {
2520        return cloneDebitInvoice;
2521    }
2522
2523    public void setCloneDebitInvoice(String cloneDebitInvoice) {
2524        this.cloneDebitInvoice = cloneDebitInvoice;
2525    }
2526
2527    public boolean isCloneFlag() {
2528        return cloneFlag;
2529    }
2530
2531    public void setCloneFlag(boolean cloneFlag) {
2532        this.cloneFlag = cloneFlag;
2533    }
2534
2535    public List<OlePaymentRequestDocument> getPaymentRequestDocuments() {
2536        return paymentRequestDocuments;
2537    }
2538
2539    public void setPaymentRequestDocuments(List<OlePaymentRequestDocument> paymentRequestDocuments) {
2540        this.paymentRequestDocuments = paymentRequestDocuments;
2541    }
2542
2543    public boolean isOffsetAccountIndicator() {
2544        return offsetAccountIndicator;
2545    }
2546
2547    public void setOffsetAccountIndicator(boolean offsetAccountIndicator) {
2548        this.offsetAccountIndicator = offsetAccountIndicator;
2549    }
2550
2551    public boolean isItemSign() {
2552        return itemSign;
2553    }
2554
2555    public void setItemSign(boolean itemSign) {
2556        this.itemSign = itemSign;
2557    }
2558
2559    public boolean isBlanketApproveSubscriptionDateValidationFlag() {
2560        return blanketApproveSubscriptionDateValidationFlag;
2561    }
2562
2563    public void setBlanketApproveSubscriptionDateValidationFlag(boolean blanketApproveSubscriptionDateValidationFlag) {
2564        this.blanketApproveSubscriptionDateValidationFlag = blanketApproveSubscriptionDateValidationFlag;
2565    }
2566
2567    public boolean isSubscriptionDateValidationFlag() {
2568        return subscriptionDateValidationFlag;
2569    }
2570
2571    public void setSubscriptionDateValidationFlag(boolean subscriptionDateValidationFlag) {
2572        this.subscriptionDateValidationFlag = subscriptionDateValidationFlag;
2573    }
2574
2575    public String getVendorLink() {
2576        String oleurl = ConfigContext.getCurrentContextConfig().getProperty("ole.url");
2577        String url = oleurl+ OLEConstants.VENDOR_LINK +vendorHeaderGeneratedIdentifier + "&amp;vendorDetailAssignedIdentifier="
2578                +vendorDetailAssignedIdentifier;
2579        return url;
2580    }
2581
2582    public void setVendorLink(String vendorLink) {
2583        this.vendorLink = vendorLink;
2584    }
2585
2586    public boolean isForeignCurrencyFlag() {
2587        return foreignCurrencyFlag;
2588    }
2589
2590    public void setForeignCurrencyFlag(boolean foreignCurrencyFlag) {
2591        this.foreignCurrencyFlag = foreignCurrencyFlag;
2592    }
2593
2594    public Long getInvoiceCurrencyTypeId() {
2595        return invoiceCurrencyTypeId;
2596    }
2597
2598    public void setInvoiceCurrencyTypeId(Long invoiceCurrencyTypeId) {
2599        this.invoiceCurrencyTypeId = invoiceCurrencyTypeId;
2600    }
2601
2602    public String getInvoiceCurrencyType() {
2603        return invoiceCurrencyType;
2604    }
2605
2606    public void setInvoiceCurrencyType(String invoiceCurrencyType) {
2607        this.invoiceCurrencyType = invoiceCurrencyType;
2608    }
2609
2610    public OleCurrencyType getOleCurrencyType() {
2611        return oleCurrencyType;
2612    }
2613
2614    public void setOleCurrencyType(OleCurrencyType oleCurrencyType) {
2615        this.oleCurrencyType = oleCurrencyType;
2616    }
2617
2618    public boolean isCurrencyOverrideFlag() {
2619        return currencyOverrideFlag;
2620    }
2621
2622    public void setCurrencyOverrideFlag(boolean currencyOverrideFlag) {
2623        this.currencyOverrideFlag = currencyOverrideFlag;
2624    }
2625
2626    public String getCurrencyOverrideMessage() {
2627        return currencyOverrideMessage;
2628    }
2629
2630    public void setCurrencyOverrideMessage(String currencyOverrideMessage) {
2631        this.currencyOverrideMessage = currencyOverrideMessage;
2632    }
2633
2634    public String getInvoiceCurrencyExchangeRate() {
2635        if (invoiceCurrencyExchangeRate != null && !invoiceCurrencyExchangeRate.isEmpty()) {
2636            if (invoiceCurrencyExchangeRate != null && invoiceCurrencyExchangeRate.contains("-")) {
2637                invoiceCurrencyExchangeRate = invoiceCurrencyExchangeRate.replace("-", "");
2638                invoiceCurrencyExchangeRate = "(" + invoiceCurrencyExchangeRate + ")";
2639            }
2640            return invoiceCurrencyExchangeRate;
2641        }
2642        return invoiceCurrencyExchangeRate;
2643    }
2644
2645    public void setInvoiceCurrencyExchangeRate(String invoiceCurrencyExchangeRate) {
2646        this.invoiceCurrencyExchangeRate = invoiceCurrencyExchangeRate;
2647        if (invoiceCurrencyExchangeRate != null) {
2648            if (invoiceCurrencyExchangeRate.contains("(") || invoiceCurrencyExchangeRate.contains(")")) {
2649                invoiceCurrencyExchangeRate = invoiceCurrencyExchangeRate.replace("(", "");
2650                invoiceCurrencyExchangeRate = invoiceCurrencyExchangeRate.replace(")", "");
2651                invoiceCurrencyExchangeRate = "-" + invoiceCurrencyExchangeRate;
2652                this.invoiceCurrencyExchangeRate = invoiceCurrencyExchangeRate;
2653            }
2654            if (new KualiDecimal(invoiceCurrencyExchangeRate).isLessThan(KualiDecimal.ZERO)) {
2655                invoiceCurrencyExchangeRate = invoiceCurrencyExchangeRate.replace("-", "");
2656                invoiceCurrencyExchangeRate = "(" + invoiceCurrencyExchangeRate + ")";
2657                this.invoiceCurrencyExchangeRate = invoiceCurrencyExchangeRate;
2658            }
2659        }
2660    }
2661
2662    public boolean isDbRetrieval() {
2663        return dbRetrieval;
2664    }
2665
2666    public void setDbRetrieval(boolean dbRetrieval) {
2667        this.dbRetrieval = dbRetrieval;
2668    }
2669
2670    public boolean isEnableCurrentItems() {
2671        return enableCurrentItems;
2672    }
2673
2674    public void setEnableCurrentItems(boolean enableCurrentItems) {
2675        this.enableCurrentItems = enableCurrentItems;
2676    }
2677}