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.StringEscapeUtils;
019import org.apache.commons.lang.StringUtils;
020import org.kuali.ole.docstore.common.client.DocstoreClient;
021import org.kuali.ole.docstore.common.client.DocstoreClientLocator;
022import org.kuali.ole.docstore.common.client.DocstoreClientLocatorService;
023import org.kuali.ole.docstore.common.client.DocstoreRestClient;
024import org.kuali.ole.docstore.common.client.impl.DocstoreClientLocatorServiceImpl;
025import org.kuali.ole.docstore.common.document.Bib;
026import org.kuali.ole.docstore.common.document.BibMarc;
027import org.kuali.ole.DocumentUniqueIDPrefix;
028import org.kuali.ole.gl.service.SufficientFundsService;
029import org.kuali.ole.module.purap.PurapConstants;
030import org.kuali.ole.module.purap.PurapConstants.PaymentRequestStatuses;
031import org.kuali.ole.module.purap.PurapParameterConstants;
032import org.kuali.ole.module.purap.PurapWorkflowConstants;
033import org.kuali.ole.module.purap.businessobject.*;
034import org.kuali.ole.module.purap.document.PaymentRequestDocument;
035import org.kuali.ole.module.purap.document.PurchaseOrderDocument;
036import org.kuali.ole.module.purap.document.service.AccountsPayableService;
037import org.kuali.ole.module.purap.document.service.PaymentRequestService;
038import org.kuali.ole.module.purap.document.service.PurapService;
039import org.kuali.ole.module.purap.service.PurapAccountingService;
040import org.kuali.ole.module.purap.util.ExpiredOrClosedAccountEntry;
041import org.kuali.ole.select.OleSelectConstant;
042import org.kuali.ole.select.bo.OLELinkPurapDonor;
043import org.kuali.ole.select.businessobject.*;
044import org.kuali.ole.select.document.service.OlePaymentRequestService;
045import org.kuali.ole.select.document.service.OlePurchaseOrderDocumentHelperService;
046import org.kuali.ole.select.document.service.OleRequisitionDocumentService;
047import org.kuali.ole.select.document.service.impl.OlePaymentRequestFundCheckServiceImpl;
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.*;
055import org.kuali.ole.sys.context.SpringContext;
056import org.kuali.ole.sys.service.GeneralLedgerPendingEntryService;
057import org.kuali.ole.sys.service.UniversityDateService;
058import org.kuali.ole.vnd.VendorConstants;
059import org.kuali.ole.vnd.businessobject.OleExchangeRate;
060import org.kuali.ole.vnd.businessobject.VendorAddress;
061import org.kuali.ole.vnd.businessobject.VendorAlias;
062import org.kuali.ole.vnd.document.service.VendorService;
063import org.kuali.rice.core.api.config.property.ConfigurationService;
064import org.kuali.rice.core.api.datetime.DateTimeService;
065import org.kuali.rice.core.api.util.type.KualiDecimal;
066import org.kuali.rice.coreservice.framework.parameter.ParameterService;
067import org.kuali.rice.kew.api.KewApiConstants;
068import org.kuali.rice.kew.api.KewApiServiceLocator;
069import org.kuali.rice.kew.api.WorkflowDocument;
070import org.kuali.rice.kew.api.action.ActionRequestType;
071import org.kuali.rice.kew.api.action.ActionTaken;
072import org.kuali.rice.kew.api.action.RoutingReportCriteria;
073import org.kuali.rice.kew.api.exception.WorkflowException;
074import org.kuali.rice.kew.framework.postprocessor.DocumentRouteLevelChange;
075import org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange;
076import org.kuali.rice.kim.api.identity.Person;
077import org.kuali.rice.kim.api.identity.PersonService;
078import org.kuali.rice.kim.api.identity.principal.Principal;
079import org.kuali.rice.kim.api.services.IdentityManagementService;
080import org.kuali.rice.kim.api.services.KimApiServiceLocator;
081import org.kuali.rice.krad.bo.Note;
082import org.kuali.rice.krad.rules.rule.event.KualiDocumentEvent;
083import org.kuali.rice.krad.service.BusinessObjectService;
084import org.kuali.rice.krad.service.DocumentService;
085import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
086import org.kuali.rice.krad.util.GlobalVariables;
087import org.kuali.rice.krad.util.ObjectUtils;
088import org.kuali.rice.krad.workflow.service.WorkflowDocumentService;
089import java.math.BigDecimal;
090import java.math.RoundingMode;
091import java.util.*;
092
093
094/**
095 * This class is the document class for Ole Payment Request
096 */
097
098public class OlePaymentRequestDocument extends PaymentRequestDocument {
099
100    private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(OlePaymentRequestDocument.class);
101
102    private Integer invoiceTypeId;
103    private Integer invoiceSubTypeId;
104
105    // NOT PERSISTED IN DB
106    private String invoiceType;
107    private String invoiceSubType;
108
109    // REFERENCE OBJECTS
110    private OleInvoiceSubType oleInvoiceSubType;
111    private OleInvoiceType oleInvoiceType;
112
113    // Prorating Additional charges
114    private boolean prorateQty;
115    private boolean prorateDollar;
116    private boolean prorateManual;
117    private boolean noProrate;
118
119    private String prorateBy;
120
121    private BigDecimal foreignVendorInvoiceAmount;
122
123    private BigDecimal purchaseOrderTypeId;
124    private PurchaseOrderType orderType;
125    private static transient BibInfoService bibInfoService;
126    private Integer paymentMethodId;
127    private OlePaymentMethod paymentMethod;
128    private String vendorAliasName;
129
130    private boolean currencyTypeIndicator= true;
131
132    public String getVendorAliasName() {
133        return vendorAliasName;
134    }
135
136    public void setVendorAliasName(String vendorAliasName) {
137        this.vendorAliasName = vendorAliasName;
138    }
139
140    public Integer getPaymentMethodId() {
141        return paymentMethodId;
142    }
143
144    public void setPaymentMethodId(Integer paymentMethodId) {
145        this.paymentMethodId = paymentMethodId;
146    }
147
148    public OlePaymentMethod getPaymentMethod() {
149        return paymentMethod;
150    }
151
152    public void setPaymentMethod(OlePaymentMethod paymentMethod) {
153        this.paymentMethod = paymentMethod;
154    }
155
156    public static BibInfoService getBibInfoService() {
157        if (bibInfoService == null) {
158            bibInfoService = SpringContext.getBean(BibInfoServiceImpl.class);
159        }
160        return bibInfoService;
161    }
162
163    @Override
164    public BigDecimal getPurchaseOrderTypeId() {
165        return purchaseOrderTypeId;
166    }
167
168    @Override
169    public void setPurchaseOrderTypeId(BigDecimal purchaseOrderTypeId) {
170        this.purchaseOrderTypeId = purchaseOrderTypeId;
171    }
172
173    @Override
174    public PurchaseOrderType getOrderType() {
175        return orderType;
176    }
177
178    @Override
179    public void setOrderType(PurchaseOrderType orderType) {
180        this.orderType = orderType;
181    }
182
183    public Integer getInvoiceTypeId() {
184        return invoiceTypeId;
185    }
186
187    public void setInvoiceTypeId(Integer invoiceTypeId) {
188        this.invoiceTypeId = invoiceTypeId;
189    }
190
191    public Integer getInvoiceSubTypeId() {
192        return invoiceSubTypeId;
193    }
194
195    public void setInvoiceSubTypeId(Integer invoiceSubTypeId) {
196        this.invoiceSubTypeId = invoiceSubTypeId;
197    }
198
199    public String getInvoiceType() {
200        return invoiceType;
201    }
202
203    public void setInvoiceType(String invoiceType) {
204        this.invoiceType = invoiceType;
205    }
206
207    public String getInvoiceSubType() {
208        return invoiceSubType;
209    }
210
211    public void setInvoiceSubType(String invoiceSubType) {
212        this.invoiceSubType = invoiceSubType;
213    }
214
215    public OleInvoiceSubType getOleInvoiceSubType() {
216        return oleInvoiceSubType;
217    }
218
219    public void setOleInvoiceSubType(OleInvoiceSubType oleInvoiceSubType) {
220        this.oleInvoiceSubType = oleInvoiceSubType;
221    }
222
223    public OleInvoiceType getOleInvoiceType() {
224        return oleInvoiceType;
225    }
226
227    public void setOleInvoiceType(OleInvoiceType oleInvoiceType) {
228        this.oleInvoiceType = oleInvoiceType;
229    }
230
231    public boolean isProrateQty() {
232        return prorateQty;
233    }
234
235    public void setProrateQty(boolean prorateQty) {
236        this.prorateQty = prorateQty;
237    }
238
239    public boolean isProrateDollar() {
240        return prorateDollar;
241    }
242
243    public void setProrateDollar(boolean prorateDollar) {
244        this.prorateDollar = prorateDollar;
245    }
246
247    public boolean isProrateManual() {
248        return prorateManual;
249    }
250
251    public void setProrateManual(boolean prorateManual) {
252        this.prorateManual = prorateManual;
253    }
254
255    public boolean isNoProrate() {
256        return noProrate;
257    }
258
259    public void setNoProrate(boolean noProrate) {
260        this.noProrate = noProrate;
261    }
262
263    private static transient ConfigurationService kualiConfigurationService;
264    private static transient BibInfoWrapperService bibInfoWrapperService;
265    private static transient FileProcessingService fileProcessingService;
266    private static transient BusinessObjectService businessObjectService;
267    private static transient VendorService vendorService;
268    private static transient PaymentRequestService paymentRequestService;
269    private static transient OlePaymentRequestService olePaymentRequestService;
270    private static transient PurapService purapService;
271    private static transient AccountsPayableService accountsPayableService;
272    private static transient IdentityManagementService identityManagementService;
273    private static transient WorkflowDocumentService workflowDocumentService;
274
275    //Proforma
276    private boolean proformaIndicator;
277
278    public static WorkflowDocumentService getWorkflowDocumentService() {
279        if (workflowDocumentService == null) {
280            workflowDocumentService = SpringContext.getBean(WorkflowDocumentService.class);
281        }
282        return workflowDocumentService;
283    }
284
285    public static void setWorkflowDocumentService(WorkflowDocumentService workflowDocumentService) {
286        OlePaymentRequestDocument.workflowDocumentService = workflowDocumentService;
287    }
288
289    public static PaymentRequestService getPaymentRequestService() {
290        if (paymentRequestService == null) {
291            paymentRequestService = SpringContext.getBean(PaymentRequestService.class);
292        }
293        return paymentRequestService;
294    }
295
296    public static void setPaymentRequestService(PaymentRequestService paymentRequestService) {
297        OlePaymentRequestDocument.paymentRequestService = paymentRequestService;
298    }
299
300    public static VendorService getVendorService() {
301        if (vendorService == null) {
302            vendorService = SpringContext.getBean(VendorService.class);
303        }
304        return vendorService;
305    }
306
307    public static void setVendorService(VendorService vendorService) {
308        OlePaymentRequestDocument.vendorService = vendorService;
309    }
310
311    public static PurapService getPurapService() {
312        if (purapService == null) {
313            purapService = SpringContext.getBean(PurapService.class);
314        }
315        return purapService;
316    }
317
318    public static void setPurapService(PurapService purapService) {
319        OlePaymentRequestDocument.purapService = purapService;
320    }
321
322    public static OlePaymentRequestService getOlePaymentRequestService() {
323        if (olePaymentRequestService == null) {
324            olePaymentRequestService = SpringContext.getBean(OlePaymentRequestService.class);
325        }
326        return olePaymentRequestService;
327    }
328
329    public static void setOlePaymentRequestService(OlePaymentRequestService olePaymentRequestService) {
330        OlePaymentRequestDocument.olePaymentRequestService = olePaymentRequestService;
331    }
332
333    public static IdentityManagementService getIdentityManagementService() {
334        if (identityManagementService == null) {
335            identityManagementService = SpringContext.getBean(IdentityManagementService.class);
336        }
337        return identityManagementService;
338    }
339
340    public static void setIdentityManagementService(IdentityManagementService identityManagementService) {
341        OlePaymentRequestDocument.identityManagementService = identityManagementService;
342    }
343
344    public static AccountsPayableService getAccountsPayableService() {
345        if (accountsPayableService == null) {
346            accountsPayableService = SpringContext.getBean(AccountsPayableService.class);
347        }
348        return accountsPayableService;
349    }
350
351    public static void setAccountsPayableService(AccountsPayableService accountsPayableService) {
352        OlePaymentRequestDocument.accountsPayableService = accountsPayableService;
353    }
354
355    public static ConfigurationService getConfigurationService() {
356        if (kualiConfigurationService == null) {
357            kualiConfigurationService = SpringContext.getBean(ConfigurationService.class);
358        }
359        return kualiConfigurationService;
360    }
361
362    public static void setConfigurationService(ConfigurationService kualiConfigurationService) {
363        OlePaymentRequestDocument.kualiConfigurationService = kualiConfigurationService;
364    }
365
366    public static BibInfoWrapperService getBibInfoWrapperService() {
367        if (bibInfoWrapperService == null) {
368            bibInfoWrapperService = SpringContext.getBean(BibInfoWrapperService.class);
369        }
370        return bibInfoWrapperService;
371    }
372
373    public static void setBibInfoWrapperService(BibInfoWrapperService bibInfoWrapperService) {
374        OlePaymentRequestDocument.bibInfoWrapperService = bibInfoWrapperService;
375    }
376
377
378    public static FileProcessingService getFileProcessingService() {
379        if (fileProcessingService == null) {
380            fileProcessingService = SpringContext.getBean(FileProcessingService.class);
381        }
382        return fileProcessingService;
383    }
384
385    public static void setFileProcessingService(FileProcessingService fileProcessingService) {
386        OlePaymentRequestDocument.fileProcessingService = fileProcessingService;
387    }
388
389    public static DateTimeService getDateTimeService() {
390        if (dateTimeService == null) {
391            dateTimeService = SpringContext.getBean(DateTimeService.class);
392        }
393        return dateTimeService;
394    }
395
396    public static void setDateTimeService(DateTimeService dateTimeService) {
397        OlePaymentRequestDocument.dateTimeService = dateTimeService;
398    }
399
400    @Override
401    public BusinessObjectService getBusinessObjectService() {
402        if (businessObjectService == null) {
403            businessObjectService = SpringContext.getBean(BusinessObjectService.class);
404        }
405        return businessObjectService;
406    }
407
408    public void setBusinessObjectService(BusinessObjectService businessObjectService) {
409        this.businessObjectService = businessObjectService;
410    }
411
412    /**
413     * Default constructor.
414     */
415    public OlePaymentRequestDocument() {
416        super();
417        // TODO Auto-generated constructor stub
418    }
419
420    /**
421     * This method is overridden to populate Ole PaymentRequestDocument from PurchaseOrder Document
422     *
423     * @see org.kuali.ole.module.purap.document.PaymentRequestDocument#populatePaymentRequestFromPurchaseOrder(org.kuali.ole.module.purap.document.PurchaseOrderDocument, java.util.HashMap)
424     */
425    @Override
426    public void populatePaymentRequestFromPurchaseOrder(PurchaseOrderDocument po, HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountList) {
427        LOG.debug("Inside populatePaymentRequestFromPurchaseOrder method of OlePaymentRequest Document");
428        this.setPaymentMethodId(po.getVendorDetail().getPaymentMethodId());
429        this.setPurchaseOrderIdentifier(po.getPurapDocumentIdentifier());
430        this.getDocumentHeader().setOrganizationDocumentNumber(po.getDocumentHeader().getOrganizationDocumentNumber());
431        this.setPostingYear(po.getPostingYear());
432        this.setReceivingDocumentRequiredIndicator(po.isReceivingDocumentRequiredIndicator());
433        this.setUseTaxIndicator(po.isUseTaxIndicator());
434        this.setPaymentRequestPositiveApprovalIndicator(po.isPaymentRequestPositiveApprovalIndicator());
435        this.setVendorCustomerNumber(po.getVendorCustomerNumber());
436
437        if (po.getPurchaseOrderCostSource() != null) {
438            this.setPaymentRequestCostSource(po.getPurchaseOrderCostSource());
439            this.setPaymentRequestCostSourceCode(po.getPurchaseOrderCostSourceCode());
440        }
441
442        if (po.getVendorShippingPaymentTerms() != null) {
443            this.setVendorShippingPaymentTerms(po.getVendorShippingPaymentTerms());
444            this.setVendorShippingPaymentTermsCode(po.getVendorShippingPaymentTermsCode());
445        }
446
447        if (po.getVendorPaymentTerms() != null) {
448            this.setVendorPaymentTermsCode(po.getVendorPaymentTermsCode());
449            this.setVendorPaymentTerms(po.getVendorPaymentTerms());
450        }
451
452        if (po.getRecurringPaymentType() != null) {
453            this.setRecurringPaymentType(po.getRecurringPaymentType());
454            this.setRecurringPaymentTypeCode(po.getRecurringPaymentTypeCode());
455        }
456
457        this.setVendorHeaderGeneratedIdentifier(po.getVendorHeaderGeneratedIdentifier());
458        this.setVendorDetailAssignedIdentifier(po.getVendorDetailAssignedIdentifier());
459        this.setVendorCustomerNumber(po.getVendorCustomerNumber());
460        this.setVendorName(po.getVendorName());
461        /*this.setVendorAliasName(((OlePurchaseOrderDocument) po).getVendorAliasName());*/
462
463        // set original vendor
464        this.setOriginalVendorHeaderGeneratedIdentifier(po.getVendorHeaderGeneratedIdentifier());
465        this.setOriginalVendorDetailAssignedIdentifier(po.getVendorDetailAssignedIdentifier());
466
467        // set alternate vendor info as well
468        this.setAlternateVendorHeaderGeneratedIdentifier(po.getAlternateVendorHeaderGeneratedIdentifier());
469        this.setAlternateVendorDetailAssignedIdentifier(po.getAlternateVendorDetailAssignedIdentifier());
470
471        // populate preq vendor address with the default remit address type for the vendor if found
472        String userCampus = GlobalVariables.getUserSession().getPerson().getCampusCode();
473        VendorAddress vendorAddress = getVendorService().getVendorDefaultAddress(po.getVendorHeaderGeneratedIdentifier(), po.getVendorDetailAssignedIdentifier(), VendorConstants.AddressTypes.REMIT, userCampus);
474        if (vendorAddress != null) {
475            this.templateVendorAddress(vendorAddress);
476            this.setVendorAddressGeneratedIdentifier(vendorAddress.getVendorAddressGeneratedIdentifier());
477            setVendorAttentionName(StringUtils.defaultString(vendorAddress.getVendorAttentionName()));
478        } else {
479            // set address from PO
480            this.setVendorAddressGeneratedIdentifier(po.getVendorAddressGeneratedIdentifier());
481            this.setVendorLine1Address(po.getVendorLine1Address());
482            this.setVendorLine2Address(po.getVendorLine2Address());
483            this.setVendorCityName(po.getVendorCityName());
484            this.setVendorAddressInternationalProvinceName(po.getVendorAddressInternationalProvinceName());
485            this.setVendorStateCode(po.getVendorStateCode());
486            this.setVendorPostalCode(po.getVendorPostalCode());
487            this.setVendorCountryCode(po.getVendorCountryCode());
488
489            boolean blankAttentionLine = StringUtils.equalsIgnoreCase(
490                    "Y",
491                    SpringContext.getBean(ParameterService.class).getParameterValueAsString(
492                            PurapConstants.PURAP_NAMESPACE, "Document",
493                            PurapParameterConstants.BLANK_ATTENTION_LINE_FOR_PO_TYPE_ADDRESS));
494
495            if (blankAttentionLine) {
496                setVendorAttentionName(StringUtils.EMPTY);
497            } else {
498                setVendorAttentionName(StringUtils.defaultString(po.getVendorAttentionName()));
499            }
500        }
501
502        this.setPaymentRequestPayDate(getPaymentRequestService().calculatePayDate(this.getInvoiceDate(), this.getVendorPaymentTerms()));
503
504        if (getPaymentRequestService().encumberedItemExistsForInvoicing(po)) {
505            for (OlePurchaseOrderItem poi : (List<OlePurchaseOrderItem>) po.getItems()) {
506                // check to make sure it's eligible for payment (i.e. active and has encumbrance available
507                if (getDocumentSpecificService().poItemEligibleForAp(this, poi)) {
508                    OlePaymentRequestItem paymentRequestItem = new OlePaymentRequestItem(poi, this, expiredOrClosedAccountList);
509                    this.getItems().add(paymentRequestItem);
510                    PurchasingCapitalAssetItem purchasingCAMSItem = po.getPurchasingCapitalAssetItemByItemIdentifier(poi.getItemIdentifier());
511                    if (purchasingCAMSItem != null) {
512                        paymentRequestItem.setCapitalAssetTransactionTypeCode(purchasingCAMSItem.getCapitalAssetTransactionTypeCode());
513                    }
514
515                    /*
516                    // copy usetaxitems over
517                    paymentRequestItem.getUseTaxItems().clear();
518                    for (PurApItemUseTax useTax : poi.getUseTaxItems()) {
519                        paymentRequestItem.getUseTaxItems().add(useTax);
520                    }
521                    */
522                }
523            }
524        }
525
526        // add missing below the line
527        getPurapService().addBelowLineItems(this);
528        this.setAccountsPayablePurchasingDocumentLinkIdentifier(po.getAccountsPayablePurchasingDocumentLinkIdentifier());
529
530        //fix up below the line items
531        getPaymentRequestService().removeIneligibleAdditionalCharges(this);
532
533        this.fixItemReferences();
534        this.refreshNonUpdateableReferences();
535    }
536
537    @Override
538    public Class getItemClass() {
539        return OlePaymentRequestItem.class;
540    }
541
542    @Override
543    public PurApAccountingLine getFirstAccount() {
544        // loop through items, and pick the first item
545        if ((getItems() != null) && (!getItems().isEmpty())) {
546            OlePaymentRequestItem itemToUse = null;
547            for (Iterator iter = getItems().iterator(); iter.hasNext(); ) {
548                OlePaymentRequestItem item = (OlePaymentRequestItem) iter.next();
549                if ((item.isConsideredEntered()) && ((item.getSourceAccountingLines() != null) && (!item.getSourceAccountingLines().isEmpty()))) {
550                    // accounting lines are not empty so pick the first account
551                    PurApAccountingLine accountLine = item.getSourceAccountingLine(0);
552                    accountLine.refreshNonUpdateableReferences();
553                    return accountLine;
554                }
555                /*
556                if (((item.getExtendedPrice() != null) && item.getExtendedPrice().compareTo(BigDecimal.ZERO) > 0) && ((item.getAccounts() != null) && (!item.getAccounts().isEmpty()))) {
557                    // accounting lines are not empty so pick the first account
558               List accts = (List)item.getAccounts();
559               PaymentRequestAccount accountLine = (PaymentRequestAccount)accts.get(0);
560                    return accountLine.getFinancialChartOfAccountsCode() + "-" + accountLine.getAccountNumber();
561                }
562                */
563            }
564        }
565        return null;
566
567    }
568
569    @Override
570    public PurApItem getItem(int pos) {
571        OlePaymentRequestItem item = (OlePaymentRequestItem) super.getItem(pos);
572        if (item.getPaymentRequest() == null) {
573            item.setPaymentRequest(this);
574        }
575        return item;
576    }
577
578    @Override
579    public void processAfterRetrieve() {
580        super.processAfterRetrieve();
581        try {
582            LOG.debug("###########inside OlePaymentRequestDocument processAfterRetrieve###########");
583            if (this.getVendorAliasName() == null) {
584                populateVendorAliasName();
585            }
586            if (this.getPaymentMethodId() != null) {
587                OlePaymentMethod olePaymentMethod = SpringContext.getBean(BusinessObjectService.class)
588                        .findBySinglePrimaryKey(OlePaymentMethod.class, this.getPaymentMethodId());
589                this.setPaymentMethod(olePaymentMethod);
590            }
591            List<BigDecimal> newUnitPriceList = new ArrayList<BigDecimal>();
592            BigDecimal newUnitPrice = new BigDecimal(0);
593            BigDecimal hundred = new BigDecimal(100);
594            List<OlePaymentRequestItem> item = this.getItems();
595
596            for (int i = 0; item.size() > i; i++) {
597                OlePaymentRequestItem items = (OlePaymentRequestItem) this.getItem(i);
598                if ((items.getItemType().isQuantityBasedGeneralLedgerIndicator())) {
599                    if (items.getItemDiscount() == null) {
600                        items.setItemDiscount(KualiDecimal.ZERO);
601                    }
602
603                    if (items.getItemListPrice() == null) {
604                        items.setItemListPrice(KualiDecimal.ZERO);
605                    }
606
607                    if (items.getItemDiscountType() != null && items.getItemDiscountType().equalsIgnoreCase(OleSelectConstant.DISCOUNT_TYPE_PERCENTAGE)) {
608                        newUnitPrice = (hundred.subtract(items.getItemDiscount().bigDecimalValue())).divide(hundred).multiply(items.getItemListPrice().bigDecimalValue());
609                    } else {
610                        newUnitPrice = items.getItemListPrice().bigDecimalValue().subtract(items.getItemDiscount().bigDecimalValue());
611                    }
612                    items.setItemSurcharge(items.getItemUnitPrice().subtract(newUnitPrice).setScale(4, RoundingMode.HALF_UP));
613                }
614            }
615            if (this.getVendorDetail().getCurrencyType()!=null){
616                if(this.getVendorDetail().getCurrencyType().getCurrencyType().equalsIgnoreCase(OleSelectConstant.CURRENCY_TYPE_NAME)){
617                    currencyTypeIndicator=true;
618                }
619                else{
620                    currencyTypeIndicator=false;
621                }
622            }
623
624            if (this.getVendorDetail() != null && (!currencyTypeIndicator)) {
625                Long currencyTypeId = this.getVendorDetail().getCurrencyType().getCurrencyTypeId();
626                Map documentNumberMap = new HashMap();
627                documentNumberMap.put(OleSelectConstant.CURRENCY_TYPE_ID, currencyTypeId);
628                List<OleExchangeRate> exchangeRateList = (List) getBusinessObjectService().findMatchingOrderBy(OleExchangeRate.class, documentNumberMap, OleSelectConstant.EXCHANGE_RATE_DATE, false);
629                Iterator iterator = exchangeRateList.iterator();
630                for (OlePaymentRequestItem items : item) {
631                    iterator = exchangeRateList.iterator();
632                    if (iterator.hasNext()) {
633                        OleExchangeRate tempOleExchangeRate = (OleExchangeRate) iterator.next();
634                        items.setItemExchangeRate(new KualiDecimal(tempOleExchangeRate.getExchangeRate()));
635                        this.setForeignVendorInvoiceAmount(this.getVendorInvoiceAmount().bigDecimalValue().multiply(tempOleExchangeRate.getExchangeRate()));
636                    }
637                }
638
639            }
640            String itemDescription = "";
641            for (OlePaymentRequestItem singleItem : item) {
642                if (LOG.isDebugEnabled()) {
643                    LOG.debug("Title id while retriving ------>" + singleItem.getItemTitleId());
644                }
645                if (singleItem.getItemTitleId() != null) {
646                    LOG.debug("###########inside processAfterRetrieve ole requisition item###########");
647                    Bib bib =  new BibMarc();
648                    DocstoreClientLocator docstoreClientLocator=new DocstoreClientLocator();
649                  if(singleItem.getItemTitleId()!=null && singleItem.getItemTitleId()!=""){
650                        bib= docstoreClientLocator.getDocstoreClient().retrieveBib(singleItem.getItemTitleId());
651                        singleItem.setBibUUID(bib.getId());
652                        singleItem.setDocFormat(DocumentUniqueIDPrefix.getBibFormatType(singleItem.getItemTitleId()));
653                  }
654                    if(singleItem.getItemUnitPrice()!=null){
655                        singleItem.setItemUnitPrice(singleItem.getItemUnitPrice().setScale(2, BigDecimal.ROUND_HALF_UP));
656                    }
657                    itemDescription = ((bib.getTitle() != null && !bib
658                            .getTitle().isEmpty()) ? bib.getTitle().trim() + ", " : "")
659                            + ((bib.getAuthor() != null && !bib
660                            .getAuthor().isEmpty()) ? bib.getAuthor().trim() + ", "
661                            : "")
662                            + ((bib.getPublisher() != null && !bib
663                            .getPublisher().isEmpty()) ? bib.getPublisher().trim()
664                            + ", " : "")
665                            + ((bib.getIsbn() != null && !bib.getIsbn()
666                            .isEmpty()) ? bib.getIsbn().trim() + ", " : "");
667                    if (itemDescription != null && !(itemDescription.equals(""))) {
668                        itemDescription = itemDescription.lastIndexOf(",") < 0 ? itemDescription :
669                                itemDescription.substring(0, itemDescription.lastIndexOf(","));
670                        StringEscapeUtils stringEscapeUtils = new StringEscapeUtils();
671                        itemDescription = stringEscapeUtils.unescapeXml(itemDescription);
672                        singleItem.setItemDescription(itemDescription);
673                    }
674                    HashMap<String, String> queryMap = new HashMap<String, String>();
675                    if (singleItem.getPoItemIdentifier() != null) {
676                        queryMap.put(OLEConstants.PO_ITEM_ID, singleItem.getPoItemIdentifier().toString());
677                        OleInvoiceItem oleInvoiceItem = getBusinessObjectService().findByPrimaryKey(OleInvoiceItem.class, queryMap);
678                        if (oleInvoiceItem != null && oleInvoiceItem.getPoItemIdentifier() != null) {
679                            queryMap.clear();
680                            queryMap.put(OLEConstants.OleCopy.PO_ITM_ID, oleInvoiceItem.getPoItemIdentifier().toString());
681                            List<OLELinkPurapDonor> oleLinkPurapDonorList = (List<OLELinkPurapDonor>) getBusinessObjectService().findMatching(OLELinkPurapDonor.class, queryMap);
682                            if (oleLinkPurapDonorList != null) {
683                                singleItem.setOleDonors(oleLinkPurapDonorList);
684                            }
685                        }
686                    }
687                }
688                for(OLEPaidCopy olePaidCopy : singleItem.getPaidCopies()){
689                    if(olePaidCopy.getPaymentRequestItemId()==null && olePaidCopy.getPaymentRequestIdentifier()==null){
690                        olePaidCopy.setPaymentRequestItemId(singleItem.getItemIdentifier());
691                        olePaidCopy.setPaymentRequestIdentifier(this.getPurapDocumentIdentifier());
692                        getBusinessObjectService().save(olePaidCopy);
693                    }
694                }
695            }
696            if (this.getProrateBy() != null) {
697                this.setProrateQty(this.getProrateBy().equals(OLEConstants.PRORATE_BY_QTY));
698                this.setProrateManual(this.getProrateBy().equals(OLEConstants.MANUAL_PRORATE));
699                this.setProrateDollar(this.getProrateBy().equals(OLEConstants.PRORATE_BY_DOLLAR));
700                this.setNoProrate(this.getProrateBy().equals(OLEConstants.NO_PRORATE));
701            }
702        } catch (Exception e) {
703            LOG.error("Exception during processAfterRetrieve() in OlePaymentRequestDocument", e);
704            throw new RuntimeException(e);
705        }
706    }
707
708    /**
709     * This method is overrided to create POA from new Line Item of PaymentRequest
710     *
711     * @see org.kuali.ole.module.purap.document.PaymentRequestDocument#doRouteStatusChange(org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange)
712     */
713    @Override
714    public void doRouteStatusChange(DocumentRouteStatusChange statusChangeEvent) {
715        LOG.debug("doRouteStatusChange() started");
716
717        super.doRouteStatusChange(statusChangeEvent);
718        try {
719            // DOCUMENT PROCESSED
720            if (this.getDocumentHeader().getWorkflowDocument().isProcessed()) {
721                if (!PaymentRequestStatuses.APPDOC_AUTO_APPROVED.equals(getApplicationDocumentStatus())) {
722                    //delete unentered items and update po totals and save po
723                    getOlePaymentRequestService().completePaymentDocument(this);
724                    if(!(SpringContext.getBean(OlePaymentRequestService.class).getPaymentMethod(this.getPaymentMethodId()).equals(OLEConstants.DEPOSIT)))   {
725
726                        this.setApplicationDocumentStatus(PurapConstants.PaymentRequestStatuses.APPDOC_DEPARTMENT_APPROVED);
727                    }
728                    else {
729                        this.setApplicationDocumentStatus(PaymentRequestStatuses.APPDOC_DO_NOT_EXTRACT);
730                    }
731                    populateDocumentForRouting();
732                    getPurapService().saveDocumentNoValidation(this);
733                    return;
734                }
735            }
736            // DOCUMENT DISAPPROVED
737            else if (this.getDocumentHeader().getWorkflowDocument().isDisapproved()) {
738                // String nodeName =
739                // getWorkflowDocumentService().getCurrentRouteLevelName(getDocumentHeader().getWorkflowDocument());
740                String nodeName = getDocumentHeader().getWorkflowDocument().getCurrentNodeNames().iterator().next();
741                HashMap<String, String> disApprovedStatusMap = PurapConstants.PaymentRequestStatuses
742                        .getPaymentRequestAppDocDisapproveStatuses();
743                // NodeDetails currentNode = NodeDetailEnum.getNodeDetailEnumByName(nodeName);
744                // STATUS_ORDER currentNode = STATUS_ORDER.getByStatusCode(nodeName);
745                if (ObjectUtils.isNotNull(nodeName)) {
746                    String newStatusCode = disApprovedStatusMap.get(nodeName);
747                    // currentNode.getDisapprovedStatusCode();
748                    if ((StringUtils.isBlank(newStatusCode))
749                            && ((PaymentRequestStatuses.APPDOC_INITIATE.equals(getApplicationDocumentStatus())) || (PaymentRequestStatuses.APPDOC_IN_PROCESS
750                            .equals(getApplicationDocumentStatus())))) {
751                        newStatusCode = PaymentRequestStatuses.APPDOC_CANCELLED_IN_PROCESS;
752                    }
753                    if (StringUtils.isNotBlank(newStatusCode)) {
754                        getAccountsPayableService().cancelAccountsPayableDocument(this, nodeName);
755                        return;
756                    }
757                }
758                logAndThrowRuntimeException("No status found to set for document being disapproved in node '" + nodeName + "'");
759            }
760            // DOCUMENT CANCELED
761            else if (this.getDocumentHeader().getWorkflowDocument().isCanceled()) {
762                // String currentNodeName =
763                // getWorkflowDocumentService().getCurrentRouteLevelName(this.getDocumentHeader().getWorkflowDocument());
764                // NodeDetails currentNode = NodeDetailEnum.getNodeDetailEnumByName(currentNodeName);
765                String nodeName = getDocumentHeader().getWorkflowDocument().getCurrentNodeNames().iterator().next();
766                HashMap<String, String> disApprovedStatusMap = PurapConstants.PaymentRequestStatuses
767                        .getPaymentRequestAppDocDisapproveStatuses();
768                if (ObjectUtils.isNotNull(nodeName)) {
769                    // String cancelledStatusCode = currentNode.getDisapprovedStatusCode();
770                    String cancelledStatusCode = disApprovedStatusMap.get(nodeName);
771                    if (StringUtils.isNotBlank(cancelledStatusCode)) {
772                        this.setApplicationDocumentStatus(cancelledStatusCode);
773                        getPurapService().saveDocumentNoValidation(this);
774                        return;
775                    }
776                }
777                logAndThrowRuntimeException("No status found to set for document being canceled in node '" + nodeName
778                        + "'");
779            }
780        } catch (Exception e) {
781            logAndThrowRuntimeException("Error saving routing data while saving document with id " + getDocumentNumber(), e);
782        }
783    }
784
785    /**
786     * Sends FYI workflow request to the given user on this document.
787     *
788     * @param workflowDocument the associated workflow document.
789     * @param userNetworkId    the network ID of the user to be sent to.
790     * @param annotation       the annotation notes contained in this document.
791     * @param responsibility   the responsibility specified in the request.
792     * @throws WorkflowException
793     */
794    public void appSpecificRouteDocumentToUser(WorkflowDocument workflowDocument, String userNetworkId,
795                                               String annotation, String responsibility) throws WorkflowException {
796        if (ObjectUtils.isNotNull(workflowDocument)) {
797            String annotationNote = (ObjectUtils.isNull(annotation)) ? "" : annotation;
798            String responsibilityNote = (ObjectUtils.isNull(responsibility)) ? "" : responsibility;
799            String currentNodeName = getCurrentRouteNodeName(workflowDocument);
800            Principal principal = getIdentityManagementService().getPrincipalByPrincipalName(userNetworkId);
801            workflowDocument.adHocToPrincipal(ActionRequestType.FYI, currentNodeName, annotationNote,
802                    principal.getPrincipalId(), responsibilityNote, true);
803        }
804    }
805
806    /**
807     * Returns the name of the current route node.
808     *
809     * @param wd the current workflow document.
810     * @return the name of the current route node.
811     * @throws WorkflowException
812     */
813    protected String getCurrentRouteNodeName(WorkflowDocument wd) throws WorkflowException {
814        // String[] nodeNames = wd.getNodeNames();
815        Set<String> nodeNameSet = wd.getNodeNames();
816        String[] nodeNames = (String[]) nodeNameSet.toArray(); // Here it fails.
817
818        if ((nodeNames == null) || (nodeNames.length == 0)) {
819            return null;
820        } else {
821            return nodeNames[0];
822        }
823    }
824
825    public BigDecimal getForeignVendorInvoiceAmount() {
826        return foreignVendorInvoiceAmount;
827    }
828
829    public void setForeignVendorInvoiceAmount(BigDecimal foreignVendorInvoiceAmount) {
830        this.foreignVendorInvoiceAmount = foreignVendorInvoiceAmount;
831    }
832
833    /**
834     * This method is used to get the bibedtior creat url from propertie file
835     *
836     * @return Bibeditor creat url string
837     */
838    public String getBibeditorCreateURL() {
839        String bibeditorCreateURL = getConfigurationService().getPropertyValueAsString(
840                OLEConstants.BIBEDITOR_CREATE_URL_KEY);
841        return bibeditorCreateURL;
842    }
843
844    public String getBibSearchURL() {
845        String bibSearchURL = getConfigurationService().getPropertyValueAsString(OLEConstants.BIBEDITOR_SEARCH_URL_KEY);
846        return bibSearchURL;
847    }
848    /**
849     * This method is used to get the dublinedtior edit url from propertie file
850     *
851     * @return Dublineditor edit url string
852     */
853    public String getDublinEditorEditURL() {
854        return SpringContext.getBean(OlePurchaseOrderDocumentHelperService.class).getDublinEditorEditURL();
855
856    }
857
858    /**
859     * This method is used to get the dublinedtior view url from propertie file
860     *
861     * @return dublineditor view url string
862     */
863    public String getDublinEditorViewURL() {
864        return SpringContext.getBean(OlePurchaseOrderDocumentHelperService.class).getDublinEditorViewURL();
865    }
866    /**
867     * This method is used to get the bibedtior edit url from propertie file
868     *
869     * @return Bibeditor edit url string
870     */
871    public String getBibeditorEditURL() {
872        String bibeditorEditURL = getConfigurationService().getPropertyValueAsString(OLEConstants.BIBEDITOR_URL_KEY);
873        return bibeditorEditURL;
874    }
875
876    /**
877     * This method is used to get the bibedtior view url from propertie file
878     *
879     * @return Bibeditor view url string
880     */
881    public String getBibeditorViewURL() {
882        String bibeditorViewURL = getConfigurationService().getPropertyValueAsString(OLEConstants.DOCSTORE_APP_URL_KEY);
883        return bibeditorViewURL;
884    }
885
886    /**
887     * This method is used to get the directory path where the marc xml files need to be created
888     *
889     * @return Directory path string
890     */
891    public String getMarcXMLFileDirLocation() throws Exception {
892        String externaleDirectory = getFileProcessingService().getMarcXMLFileDirLocation();
893        return externaleDirectory;
894    }
895
896    @Override
897    public void prepareForSave(KualiDocumentEvent event) {
898        // TODO Auto-generated method stub
899        super.prepareForSave(event);
900        try {
901            if (this.proformaIndicator && !this.immediatePaymentIndicator) {
902                this.setImmediatePaymentIndicator(true);
903            }
904            LOG.debug("###########Inside OlePaymentRequestDocument " + "repareForSave###########");
905            List<OlePaymentRequestItem> items = new ArrayList<OlePaymentRequestItem>();
906            items = this.getItems();
907            Iterator iterator = items.iterator();
908            HashMap dataMap = new HashMap();
909            String titleId;
910            while (iterator.hasNext()) {
911                LOG.debug("###########inside prepareForSave item loop###########");
912                Object object = iterator.next();
913                if (object instanceof OlePaymentRequestItem) {
914                    LOG.debug("###########inside prepareForSave ole payment request item###########");
915                    OlePaymentRequestItem singleItem = (OlePaymentRequestItem) object;
916                    setItemDescription(singleItem);
917                }
918            }
919        } catch (Exception e) {
920            LOG.error("Exception during prepareForSave() in OlePaymentRequestDocument", e);
921            throw new RuntimeException(e);
922        }
923    }
924
925    @Override
926    public KualiDecimal getGrandTotal() {
927        if ((this.prorateBy != null) && (this.prorateBy.equals(OLEConstants.PRORATE_BY_QTY) || this.prorateBy.equals(OLEConstants.PRORATE_BY_DOLLAR) || this.prorateBy.equals(OLEConstants.MANUAL_PRORATE))) {
928            return this.getGrandPreTaxTotal().add(this.getGrandTaxAmount());
929        } else {
930            return super.getGrandTotal();
931        }
932    }
933
934    @Override
935    public KualiDecimal getGrandTotalExcludingDiscount() {
936        String[] discountCode = new String[]{PurapConstants.ItemTypeCodes.ITEM_TYPE_PMT_TERMS_DISCOUNT_CODE};
937        if ((this.prorateBy != null)
938                && (this.prorateBy.equals(OLEConstants.PRORATE_BY_QTY)
939                || this.prorateBy.equals(OLEConstants.PRORATE_BY_DOLLAR) || this.prorateBy
940                .equals(OLEConstants.MANUAL_PRORATE))) {
941            return this.getTotalDollarAmountWithExclusions(discountCode, false);
942        } else {
943            return this.getTotalDollarAmountWithExclusions(discountCode, true);
944        }
945    }
946
947    @Override
948    public KualiDecimal getTotalDollarAmountAllItems(String[] excludedTypes) {
949        if ((this.prorateBy != null)
950                && (this.prorateBy.equals(OLEConstants.PRORATE_BY_QTY)
951                || this.prorateBy.equals(OLEConstants.PRORATE_BY_DOLLAR) || this.prorateBy
952                .equals(OLEConstants.MANUAL_PRORATE))) {
953            return getTotalDollarAmountWithExclusions(excludedTypes, false);
954        } else {
955            return getTotalDollarAmountWithExclusions(excludedTypes, true);
956        }
957    }
958
959    @Override
960    public KualiDecimal getGrandPreTaxTotalExcludingDiscount() {
961        String[] discountCode = new String[]{PurapConstants.ItemTypeCodes.ITEM_TYPE_PMT_TERMS_DISCOUNT_CODE};
962        if ((this.prorateBy != null)
963                && (this.prorateBy.equals(OLEConstants.PRORATE_BY_QTY)
964                || this.prorateBy.equals(OLEConstants.PRORATE_BY_DOLLAR) || this.prorateBy
965                .equals(OLEConstants.MANUAL_PRORATE))) {
966            return this.getTotalPreTaxDollarAmountWithExclusions(discountCode, false);
967        } else {
968            return this.getTotalPreTaxDollarAmountWithExclusions(discountCode, true);
969        }
970    }
971
972    @Override
973    public KualiDecimal getGrandTaxAmountExcludingDiscount() {
974        String[] discountCode = new String[]{PurapConstants.ItemTypeCodes.ITEM_TYPE_PMT_TERMS_DISCOUNT_CODE};
975        if ((this.prorateBy != null)
976                && (this.prorateBy.equals(OLEConstants.PRORATE_BY_QTY)
977                || this.prorateBy.equals(OLEConstants.PRORATE_BY_DOLLAR) || this.prorateBy
978                .equals(OLEConstants.MANUAL_PRORATE))) {
979            return this.getTotalTaxAmountWithExclusions(discountCode, false);
980        } else {
981            return this.getTotalTaxAmountWithExclusions(discountCode, true);
982        }
983    }
984
985
986    @Override
987    public KualiDecimal getTotalPreTaxDollarAmountAboveLineItems() {
988        if ((this.prorateBy != null) && (this.prorateBy.equals(OLEConstants.PRORATE_BY_QTY) || this.prorateBy.equals(OLEConstants.PRORATE_BY_DOLLAR) || this.prorateBy.equals(OLEConstants.MANUAL_PRORATE))) {
989            KualiDecimal addChargeItem = KualiDecimal.ZERO;
990            KualiDecimal lineItemPreTaxTotal = KualiDecimal.ZERO;
991            KualiDecimal prorateSurcharge = KualiDecimal.ZERO;
992            List<OlePaymentRequestItem> item = this.getItems();
993            for (OlePaymentRequestItem items : item) {
994                if (items.getItemType().isQuantityBasedGeneralLedgerIndicator() && items.getExtendedPrice() != null && items.getExtendedPrice().compareTo(KualiDecimal.ZERO) != 0) {
995                    if (items.getItemSurcharge() != null) {
996                        prorateSurcharge = new KualiDecimal(items.getItemSurcharge());
997                    }
998                    addChargeItem = addChargeItem.add(items.getExtendedPrice().subtract(prorateSurcharge.multiply(items.getItemQuantity())));
999                }
1000            }
1001            lineItemPreTaxTotal = addChargeItem;
1002            return lineItemPreTaxTotal;
1003        } else {
1004            return super.getTotalPreTaxDollarAmountAboveLineItems();
1005        }
1006    }
1007
1008    /**
1009     * This method is used to check the status of the document for displaying view and edit buttons in line item
1010     *
1011     * @return boolean
1012     */
1013    public boolean getIsSaved() {
1014        if (this.getDocumentHeader().getWorkflowDocument().isSaved()
1015                || this.getDocumentHeader().getWorkflowDocument().isInitiated()) {
1016            return true;
1017        }
1018        return false;
1019    }
1020
1021    private void setItemDescription(OlePaymentRequestItem singleItem) throws Exception {
1022        if (singleItem.getOleOrderRecord() != null) {
1023            Map<String, ?> bibAssociatedFieldValuesMap = singleItem.getOleOrderRecord().getOleBibRecord().getBibAssociatedFieldsValueMap();
1024            List titleList = (List) bibAssociatedFieldValuesMap.get("Title_search");
1025            String title = titleList != null && !titleList.isEmpty() ? (String) (titleList).get(0) : null;
1026            List authorList = (List) bibAssociatedFieldValuesMap.get("Author_search");
1027            String author = authorList != null && !authorList.isEmpty() ? (String) (authorList).get(0) : null;
1028            List publisherList = (List) bibAssociatedFieldValuesMap.get("Publisher_search");
1029            String publisher = publisherList != null && !publisherList.isEmpty() ? (String) (publisherList).get(0) : null;
1030            List isbnList = (List) bibAssociatedFieldValuesMap.get("020a");
1031            String isbn = isbnList != null && !isbnList.isEmpty() ? (String) (isbnList).get(0) : null;
1032
1033            singleItem.setBibUUID(singleItem.getOleOrderRecord().getOleBibRecord().getBibUUID());
1034            singleItem.setItemDescription(title + "," + author + "," + publisher + "," + isbn);
1035        }
1036    }
1037
1038    public String getProrateBy() {
1039        return prorateBy;
1040    }
1041
1042    public void setProrateBy(String prorateBy) {
1043        this.prorateBy = prorateBy;
1044    }
1045
1046    /**
1047     * This method returns the boolean if the proforma indicator is selected
1048     *
1049     * @return proformaIndicator
1050     */
1051    public boolean isProformaIndicator() {
1052        return proformaIndicator;
1053    }
1054
1055    /**
1056     * This method sets the proforma Indicator
1057     *
1058     * @param proformaIndicator
1059     */
1060
1061    public void setProformaIndicator(boolean proformaIndicator) {
1062        this.proformaIndicator = proformaIndicator;
1063    }
1064
1065    /**
1066     * Payment Request needs to wait for receiving if the receiving requirements have NOT been met.
1067     *
1068     * @return
1069     */
1070    @Override
1071    protected boolean shouldWaitForReceiving() {
1072        // only require if PO was marked to require receiving
1073        if (isReceivingDocumentRequiredIndicator() && !this.proformaIndicator) {
1074            return !isReceivingRequirementMet();
1075        }
1076
1077        //receiving is not required or has already been fulfilled, no need to stop for routing
1078        return false;
1079    }
1080
1081    /**
1082     * Provides answers to the following splits: PurchaseWasReceived VendorIsEmployeeOrNonResidentAlien
1083     *
1084     * @see org.kuali.ole.sys.document.FinancialSystemTransactionalDocumentBase#answerSplitNodeQuestion(java.lang.String)
1085     */
1086    @Override
1087    public boolean answerSplitNodeQuestion(String nodeName) throws UnsupportedOperationException {
1088        if (nodeName.equals(OLEConstants.HAS_VENDOR_DEPOSIT_ACCOUNT)) {
1089            return hasVendorDepositAccount();
1090        }
1091        if (nodeName.equals(OLEConstants.OlePaymentRequest.HAS_INVOICE_TYPE)) {
1092            return hasInvoiceType();
1093        }
1094        if (nodeName.equals(OLEConstants.OlePaymentRequest.HAS_PREPAID_INVOICE_TYPE)) {
1095            return hasPrepaidInvoiceType();
1096        }
1097        if (nodeName.equals(OLEConstants.OlePaymentRequest.HAS_PAYMENT_METHOD)) {
1098            return hasPaymentMethod();
1099        }
1100        if (nodeName.equals(PurapWorkflowConstants.BUDGET_REVIEW_REQUIRED)) {
1101            return isBudgetReviewRequired();
1102        }
1103        if (nodeName.equals(PurapWorkflowConstants.REQUIRES_IMAGE_ATTACHMENT)) {
1104            return requiresAccountsPayableReviewRouting();
1105        }
1106        if (nodeName.equals(PurapWorkflowConstants.PURCHASE_WAS_RECEIVED)) {
1107            return shouldWaitForReceiving();
1108        }
1109        if (nodeName.equals(PurapWorkflowConstants.VENDOR_IS_EMPLOYEE_OR_NON_RESIDENT_ALIEN)) {
1110            return isVendorEmployeeOrNonResidentAlien();
1111        }
1112        if (nodeName.equals(OLEConstants.REQUIRES_SEPARATION_OF_DUTIES)) {
1113            return isSeparationOfDutiesReviewRequired();
1114        }
1115
1116        if (nodeName.equals(PurapWorkflowConstants.NOTIFY_BUDGET_REVIEW)) {
1117            return isNotificationRequired();
1118        }
1119        throw new UnsupportedOperationException("Cannot answer split question for this node you call \"" + nodeName + "\"");
1120    }
1121
1122    private boolean hasInvoiceType() {
1123        if (this.getInvoiceTypeId() != null) {
1124            return true;
1125        }
1126        return false;
1127    }
1128
1129    private boolean hasVendorDepositAccount() {
1130        List<PaymentRequestAccount> sourceAccounts = this.getSourceAccountingLines();
1131        for (PaymentRequestAccount sourceAccount : sourceAccounts) {
1132            if (sourceAccount.getAccount().getSubFundGroupCode().equalsIgnoreCase(OLEConstants.CLEARING_ACCOUNT_CODE)) {
1133                return true;
1134            }
1135        }
1136        return false;
1137    }
1138
1139    private boolean hasPrepaidInvoiceType() {
1140        if (this.getInvoiceTypeId() != null) {
1141            Map<String, String> invoiceMap = new HashMap<String, String>();
1142            invoiceMap.put("invoiceTypeId", this.getInvoiceTypeId().toString());
1143            OleInvoiceType invoiceType = this.getBusinessObjectService().findByPrimaryKey(OleInvoiceType.class,
1144                    invoiceMap);
1145            if (invoiceType != null &&
1146                    invoiceType.getInvoiceType().equals("Prepay") ||
1147                    invoiceType.getInvoiceType().equals("Deposit")) {
1148                return true;
1149            }
1150        }
1151        return false;
1152    }
1153
1154    private boolean hasPaymentMethod() {
1155        if (this.getPaymentMethodId() != null) {
1156            return true;
1157        }
1158        return false;
1159    }
1160
1161    public Set<Person> getAllPriorApprovers() throws WorkflowException {
1162        PersonService personService = KimApiServiceLocator.getPersonService();
1163        List<ActionTaken> actionsTaken = getDocumentHeader().getWorkflowDocument().getActionsTaken();
1164        Set<String> principalIds = new HashSet<String>();
1165        Set<Person> persons = new HashSet<Person>();
1166
1167        for (ActionTaken actionTaken : actionsTaken) {
1168            if (KewApiConstants.ACTION_TAKEN_APPROVED_CD.equals(actionTaken.getActionTaken())) {
1169                String principalId = actionTaken.getPrincipalId();
1170                if (!principalIds.contains(principalId)) {
1171                    principalIds.add(principalId);
1172                    persons.add(personService.getPerson(principalId));
1173                }
1174            }
1175        }
1176        return persons;
1177    }
1178
1179    protected boolean isSeparationOfDutiesReviewRequired() {
1180        try {
1181            Set<Person> priorApprovers = getAllPriorApprovers();
1182
1183            // The initiator cannot be the approver
1184            String initiatorPrincipalId = getDocumentHeader().getWorkflowDocument().getInitiatorPrincipalId();
1185            Person initiator = SpringContext.getBean(PersonService.class).getPerson(initiatorPrincipalId);
1186            // If there is only one approver, and that approver is also the initiator, then Separation of Duties is required.
1187            boolean priorApproverIsInitiator = priorApprovers.contains(initiator);
1188            boolean onlyOneApprover = (priorApprovers.size() == 1);
1189            if (priorApproverIsInitiator && onlyOneApprover) {
1190                return true;
1191            }
1192
1193            // if there are more than 0 prior approvers which means there had been at least another approver than the current approver
1194            // then no need for separation of duties
1195            if (priorApprovers.size() > 0) {
1196                return false;
1197            }
1198        } catch (WorkflowException we) {
1199            LOG.error("Exception while attempting to retrieve all prior approvers from workflow: " + we);
1200        }
1201        return false;
1202    }
1203
1204    public boolean isBudgetReviewRequired() {
1205
1206        OlePaymentRequestFundCheckServiceImpl olePaymentRequestFundCheckServiceImpl = new OlePaymentRequestFundCheckServiceImpl();
1207        boolean required = false;
1208        if((SpringContext.getBean(OlePaymentRequestService.class).getPaymentMethod(this.getPaymentMethodId())).equals(OLEConstants.DEPOSIT)) {
1209            return false;
1210        }
1211        // if document's fiscal year is less than or equal to the current fiscal year
1212        if (SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear().compareTo(getPostingYear()) >= 0) {
1213            List<SourceAccountingLine> sourceAccountingLineList = this.getSourceAccountingLines();
1214            for (SourceAccountingLine accLine : sourceAccountingLineList) {
1215                String chart = accLine.getAccount().getChartOfAccountsCode();
1216                String account = accLine.getAccount().getAccountNumber();
1217                String sfCode = accLine.getAccount().getAccountSufficientFundsCode();
1218                Map<String, Object> key = new HashMap<String, Object>();
1219                key.put(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, chart);
1220                key.put(OLEPropertyConstants.ACCOUNT_NUMBER, account);
1221                OleSufficientFundCheck oleSufficientFundCheck = businessObjectService.findByPrimaryKey(
1222                        OleSufficientFundCheck.class, key);
1223                if (oleSufficientFundCheck != null) {
1224                    String option = oleSufficientFundCheck.getNotificationOption() != null ? oleSufficientFundCheck
1225                            .getNotificationOption() : "";
1226                    if (option.equals(OLEPropertyConstants.BUD_REVIEW)) {
1227                        required = olePaymentRequestFundCheckServiceImpl.hasSufficientFundCheckRequired(accLine);
1228                        return required;
1229                    }
1230                }
1231            }
1232        }
1233        return required;
1234        // get list of sufficientfundItems
1235
1236        // delete and recreate the GL entries for this document so they do not get included in the SF check
1237        // This is *NOT* ideal. The SF service needs to be updated to allow it to provide the current
1238        // document number so that it can be exlcuded from pending entry checks.
1239        // List<GeneralLedgerPendingEntry> pendingEntries = getPendingLedgerEntriesForSufficientFundsChecking();
1240        // dumb loop to just force OJB to load the objects. Otherwise, the proxy object above
1241        // only gets resolved *after* the delete below and no SF check happens.
1242        // for (GeneralLedgerPendingEntry glpe : pendingEntries) {
1243        // glpe.getChartOfAccountsCode();
1244        // }
1245        // SpringContext.getBean(GeneralLedgerPendingEntryService.class).delete(getDocumentNumber());
1246        // List<SufficientFundsItem> fundsItems = SpringContext.getBean(SufficientFundsService.class)
1247        // .checkSufficientFundsForPREQ(pendingEntries);
1248        // SpringContext.getBean(GeneralLedgerPendingEntryService.class).generateGeneralLedgerPendingEntries(this);
1249        // SpringContext.getBean(BusinessObjectService.class).save(getGeneralLedgerPendingEntries());
1250        // if (fundsItems.size() > 0) {
1251        // return true;
1252        // }
1253        // }
1254        //
1255        // return false;
1256    }
1257
1258    private boolean isNotificationRequired() {
1259        OleRequisitionDocumentService oleRequisitionDocumentService = (OleRequisitionDocumentService) SpringContext
1260                .getBean("oleRequisitionDocumentService");
1261        List<SourceAccountingLine> sourceAccountingLineList = this.getSourceAccountingLines();
1262        boolean sufficientFundCheck = false;
1263        for (SourceAccountingLine accLine : sourceAccountingLineList) {
1264            Map searchMap = new HashMap();
1265            String notificationOption = null;
1266            Map<String, Object> key = new HashMap<String, Object>();
1267            String chartCode = accLine.getChartOfAccountsCode();
1268            String accNo = accLine.getAccountNumber();
1269            String objectCd = accLine.getFinancialObjectCode();
1270            key.put(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, chartCode);
1271            key.put(OLEPropertyConstants.ACCOUNT_NUMBER, accNo);
1272            OleSufficientFundCheck account = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(
1273                    OleSufficientFundCheck.class, key);
1274            if (account != null) {
1275                notificationOption = account.getNotificationOption();
1276            }
1277            if (notificationOption != null && notificationOption.equals(OLEPropertyConstants.NOTIFICATION)) {
1278                sufficientFundCheck = true;
1279            }
1280        }
1281        return sufficientFundCheck;
1282    }
1283
1284    @Override
1285    protected void populateAccountsForRouting() {
1286
1287        // if(this.getDocumentHeader().ge)
1288        List<SufficientFundsItem> fundsItems = new ArrayList<SufficientFundsItem>();
1289        try {
1290            // String nodeName =
1291            // SpringContext.getBean(WorkflowDocumentService.class).getCurrentRouteLevelName(getFinancialSystemDocumentHeader().getWorkflowDocument());
1292            if(getFinancialSystemDocumentHeader() != null){
1293                String documentNumber = this.getDocumentNumber();
1294                if(documentNumber != null){
1295                WorkflowDocument workflowDocument = null;
1296                workflowDocument = KRADServiceLocatorWeb.getWorkflowDocumentService().loadWorkflowDocument(this.getDocumentNumber(), SpringContext.getBean(PersonService.class).getPerson(GlobalVariables.getUserSession().getPerson().getPrincipalId()));
1297                getFinancialSystemDocumentHeader().setWorkflowDocument(workflowDocument);
1298                }
1299            }
1300            String nodeName = getFinancialSystemDocumentHeader().getWorkflowDocument().getCurrentNodeNames().iterator()
1301                    .next();
1302            if (nodeName != null
1303                    && (nodeName.equalsIgnoreCase(PurapWorkflowConstants.BUDGET_NODE) || nodeName
1304                    .equalsIgnoreCase(PurapWorkflowConstants.BUDGET_REVIEW_REQUIRED))) {
1305                if (SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear()
1306                        .compareTo(getPostingYear()) >= 0) {
1307                    List<GeneralLedgerPendingEntry> pendingEntries = getPendingLedgerEntriesForSufficientFundsChecking();
1308                    for (GeneralLedgerPendingEntry glpe : pendingEntries) {
1309                        glpe.getChartOfAccountsCode();
1310                    }
1311                    // SpringContext.getBean(GeneralLedgerPendingEntryService.class).delete(getDocumentNumber());
1312                    fundsItems = SpringContext.getBean(SufficientFundsService.class).checkSufficientFundsForPREQ(
1313                            pendingEntries);
1314                    // SpringContext.getBean(GeneralLedgerPendingEntryService.class).generateGeneralLedgerPendingEntries(
1315                    // this);
1316                    // SpringContext.getBean(BusinessObjectService.class).save(getGeneralLedgerPendingEntries());
1317                }
1318                SpringContext.getBean(PurapAccountingService.class).updateAccountAmounts(this);
1319                accountsForRouting = (SpringContext.getBean(PurapAccountingService.class).generateSummary(getItems()));
1320                String documentFiscalYearString = this.getPostingYear().toString();
1321                List<String> fundsItemList = new ArrayList<String>();
1322                List<String> accountsList = new ArrayList<String>();
1323                for (SufficientFundsItem fundsItem : fundsItems) {
1324                    fundsItemList.add(fundsItem.getAccount().getChartOfAccountsCode());
1325                }
1326                for (Iterator accountsForRoutingIter = accountsForRouting.iterator(); accountsForRoutingIter.hasNext(); ) {
1327                    if (!(fundsItemList.contains(((SourceAccountingLine) accountsForRoutingIter.next())
1328                            .getChartOfAccountsCode()))) {
1329                        accountsForRoutingIter.remove();
1330                    }
1331                }
1332                setAccountsForRouting(accountsForRouting);
1333                // need to refresh to get the references for the searchable attributes (ie status) and for invoking route levels (ie
1334                // account
1335                // objects) -hjs
1336                refreshNonUpdateableReferences();
1337                for (SourceAccountingLine sourceLine : getAccountsForRouting()) {
1338                    sourceLine.refreshNonUpdateableReferences();
1339                }
1340            } else {
1341                super.populateAccountsForRouting();
1342            }
1343        } catch (Exception e) {
1344            logAndThrowRuntimeException("Error in populateAccountsForRouting while submitting document with id "
1345                    + getDocumentNumber(), e);
1346        }
1347
1348    }
1349
1350    /**
1351     * @see org.kuali.rice.krad.document.DocumentBase#doRouteLevelChange(org.kuali.rice.kew.framework.postprocessor.DocumentRouteLevelChange)
1352     */
1353    @Override
1354    public void doRouteLevelChange(DocumentRouteLevelChange levelChangeEvent) {
1355
1356        super.doRouteLevelChange(levelChangeEvent);
1357        try {
1358            String newNodeName = levelChangeEvent.getNewNodeName();
1359            List<String> desiredActions = new ArrayList<String>(2);
1360            RoutingReportCriteria.Builder reportCriteria = RoutingReportCriteria.Builder
1361                    .createByDocumentIdAndTargetNodeName(getDocumentNumber(), newNodeName);
1362            desiredActions.add(ActionRequestType.APPROVE.getCode());
1363            desiredActions.add(ActionRequestType.COMPLETE.getCode());
1364            if (KewApiServiceLocator.getWorkflowDocumentActionsService().documentWillHaveAtLeastOneActionRequest(
1365                    reportCriteria.build(), desiredActions, false)) {
1366                if (StringUtils.isNotBlank(newNodeName)) {
1367                    if (StringUtils.isNotBlank(newNodeName)) {
1368                        if (newNodeName.equalsIgnoreCase(PurapWorkflowConstants.BUDGET_NODE)
1369                                || newNodeName.equalsIgnoreCase(PurapWorkflowConstants.FYI_BUDGET)) {
1370                            String note = OLEConstants.SufficientFundCheck.PREQ_NOTE;
1371                            DocumentService documentService = SpringContext.getBean(DocumentService.class);
1372                            Note apoNote = documentService.createNoteFromDocument(this, note);
1373                            this.addNote(apoNote);
1374                            documentService.saveDocumentNotes(this);
1375                        }
1376                    }
1377                }
1378            }
1379        } catch (Exception e) {
1380            String errorMsg = "Workflow Error found checking actions requests on document with id "
1381                    + getDocumentNumber() + ". *** WILL NOT UPDATE PURAP STATUS ***";
1382            LOG.error(errorMsg, e);
1383        }
1384    }
1385
1386    private void populateVendorAliasName() {
1387        Map vendorDetailMap = new HashMap();
1388        vendorDetailMap.put(OLEConstants.VENDOR_HEADER_IDENTIFIER, this.getVendorHeaderGeneratedIdentifier());
1389        vendorDetailMap.put(OLEConstants.VENDOR_DETAIL_IDENTIFIER, this.getVendorDetailAssignedIdentifier());
1390        List<VendorAlias> vendorDetailList = (List) getBusinessObjectService().findMatching(VendorAlias.class, vendorDetailMap);
1391        if (vendorDetailList != null && vendorDetailList.size() > 0) {
1392            this.setVendorAliasName(vendorDetailList.get(0).getVendorAliasName());
1393        }
1394    }
1395    
1396    @Override
1397    public boolean generateGeneralLedgerPendingEntries(GeneralLedgerPendingEntrySourceDetail glpeSourceDetail, GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
1398        LOG.debug("processGenerateGeneralLedgerPendingEntries(AccountingDocument, AccountingLine, GeneralLedgerPendingEntrySequenceHelper) - start");
1399
1400        // handle the explicit entry
1401        // create a reference to the explicitEntry to be populated, so we can pass to the offset method later
1402        GeneralLedgerPendingEntry explicitEntry = new GeneralLedgerPendingEntry();
1403        processExplicitGeneralLedgerPendingEntry(sequenceHelper, glpeSourceDetail, explicitEntry);
1404        // increment the sequence counter
1405        sequenceHelper.increment();
1406
1407        // handle the offset entry
1408
1409        GeneralLedgerPendingEntry offsetEntry = new GeneralLedgerPendingEntry(explicitEntry);
1410        boolean success = processOffsetGeneralLedgerPendingEntry(sequenceHelper, glpeSourceDetail, explicitEntry, offsetEntry);
1411
1412        LOG.debug("processGenerateGeneralLedgerPendingEntries(AccountingDocument, AccountingLine, GeneralLedgerPendingEntrySequenceHelper) - end");
1413        return success;
1414    }
1415
1416    /**
1417     * This method processes an accounting line's information to build an offset entry, and then adds that to the document.
1418     *
1419     * @param sequenceHelper
1420     * @param explicitEntry
1421     * @param offsetEntry
1422     * @return boolean True if the offset generation is successful.
1423     */
1424    protected boolean processOffsetGeneralLedgerPendingEntry(GeneralLedgerPendingEntrySequenceHelper sequenceHelper, GeneralLedgerPendingEntrySourceDetail postable, GeneralLedgerPendingEntry explicitEntry, GeneralLedgerPendingEntry offsetEntry) {
1425        LOG.debug("processOffsetGeneralLedgerPendingEntry(AccountingDocument, GeneralLedgerPendingEntrySequenceHelper, AccountingLine, GeneralLedgerPendingEntry, GeneralLedgerPendingEntry) - start");
1426
1427        // populate the offset entry
1428        boolean success = SpringContext.getBean(GeneralLedgerPendingEntryService.class).populateOffsetGeneralLedgerPendingEntry(getPostingYear(), explicitEntry, sequenceHelper, offsetEntry);
1429
1430        // hook for children documents to implement document specific field mappings for the GLPE
1431        success &= customizeOffsetGeneralLedgerPendingEntry(postable, explicitEntry, offsetEntry);
1432
1433        if (SpringContext.getBean(OlePaymentRequestService.class).getPaymentMethod(this.getPaymentMethodId()).equals(OLEConstants.DEPOSIT)) {
1434            if (offsetEntry.getFinancialBalanceTypeCode().equals(OLEConstants.BALANCE_TYPE_ACTUAL) && offsetEntry.isTransactionEntryOffsetIndicator()) {
1435                Integer purapDocumentIdentifier = this.getPurapDocumentIdentifier();
1436                Map itemMap = new HashMap();
1437                itemMap.put("purapDocumentIdentifier", purapDocumentIdentifier);
1438                List<OlePaymentRequestItem> paymentRequestItems = (List<OlePaymentRequestItem>) getBusinessObjectService().findMatching(OlePaymentRequestItem.class, itemMap);
1439                if (paymentRequestItems.size() > 0) {
1440                    for (OlePaymentRequestItem item : paymentRequestItems) {
1441                        for (int i = 0; i < item.getSourceAccountingLines().size(); i++) {
1442                            if (item.getSourceAccountingLine(i).getAccountNumber().equals(explicitEntry.getAccountNumber())) {
1443                                Integer poItemIdentifier = item.getPoItemIdentifier();
1444                                Map offMap = new HashMap();
1445                                offMap.put("itemIdentifier", poItemIdentifier);
1446                                List<OLEInvoiceOffsetAccountingLine> offsetAccountingLines = (List<OLEInvoiceOffsetAccountingLine>) getBusinessObjectService().findMatching(OLEInvoiceOffsetAccountingLine.class, offMap);
1447                                if (offsetAccountingLines.size() > 0) {
1448                                    int size = offsetAccountingLines.size();
1449                                    for (OLEInvoiceOffsetAccountingLine accLine : offsetAccountingLines) {
1450                                        offsetEntry.setChartOfAccountsCode(accLine.getChartOfAccountsCode());
1451                                        offsetEntry.setAccountNumber(accLine.getAccountNumber());
1452                                        offsetEntry.setFinancialObjectCode(accLine.getFinancialObjectCode());
1453                                        offsetEntry.setFinancialBalanceTypeCode("AC");
1454                                        offsetEntry.setFinancialObjectTypeCode("AS");
1455                                        offsetEntry.setTransactionDebitCreditCode(OLEConstants.GL_CREDIT_CODE);
1456                                        offsetEntry.setTransactionLedgerEntryAmount(accLine.getAmount());
1457                                        offsetEntry.setAcctSufficientFundsFinObjCd(accLine.getFinancialObjectCode());
1458                                        addPendingEntry(offsetEntry);
1459                                    }
1460                                }
1461                            }
1462                        }
1463                    }
1464                }
1465
1466            } else {
1467                addPendingEntry(offsetEntry);
1468            }
1469        } else {
1470            addPendingEntry(offsetEntry);
1471        }
1472
1473        LOG.debug("processOffsetGeneralLedgerPendingEntry(AccountingDocument, GeneralLedgerPendingEntrySequenceHelper, AccountingLine, GeneralLedgerPendingEntry, GeneralLedgerPendingEntry) - end");
1474        return success;
1475    }
1476
1477
1478    /**
1479     * This method processes all necessary information to build an explicit general ledger entry, and then adds that to the
1480     * document.
1481     *
1482     * @param sequenceHelper
1483     * @param explicitEntry
1484     * @return boolean True if the explicit entry generation was successful, false otherwise.
1485     */
1486    protected void processExplicitGeneralLedgerPendingEntry(GeneralLedgerPendingEntrySequenceHelper sequenceHelper, GeneralLedgerPendingEntrySourceDetail glpeSourceDetail, GeneralLedgerPendingEntry explicitEntry) {
1487        LOG.debug("processExplicitGeneralLedgerPendingEntry(AccountingDocument, GeneralLedgerPendingEntrySequenceHelper, AccountingLine, GeneralLedgerPendingEntry) - start");
1488
1489        // populate the explicit entry
1490        SpringContext.getBean(GeneralLedgerPendingEntryService.class).populateExplicitGeneralLedgerPendingEntry(this, glpeSourceDetail, sequenceHelper, explicitEntry);
1491
1492        // hook for children documents to implement document specific GLPE field mappings
1493        customizeExplicitGeneralLedgerPendingEntry(glpeSourceDetail, explicitEntry);
1494
1495        if ((SpringContext.getBean(OlePaymentRequestService.class).getPaymentMethod(this.getPaymentMethodId()).equals(OLEConstants.DEPOSIT)) && explicitEntry.getFinancialBalanceTypeCode().equals(OLEConstants.BALANCE_TYPE_ACTUAL)) {
1496            explicitEntry.setTransactionDebitCreditCode(OLEConstants.GL_DEBIT_CODE);
1497            addPendingEntry(explicitEntry);
1498        } else {
1499            addPendingEntry(explicitEntry);
1500        }
1501
1502        LOG.debug("processExplicitGeneralLedgerPendingEntry(AccountingDocument, GeneralLedgerPendingEntrySequenceHelper, AccountingLine, GeneralLedgerPendingEntry) - end");
1503    }
1504
1505}
1506