View Javadoc
1   /*
2    * Copyright 2011 The Kuali Foundation.
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.select.document;
17  
18  import org.apache.commons.lang.StringEscapeUtils;
19  import org.apache.commons.lang.StringUtils;
20  import org.kuali.ole.docstore.common.client.DocstoreClient;
21  import org.kuali.ole.docstore.common.client.DocstoreClientLocator;
22  import org.kuali.ole.docstore.common.client.DocstoreClientLocatorService;
23  import org.kuali.ole.docstore.common.client.DocstoreRestClient;
24  import org.kuali.ole.docstore.common.client.impl.DocstoreClientLocatorServiceImpl;
25  import org.kuali.ole.docstore.common.document.Bib;
26  import org.kuali.ole.docstore.common.document.BibMarc;
27  import org.kuali.ole.DocumentUniqueIDPrefix;
28  import org.kuali.ole.gl.service.SufficientFundsService;
29  import org.kuali.ole.module.purap.PurapConstants;
30  import org.kuali.ole.module.purap.PurapConstants.PaymentRequestStatuses;
31  import org.kuali.ole.module.purap.PurapParameterConstants;
32  import org.kuali.ole.module.purap.PurapWorkflowConstants;
33  import org.kuali.ole.module.purap.businessobject.*;
34  import org.kuali.ole.module.purap.document.PaymentRequestDocument;
35  import org.kuali.ole.module.purap.document.PurchaseOrderDocument;
36  import org.kuali.ole.module.purap.document.service.AccountsPayableService;
37  import org.kuali.ole.module.purap.document.service.PaymentRequestService;
38  import org.kuali.ole.module.purap.document.service.PurapService;
39  import org.kuali.ole.module.purap.service.PurapAccountingService;
40  import org.kuali.ole.module.purap.util.ExpiredOrClosedAccountEntry;
41  import org.kuali.ole.select.OleSelectConstant;
42  import org.kuali.ole.select.bo.OLELinkPurapDonor;
43  import org.kuali.ole.select.businessobject.*;
44  import org.kuali.ole.select.document.service.OlePaymentRequestService;
45  import org.kuali.ole.select.document.service.OlePurchaseOrderDocumentHelperService;
46  import org.kuali.ole.select.document.service.OleRequisitionDocumentService;
47  import org.kuali.ole.select.document.service.impl.OlePaymentRequestFundCheckServiceImpl;
48  import org.kuali.ole.select.service.BibInfoService;
49  import org.kuali.ole.select.service.BibInfoWrapperService;
50  import org.kuali.ole.select.service.FileProcessingService;
51  import org.kuali.ole.select.service.impl.BibInfoServiceImpl;
52  import org.kuali.ole.sys.OLEConstants;
53  import org.kuali.ole.sys.OLEPropertyConstants;
54  import org.kuali.ole.sys.businessobject.*;
55  import org.kuali.ole.sys.context.SpringContext;
56  import org.kuali.ole.sys.service.GeneralLedgerPendingEntryService;
57  import org.kuali.ole.sys.service.UniversityDateService;
58  import org.kuali.ole.vnd.VendorConstants;
59  import org.kuali.ole.vnd.businessobject.OleExchangeRate;
60  import org.kuali.ole.vnd.businessobject.VendorAddress;
61  import org.kuali.ole.vnd.businessobject.VendorAlias;
62  import org.kuali.ole.vnd.document.service.VendorService;
63  import org.kuali.rice.core.api.config.property.ConfigurationService;
64  import org.kuali.rice.core.api.datetime.DateTimeService;
65  import org.kuali.rice.core.api.util.type.KualiDecimal;
66  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
67  import org.kuali.rice.kew.api.KewApiConstants;
68  import org.kuali.rice.kew.api.KewApiServiceLocator;
69  import org.kuali.rice.kew.api.WorkflowDocument;
70  import org.kuali.rice.kew.api.action.ActionRequestType;
71  import org.kuali.rice.kew.api.action.ActionTaken;
72  import org.kuali.rice.kew.api.action.RoutingReportCriteria;
73  import org.kuali.rice.kew.api.exception.WorkflowException;
74  import org.kuali.rice.kew.framework.postprocessor.DocumentRouteLevelChange;
75  import org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange;
76  import org.kuali.rice.kim.api.identity.Person;
77  import org.kuali.rice.kim.api.identity.PersonService;
78  import org.kuali.rice.kim.api.identity.principal.Principal;
79  import org.kuali.rice.kim.api.services.IdentityManagementService;
80  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
81  import org.kuali.rice.krad.bo.Note;
82  import org.kuali.rice.krad.rules.rule.event.KualiDocumentEvent;
83  import org.kuali.rice.krad.service.BusinessObjectService;
84  import org.kuali.rice.krad.service.DocumentService;
85  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
86  import org.kuali.rice.krad.util.GlobalVariables;
87  import org.kuali.rice.krad.util.ObjectUtils;
88  import org.kuali.rice.krad.workflow.service.WorkflowDocumentService;
89  import java.math.BigDecimal;
90  import java.math.RoundingMode;
91  import java.util.*;
92  
93  
94  /**
95   * This class is the document class for Ole Payment Request
96   */
97  
98  public class OlePaymentRequestDocument extends PaymentRequestDocument {
99  
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.substring(0, itemDescription.lastIndexOf(","));
669                         StringEscapeUtils stringEscapeUtils = new StringEscapeUtils();
670                         itemDescription = stringEscapeUtils.unescapeXml(itemDescription);
671                         singleItem.setItemDescription(itemDescription);
672                     }
673                     HashMap<String, String> queryMap = new HashMap<String, String>();
674                     if (singleItem.getPoItemIdentifier() != null) {
675                         queryMap.put(OLEConstants.PO_ITEM_ID, singleItem.getPoItemIdentifier().toString());
676                         OleInvoiceItem oleInvoiceItem = getBusinessObjectService().findByPrimaryKey(OleInvoiceItem.class, queryMap);
677                         if (oleInvoiceItem != null && oleInvoiceItem.getPoItemIdentifier() != null) {
678                             queryMap.clear();
679                             queryMap.put(OLEConstants.OleCopy.PO_ITM_ID, oleInvoiceItem.getPoItemIdentifier().toString());
680                             List<OLELinkPurapDonor> oleLinkPurapDonorList = (List<OLELinkPurapDonor>) getBusinessObjectService().findMatching(OLELinkPurapDonor.class, queryMap);
681                             if (oleLinkPurapDonorList != null) {
682                                 singleItem.setOleDonors(oleLinkPurapDonorList);
683                             }
684                         }
685                     }
686                 }
687                 for(OLEPaidCopy olePaidCopy : singleItem.getPaidCopies()){
688                     if(olePaidCopy.getPaymentRequestItemId()==null && olePaidCopy.getPaymentRequestIdentifier()==null){
689                         olePaidCopy.setPaymentRequestItemId(singleItem.getItemIdentifier());
690                         olePaidCopy.setPaymentRequestIdentifier(this.getPurapDocumentIdentifier());
691                         getBusinessObjectService().save(olePaidCopy);
692                     }
693                 }
694             }
695             if (this.getProrateBy() != null) {
696                 this.setProrateQty(this.getProrateBy().equals(OLEConstants.PRORATE_BY_QTY));
697                 this.setProrateManual(this.getProrateBy().equals(OLEConstants.MANUAL_PRORATE));
698                 this.setProrateDollar(this.getProrateBy().equals(OLEConstants.PRORATE_BY_DOLLAR));
699                 this.setNoProrate(this.getProrateBy().equals(OLEConstants.NO_PRORATE));
700             }
701         } catch (Exception e) {
702             LOG.error("Exception during processAfterRetrieve() in OlePaymentRequestDocument", e);
703             throw new RuntimeException(e);
704         }
705     }
706 
707     /**
708      * This method is overrided to create POA from new Line Item of PaymentRequest
709      *
710      * @see org.kuali.ole.module.purap.document.PaymentRequestDocument#doRouteStatusChange(org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange)
711      */
712     @Override
713     public void doRouteStatusChange(DocumentRouteStatusChange statusChangeEvent) {
714         LOG.debug("doRouteStatusChange() started");
715 
716         super.doRouteStatusChange(statusChangeEvent);
717         try {
718             // DOCUMENT PROCESSED
719             if (this.getDocumentHeader().getWorkflowDocument().isProcessed()) {
720                 if (!PaymentRequestStatuses.APPDOC_AUTO_APPROVED.equals(getApplicationDocumentStatus())) {
721                     //delete unentered items and update po totals and save po
722                     getOlePaymentRequestService().completePaymentDocument(this);
723                     if(!(SpringContext.getBean(OlePaymentRequestService.class).getPaymentMethod(this.getPaymentMethodId()).equals(OLEConstants.DEPOSIT)))   {
724 
725                         this.setApplicationDocumentStatus(PurapConstants.PaymentRequestStatuses.APPDOC_DEPARTMENT_APPROVED);
726                     }
727                     else {
728                         this.setApplicationDocumentStatus(PaymentRequestStatuses.APPDOC_DO_NOT_EXTRACT);
729                     }
730                     populateDocumentForRouting();
731                     getPurapService().saveDocumentNoValidation(this);
732                     return;
733                 }
734             }
735             // DOCUMENT DISAPPROVED
736             else if (this.getDocumentHeader().getWorkflowDocument().isDisapproved()) {
737                 // String nodeName =
738                 // getWorkflowDocumentService().getCurrentRouteLevelName(getDocumentHeader().getWorkflowDocument());
739                 String nodeName = getDocumentHeader().getWorkflowDocument().getCurrentNodeNames().iterator().next();
740                 HashMap<String, String> disApprovedStatusMap = PurapConstants.PaymentRequestStatuses
741                         .getPaymentRequestAppDocDisapproveStatuses();
742                 // NodeDetails currentNode = NodeDetailEnum.getNodeDetailEnumByName(nodeName);
743                 // STATUS_ORDER currentNode = STATUS_ORDER.getByStatusCode(nodeName);
744                 if (ObjectUtils.isNotNull(nodeName)) {
745                     String newStatusCode = disApprovedStatusMap.get(nodeName);
746                     // currentNode.getDisapprovedStatusCode();
747                     if ((StringUtils.isBlank(newStatusCode))
748                             && ((PaymentRequestStatuses.APPDOC_INITIATE.equals(getApplicationDocumentStatus())) || (PaymentRequestStatuses.APPDOC_IN_PROCESS
749                             .equals(getApplicationDocumentStatus())))) {
750                         newStatusCode = PaymentRequestStatuses.APPDOC_CANCELLED_IN_PROCESS;
751                     }
752                     if (StringUtils.isNotBlank(newStatusCode)) {
753                         getAccountsPayableService().cancelAccountsPayableDocument(this, nodeName);
754                         return;
755                     }
756                 }
757                 logAndThrowRuntimeException("No status found to set for document being disapproved in node '" + nodeName + "'");
758             }
759             // DOCUMENT CANCELED
760             else if (this.getDocumentHeader().getWorkflowDocument().isCanceled()) {
761                 // String currentNodeName =
762                 // getWorkflowDocumentService().getCurrentRouteLevelName(this.getDocumentHeader().getWorkflowDocument());
763                 // NodeDetails currentNode = NodeDetailEnum.getNodeDetailEnumByName(currentNodeName);
764                 String nodeName = getDocumentHeader().getWorkflowDocument().getCurrentNodeNames().iterator().next();
765                 HashMap<String, String> disApprovedStatusMap = PurapConstants.PaymentRequestStatuses
766                         .getPaymentRequestAppDocDisapproveStatuses();
767                 if (ObjectUtils.isNotNull(nodeName)) {
768                     // String cancelledStatusCode = currentNode.getDisapprovedStatusCode();
769                     String cancelledStatusCode = disApprovedStatusMap.get(nodeName);
770                     if (StringUtils.isNotBlank(cancelledStatusCode)) {
771                         this.setApplicationDocumentStatus(cancelledStatusCode);
772                         getPurapService().saveDocumentNoValidation(this);
773                         return;
774                     }
775                 }
776                 logAndThrowRuntimeException("No status found to set for document being canceled in node '" + nodeName
777                         + "'");
778             }
779         } catch (Exception e) {
780             logAndThrowRuntimeException("Error saving routing data while saving document with id " + getDocumentNumber(), e);
781         }
782     }
783 
784     /**
785      * Sends FYI workflow request to the given user on this document.
786      *
787      * @param workflowDocument the associated workflow document.
788      * @param userNetworkId    the network ID of the user to be sent to.
789      * @param annotation       the annotation notes contained in this document.
790      * @param responsibility   the responsibility specified in the request.
791      * @throws WorkflowException
792      */
793     public void appSpecificRouteDocumentToUser(WorkflowDocument workflowDocument, String userNetworkId,
794                                                String annotation, String responsibility) throws WorkflowException {
795         if (ObjectUtils.isNotNull(workflowDocument)) {
796             String annotationNote = (ObjectUtils.isNull(annotation)) ? "" : annotation;
797             String responsibilityNote = (ObjectUtils.isNull(responsibility)) ? "" : responsibility;
798             String currentNodeName = getCurrentRouteNodeName(workflowDocument);
799             Principal principal = getIdentityManagementService().getPrincipalByPrincipalName(userNetworkId);
800             workflowDocument.adHocToPrincipal(ActionRequestType.FYI, currentNodeName, annotationNote,
801                     principal.getPrincipalId(), responsibilityNote, true);
802         }
803     }
804 
805     /**
806      * Returns the name of the current route node.
807      *
808      * @param wd the current workflow document.
809      * @return the name of the current route node.
810      * @throws WorkflowException
811      */
812     protected String getCurrentRouteNodeName(WorkflowDocument wd) throws WorkflowException {
813         // String[] nodeNames = wd.getNodeNames();
814         Set<String> nodeNameSet = wd.getNodeNames();
815         String[] nodeNames = (String[]) nodeNameSet.toArray(); // Here it fails.
816 
817         if ((nodeNames == null) || (nodeNames.length == 0)) {
818             return null;
819         } else {
820             return nodeNames[0];
821         }
822     }
823 
824     public BigDecimal getForeignVendorInvoiceAmount() {
825         return foreignVendorInvoiceAmount;
826     }
827 
828     public void setForeignVendorInvoiceAmount(BigDecimal foreignVendorInvoiceAmount) {
829         this.foreignVendorInvoiceAmount = foreignVendorInvoiceAmount;
830     }
831 
832     /**
833      * This method is used to get the bibedtior creat url from propertie file
834      *
835      * @return Bibeditor creat url string
836      */
837     public String getBibeditorCreateURL() {
838         String bibeditorCreateURL = getConfigurationService().getPropertyValueAsString(
839                 OLEConstants.BIBEDITOR_CREATE_URL_KEY);
840         return bibeditorCreateURL;
841     }
842 
843     public String getBibSearchURL() {
844         String bibSearchURL = getConfigurationService().getPropertyValueAsString(OLEConstants.BIBEDITOR_SEARCH_URL_KEY);
845         return bibSearchURL;
846     }
847     /**
848      * This method is used to get the dublinedtior edit url from propertie file
849      *
850      * @return Dublineditor edit url string
851      */
852     public String getDublinEditorEditURL() {
853         return SpringContext.getBean(OlePurchaseOrderDocumentHelperService.class).getDublinEditorEditURL();
854 
855     }
856 
857     /**
858      * This method is used to get the dublinedtior view url from propertie file
859      *
860      * @return dublineditor view url string
861      */
862     public String getDublinEditorViewURL() {
863         return SpringContext.getBean(OlePurchaseOrderDocumentHelperService.class).getDublinEditorViewURL();
864     }
865     /**
866      * This method is used to get the bibedtior edit url from propertie file
867      *
868      * @return Bibeditor edit url string
869      */
870     public String getBibeditorEditURL() {
871         String bibeditorEditURL = getConfigurationService().getPropertyValueAsString(OLEConstants.BIBEDITOR_URL_KEY);
872         return bibeditorEditURL;
873     }
874 
875     /**
876      * This method is used to get the bibedtior view url from propertie file
877      *
878      * @return Bibeditor view url string
879      */
880     public String getBibeditorViewURL() {
881         String bibeditorViewURL = getConfigurationService().getPropertyValueAsString(OLEConstants.DOCSTORE_APP_URL_KEY);
882         return bibeditorViewURL;
883     }
884 
885     /**
886      * This method is used to get the directory path where the marc xml files need to be created
887      *
888      * @return Directory path string
889      */
890     public String getMarcXMLFileDirLocation() throws Exception {
891         String externaleDirectory = getFileProcessingService().getMarcXMLFileDirLocation();
892         return externaleDirectory;
893     }
894 
895     @Override
896     public void prepareForSave(KualiDocumentEvent event) {
897         // TODO Auto-generated method stub
898         super.prepareForSave(event);
899         try {
900             if (this.proformaIndicator && !this.immediatePaymentIndicator) {
901                 this.setImmediatePaymentIndicator(true);
902             }
903             LOG.debug("###########Inside OlePaymentRequestDocument " + "repareForSave###########");
904             List<OlePaymentRequestItem> items = new ArrayList<OlePaymentRequestItem>();
905             items = this.getItems();
906             Iterator iterator = items.iterator();
907             HashMap dataMap = new HashMap();
908             String titleId;
909             while (iterator.hasNext()) {
910                 LOG.debug("###########inside prepareForSave item loop###########");
911                 Object object = iterator.next();
912                 if (object instanceof OlePaymentRequestItem) {
913                     LOG.debug("###########inside prepareForSave ole payment request item###########");
914                     OlePaymentRequestItem singleItem = (OlePaymentRequestItem) object;
915                     setItemDescription(singleItem);
916                 }
917             }
918         } catch (Exception e) {
919             LOG.error("Exception during prepareForSave() in OlePaymentRequestDocument", e);
920             throw new RuntimeException(e);
921         }
922     }
923 
924     @Override
925     public KualiDecimal getGrandTotal() {
926         if ((this.prorateBy != null) && (this.prorateBy.equals(OLEConstants.PRORATE_BY_QTY) || this.prorateBy.equals(OLEConstants.PRORATE_BY_DOLLAR) || this.prorateBy.equals(OLEConstants.MANUAL_PRORATE))) {
927             return this.getGrandPreTaxTotal().add(this.getGrandTaxAmount());
928         } else {
929             return super.getGrandTotal();
930         }
931     }
932 
933     @Override
934     public KualiDecimal getGrandTotalExcludingDiscount() {
935         String[] discountCode = new String[]{PurapConstants.ItemTypeCodes.ITEM_TYPE_PMT_TERMS_DISCOUNT_CODE};
936         if ((this.prorateBy != null)
937                 && (this.prorateBy.equals(OLEConstants.PRORATE_BY_QTY)
938                 || this.prorateBy.equals(OLEConstants.PRORATE_BY_DOLLAR) || this.prorateBy
939                 .equals(OLEConstants.MANUAL_PRORATE))) {
940             return this.getTotalDollarAmountWithExclusions(discountCode, false);
941         } else {
942             return this.getTotalDollarAmountWithExclusions(discountCode, true);
943         }
944     }
945 
946     @Override
947     public KualiDecimal getTotalDollarAmountAllItems(String[] excludedTypes) {
948         if ((this.prorateBy != null)
949                 && (this.prorateBy.equals(OLEConstants.PRORATE_BY_QTY)
950                 || this.prorateBy.equals(OLEConstants.PRORATE_BY_DOLLAR) || this.prorateBy
951                 .equals(OLEConstants.MANUAL_PRORATE))) {
952             return getTotalDollarAmountWithExclusions(excludedTypes, false);
953         } else {
954             return getTotalDollarAmountWithExclusions(excludedTypes, true);
955         }
956     }
957 
958     @Override
959     public KualiDecimal getGrandPreTaxTotalExcludingDiscount() {
960         String[] discountCode = new String[]{PurapConstants.ItemTypeCodes.ITEM_TYPE_PMT_TERMS_DISCOUNT_CODE};
961         if ((this.prorateBy != null)
962                 && (this.prorateBy.equals(OLEConstants.PRORATE_BY_QTY)
963                 || this.prorateBy.equals(OLEConstants.PRORATE_BY_DOLLAR) || this.prorateBy
964                 .equals(OLEConstants.MANUAL_PRORATE))) {
965             return this.getTotalPreTaxDollarAmountWithExclusions(discountCode, false);
966         } else {
967             return this.getTotalPreTaxDollarAmountWithExclusions(discountCode, true);
968         }
969     }
970 
971     @Override
972     public KualiDecimal getGrandTaxAmountExcludingDiscount() {
973         String[] discountCode = new String[]{PurapConstants.ItemTypeCodes.ITEM_TYPE_PMT_TERMS_DISCOUNT_CODE};
974         if ((this.prorateBy != null)
975                 && (this.prorateBy.equals(OLEConstants.PRORATE_BY_QTY)
976                 || this.prorateBy.equals(OLEConstants.PRORATE_BY_DOLLAR) || this.prorateBy
977                 .equals(OLEConstants.MANUAL_PRORATE))) {
978             return this.getTotalTaxAmountWithExclusions(discountCode, false);
979         } else {
980             return this.getTotalTaxAmountWithExclusions(discountCode, true);
981         }
982     }
983 
984 
985     @Override
986     public KualiDecimal getTotalPreTaxDollarAmountAboveLineItems() {
987         if ((this.prorateBy != null) && (this.prorateBy.equals(OLEConstants.PRORATE_BY_QTY) || this.prorateBy.equals(OLEConstants.PRORATE_BY_DOLLAR) || this.prorateBy.equals(OLEConstants.MANUAL_PRORATE))) {
988             KualiDecimal addChargeItem = KualiDecimal.ZERO;
989             KualiDecimal lineItemPreTaxTotal = KualiDecimal.ZERO;
990             KualiDecimal prorateSurcharge = KualiDecimal.ZERO;
991             List<OlePaymentRequestItem> item = this.getItems();
992             for (OlePaymentRequestItem items : item) {
993                 if (items.getItemType().isQuantityBasedGeneralLedgerIndicator() && items.getExtendedPrice() != null && items.getExtendedPrice().compareTo(KualiDecimal.ZERO) != 0) {
994                     if (items.getItemSurcharge() != null) {
995                         prorateSurcharge = new KualiDecimal(items.getItemSurcharge());
996                     }
997                     addChargeItem = addChargeItem.add(items.getExtendedPrice().subtract(prorateSurcharge.multiply(items.getItemQuantity())));
998                 }
999             }
1000             lineItemPreTaxTotal = addChargeItem;
1001             return lineItemPreTaxTotal;
1002         } else {
1003             return super.getTotalPreTaxDollarAmountAboveLineItems();
1004         }
1005     }
1006 
1007     /**
1008      * This method is used to check the status of the document for displaying view and edit buttons in line item
1009      *
1010      * @return boolean
1011      */
1012     public boolean getIsSaved() {
1013         if (this.getDocumentHeader().getWorkflowDocument().isSaved()
1014                 || this.getDocumentHeader().getWorkflowDocument().isInitiated()) {
1015             return true;
1016         }
1017         return false;
1018     }
1019 
1020     private void setItemDescription(OlePaymentRequestItem singleItem) throws Exception {
1021         if (singleItem.getOleOrderRecord() != null) {
1022             Map<String, ?> bibAssociatedFieldValuesMap = singleItem.getOleOrderRecord().getOleBibRecord().getBibAssociatedFieldsValueMap();
1023             List titleList = (List) bibAssociatedFieldValuesMap.get("Title_search");
1024             String title = titleList != null && !titleList.isEmpty() ? (String) (titleList).get(0) : null;
1025             List authorList = (List) bibAssociatedFieldValuesMap.get("Author_search");
1026             String author = authorList != null && !authorList.isEmpty() ? (String) (authorList).get(0) : null;
1027             List publisherList = (List) bibAssociatedFieldValuesMap.get("Publisher_search");
1028             String publisher = publisherList != null && !publisherList.isEmpty() ? (String) (publisherList).get(0) : null;
1029             List isbnList = (List) bibAssociatedFieldValuesMap.get("020a");
1030             String isbn = isbnList != null && !isbnList.isEmpty() ? (String) (isbnList).get(0) : null;
1031 
1032             singleItem.setBibUUID(singleItem.getOleOrderRecord().getOleBibRecord().getBibUUID());
1033             singleItem.setItemDescription(title + "," + author + "," + publisher + "," + isbn);
1034         }
1035     }
1036 
1037     public String getProrateBy() {
1038         return prorateBy;
1039     }
1040 
1041     public void setProrateBy(String prorateBy) {
1042         this.prorateBy = prorateBy;
1043     }
1044 
1045     /**
1046      * This method returns the boolean if the proforma indicator is selected
1047      *
1048      * @return proformaIndicator
1049      */
1050     public boolean isProformaIndicator() {
1051         return proformaIndicator;
1052     }
1053 
1054     /**
1055      * This method sets the proforma Indicator
1056      *
1057      * @param proformaIndicator
1058      */
1059 
1060     public void setProformaIndicator(boolean proformaIndicator) {
1061         this.proformaIndicator = proformaIndicator;
1062     }
1063 
1064     /**
1065      * Payment Request needs to wait for receiving if the receiving requirements have NOT been met.
1066      *
1067      * @return
1068      */
1069     @Override
1070     protected boolean shouldWaitForReceiving() {
1071         // only require if PO was marked to require receiving
1072         if (isReceivingDocumentRequiredIndicator() && !this.proformaIndicator) {
1073             return !isReceivingRequirementMet();
1074         }
1075 
1076         //receiving is not required or has already been fulfilled, no need to stop for routing
1077         return false;
1078     }
1079 
1080     /**
1081      * Provides answers to the following splits: PurchaseWasReceived VendorIsEmployeeOrNonResidentAlien
1082      *
1083      * @see org.kuali.ole.sys.document.FinancialSystemTransactionalDocumentBase#answerSplitNodeQuestion(java.lang.String)
1084      */
1085     @Override
1086     public boolean answerSplitNodeQuestion(String nodeName) throws UnsupportedOperationException {
1087         if (nodeName.equals(OLEConstants.HAS_VENDOR_DEPOSIT_ACCOUNT)) {
1088             return hasVendorDepositAccount();
1089         }
1090         if (nodeName.equals(OLEConstants.OlePaymentRequest.HAS_INVOICE_TYPE)) {
1091             return hasInvoiceType();
1092         }
1093         if (nodeName.equals(OLEConstants.OlePaymentRequest.HAS_PREPAID_INVOICE_TYPE)) {
1094             return hasPrepaidInvoiceType();
1095         }
1096         if (nodeName.equals(OLEConstants.OlePaymentRequest.HAS_PAYMENT_METHOD)) {
1097             return hasPaymentMethod();
1098         }
1099         if (nodeName.equals(PurapWorkflowConstants.BUDGET_REVIEW_REQUIRED)) {
1100             return isBudgetReviewRequired();
1101         }
1102         if (nodeName.equals(PurapWorkflowConstants.REQUIRES_IMAGE_ATTACHMENT)) {
1103             return requiresAccountsPayableReviewRouting();
1104         }
1105         if (nodeName.equals(PurapWorkflowConstants.PURCHASE_WAS_RECEIVED)) {
1106             return shouldWaitForReceiving();
1107         }
1108         if (nodeName.equals(PurapWorkflowConstants.VENDOR_IS_EMPLOYEE_OR_NON_RESIDENT_ALIEN)) {
1109             return isVendorEmployeeOrNonResidentAlien();
1110         }
1111         if (nodeName.equals(OLEConstants.REQUIRES_SEPARATION_OF_DUTIES)) {
1112             return isSeparationOfDutiesReviewRequired();
1113         }
1114 
1115         if (nodeName.equals(PurapWorkflowConstants.NOTIFY_BUDGET_REVIEW)) {
1116             return isNotificationRequired();
1117         }
1118         throw new UnsupportedOperationException("Cannot answer split question for this node you call \"" + nodeName + "\"");
1119     }
1120 
1121     private boolean hasInvoiceType() {
1122         if (this.getInvoiceTypeId() != null) {
1123             return true;
1124         }
1125         return false;
1126     }
1127 
1128     private boolean hasVendorDepositAccount() {
1129         List<PaymentRequestAccount> sourceAccounts = this.getSourceAccountingLines();
1130         for (PaymentRequestAccount sourceAccount : sourceAccounts) {
1131             if (sourceAccount.getAccount().getSubFundGroupCode().equalsIgnoreCase(OLEConstants.CLEARING_ACCOUNT_CODE)) {
1132                 return true;
1133             }
1134         }
1135         return false;
1136     }
1137 
1138     private boolean hasPrepaidInvoiceType() {
1139         if (this.getInvoiceTypeId() != null) {
1140             Map<String, String> invoiceMap = new HashMap<String, String>();
1141             invoiceMap.put("invoiceTypeId", this.getInvoiceTypeId().toString());
1142             OleInvoiceType invoiceType = this.getBusinessObjectService().findByPrimaryKey(OleInvoiceType.class,
1143                     invoiceMap);
1144             if (invoiceType != null &&
1145                     invoiceType.getInvoiceType().equals("Prepay") ||
1146                     invoiceType.getInvoiceType().equals("Deposit")) {
1147                 return true;
1148             }
1149         }
1150         return false;
1151     }
1152 
1153     private boolean hasPaymentMethod() {
1154         if (this.getPaymentMethodId() != null) {
1155             return true;
1156         }
1157         return false;
1158     }
1159 
1160     public Set<Person> getAllPriorApprovers() throws WorkflowException {
1161         PersonService personService = KimApiServiceLocator.getPersonService();
1162         List<ActionTaken> actionsTaken = getDocumentHeader().getWorkflowDocument().getActionsTaken();
1163         Set<String> principalIds = new HashSet<String>();
1164         Set<Person> persons = new HashSet<Person>();
1165 
1166         for (ActionTaken actionTaken : actionsTaken) {
1167             if (KewApiConstants.ACTION_TAKEN_APPROVED_CD.equals(actionTaken.getActionTaken())) {
1168                 String principalId = actionTaken.getPrincipalId();
1169                 if (!principalIds.contains(principalId)) {
1170                     principalIds.add(principalId);
1171                     persons.add(personService.getPerson(principalId));
1172                 }
1173             }
1174         }
1175         return persons;
1176     }
1177 
1178     protected boolean isSeparationOfDutiesReviewRequired() {
1179         try {
1180             Set<Person> priorApprovers = getAllPriorApprovers();
1181 
1182             // The initiator cannot be the approver
1183             String initiatorPrincipalId = getDocumentHeader().getWorkflowDocument().getInitiatorPrincipalId();
1184             Person initiator = SpringContext.getBean(PersonService.class).getPerson(initiatorPrincipalId);
1185             // If there is only one approver, and that approver is also the initiator, then Separation of Duties is required.
1186             boolean priorApproverIsInitiator = priorApprovers.contains(initiator);
1187             boolean onlyOneApprover = (priorApprovers.size() == 1);
1188             if (priorApproverIsInitiator && onlyOneApprover) {
1189                 return true;
1190             }
1191 
1192             // if there are more than 0 prior approvers which means there had been at least another approver than the current approver
1193             // then no need for separation of duties
1194             if (priorApprovers.size() > 0) {
1195                 return false;
1196             }
1197         } catch (WorkflowException we) {
1198             LOG.error("Exception while attempting to retrieve all prior approvers from workflow: " + we);
1199         }
1200         return false;
1201     }
1202 
1203     public boolean isBudgetReviewRequired() {
1204 
1205         OlePaymentRequestFundCheckServiceImpl olePaymentRequestFundCheckServiceImpl = new OlePaymentRequestFundCheckServiceImpl();
1206         boolean required = false;
1207         if((SpringContext.getBean(OlePaymentRequestService.class).getPaymentMethod(this.getPaymentMethodId())).equals(OLEConstants.DEPOSIT)) {
1208             return false;
1209         }
1210         // if document's fiscal year is less than or equal to the current fiscal year
1211         if (SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear().compareTo(getPostingYear()) >= 0) {
1212             List<SourceAccountingLine> sourceAccountingLineList = this.getSourceAccountingLines();
1213             for (SourceAccountingLine accLine : sourceAccountingLineList) {
1214                 String chart = accLine.getAccount().getChartOfAccountsCode();
1215                 String account = accLine.getAccount().getAccountNumber();
1216                 String sfCode = accLine.getAccount().getAccountSufficientFundsCode();
1217                 Map<String, Object> key = new HashMap<String, Object>();
1218                 key.put(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, chart);
1219                 key.put(OLEPropertyConstants.ACCOUNT_NUMBER, account);
1220                 OleSufficientFundCheck oleSufficientFundCheck = businessObjectService.findByPrimaryKey(
1221                         OleSufficientFundCheck.class, key);
1222                 if (oleSufficientFundCheck != null) {
1223                     String option = oleSufficientFundCheck.getNotificationOption() != null ? oleSufficientFundCheck
1224                             .getNotificationOption() : "";
1225                     if (option.equals(OLEPropertyConstants.BUD_REVIEW)) {
1226                         required = olePaymentRequestFundCheckServiceImpl.hasSufficientFundCheckRequired(accLine);
1227                         return required;
1228                     }
1229                 }
1230             }
1231         }
1232         return required;
1233         // get list of sufficientfundItems
1234 
1235         // delete and recreate the GL entries for this document so they do not get included in the SF check
1236         // This is *NOT* ideal. The SF service needs to be updated to allow it to provide the current
1237         // document number so that it can be exlcuded from pending entry checks.
1238         // List<GeneralLedgerPendingEntry> pendingEntries = getPendingLedgerEntriesForSufficientFundsChecking();
1239         // dumb loop to just force OJB to load the objects. Otherwise, the proxy object above
1240         // only gets resolved *after* the delete below and no SF check happens.
1241         // for (GeneralLedgerPendingEntry glpe : pendingEntries) {
1242         // glpe.getChartOfAccountsCode();
1243         // }
1244         // SpringContext.getBean(GeneralLedgerPendingEntryService.class).delete(getDocumentNumber());
1245         // List<SufficientFundsItem> fundsItems = SpringContext.getBean(SufficientFundsService.class)
1246         // .checkSufficientFundsForPREQ(pendingEntries);
1247         // SpringContext.getBean(GeneralLedgerPendingEntryService.class).generateGeneralLedgerPendingEntries(this);
1248         // SpringContext.getBean(BusinessObjectService.class).save(getGeneralLedgerPendingEntries());
1249         // if (fundsItems.size() > 0) {
1250         // return true;
1251         // }
1252         // }
1253         //
1254         // return false;
1255     }
1256 
1257     private boolean isNotificationRequired() {
1258         OleRequisitionDocumentService oleRequisitionDocumentService = (OleRequisitionDocumentService) SpringContext
1259                 .getBean("oleRequisitionDocumentService");
1260         List<SourceAccountingLine> sourceAccountingLineList = this.getSourceAccountingLines();
1261         boolean sufficientFundCheck = false;
1262         for (SourceAccountingLine accLine : sourceAccountingLineList) {
1263             Map searchMap = new HashMap();
1264             String notificationOption = null;
1265             Map<String, Object> key = new HashMap<String, Object>();
1266             String chartCode = accLine.getChartOfAccountsCode();
1267             String accNo = accLine.getAccountNumber();
1268             String objectCd = accLine.getFinancialObjectCode();
1269             key.put(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, chartCode);
1270             key.put(OLEPropertyConstants.ACCOUNT_NUMBER, accNo);
1271             OleSufficientFundCheck account = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(
1272                     OleSufficientFundCheck.class, key);
1273             if (account != null) {
1274                 notificationOption = account.getNotificationOption();
1275             }
1276             if (notificationOption != null && notificationOption.equals(OLEPropertyConstants.NOTIFICATION)) {
1277                 sufficientFundCheck = true;
1278             }
1279         }
1280         return sufficientFundCheck;
1281     }
1282 
1283     @Override
1284     protected void populateAccountsForRouting() {
1285 
1286         // if(this.getDocumentHeader().ge)
1287         List<SufficientFundsItem> fundsItems = new ArrayList<SufficientFundsItem>();
1288         try {
1289             // String nodeName =
1290             // SpringContext.getBean(WorkflowDocumentService.class).getCurrentRouteLevelName(getFinancialSystemDocumentHeader().getWorkflowDocument());
1291             if(getFinancialSystemDocumentHeader() != null){
1292                 String documentNumber = this.getDocumentNumber();
1293                 if(documentNumber != null){
1294                 WorkflowDocument workflowDocument = null;
1295                 workflowDocument = KRADServiceLocatorWeb.getWorkflowDocumentService().loadWorkflowDocument(this.getDocumentNumber(), SpringContext.getBean(PersonService.class).getPerson(GlobalVariables.getUserSession().getPerson().getPrincipalId()));
1296                 getFinancialSystemDocumentHeader().setWorkflowDocument(workflowDocument);
1297                 }
1298             }
1299             String nodeName = getFinancialSystemDocumentHeader().getWorkflowDocument().getCurrentNodeNames().iterator()
1300                     .next();
1301             if (nodeName != null
1302                     && (nodeName.equalsIgnoreCase(PurapWorkflowConstants.BUDGET_NODE) || nodeName
1303                     .equalsIgnoreCase(PurapWorkflowConstants.BUDGET_REVIEW_REQUIRED))) {
1304                 if (SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear()
1305                         .compareTo(getPostingYear()) >= 0) {
1306                     List<GeneralLedgerPendingEntry> pendingEntries = getPendingLedgerEntriesForSufficientFundsChecking();
1307                     for (GeneralLedgerPendingEntry glpe : pendingEntries) {
1308                         glpe.getChartOfAccountsCode();
1309                     }
1310                     // SpringContext.getBean(GeneralLedgerPendingEntryService.class).delete(getDocumentNumber());
1311                     fundsItems = SpringContext.getBean(SufficientFundsService.class).checkSufficientFundsForPREQ(
1312                             pendingEntries);
1313                     // SpringContext.getBean(GeneralLedgerPendingEntryService.class).generateGeneralLedgerPendingEntries(
1314                     // this);
1315                     // SpringContext.getBean(BusinessObjectService.class).save(getGeneralLedgerPendingEntries());
1316                 }
1317                 SpringContext.getBean(PurapAccountingService.class).updateAccountAmounts(this);
1318                 accountsForRouting = (SpringContext.getBean(PurapAccountingService.class).generateSummary(getItems()));
1319                 String documentFiscalYearString = this.getPostingYear().toString();
1320                 List<String> fundsItemList = new ArrayList<String>();
1321                 List<String> accountsList = new ArrayList<String>();
1322                 for (SufficientFundsItem fundsItem : fundsItems) {
1323                     fundsItemList.add(fundsItem.getAccount().getChartOfAccountsCode());
1324                 }
1325                 for (Iterator accountsForRoutingIter = accountsForRouting.iterator(); accountsForRoutingIter.hasNext(); ) {
1326                     if (!(fundsItemList.contains(((SourceAccountingLine) accountsForRoutingIter.next())
1327                             .getChartOfAccountsCode()))) {
1328                         accountsForRoutingIter.remove();
1329                     }
1330                 }
1331                 setAccountsForRouting(accountsForRouting);
1332                 // need to refresh to get the references for the searchable attributes (ie status) and for invoking route levels (ie
1333                 // account
1334                 // objects) -hjs
1335                 refreshNonUpdateableReferences();
1336                 for (SourceAccountingLine sourceLine : getAccountsForRouting()) {
1337                     sourceLine.refreshNonUpdateableReferences();
1338                 }
1339             } else {
1340                 super.populateAccountsForRouting();
1341             }
1342         } catch (Exception e) {
1343             logAndThrowRuntimeException("Error in populateAccountsForRouting while submitting document with id "
1344                     + getDocumentNumber(), e);
1345         }
1346 
1347     }
1348 
1349     /**
1350      * @see org.kuali.rice.krad.document.DocumentBase#doRouteLevelChange(org.kuali.rice.kew.framework.postprocessor.DocumentRouteLevelChange)
1351      */
1352     @Override
1353     public void doRouteLevelChange(DocumentRouteLevelChange levelChangeEvent) {
1354 
1355         super.doRouteLevelChange(levelChangeEvent);
1356         try {
1357             String newNodeName = levelChangeEvent.getNewNodeName();
1358             List<String> desiredActions = new ArrayList<String>(2);
1359             RoutingReportCriteria.Builder reportCriteria = RoutingReportCriteria.Builder
1360                     .createByDocumentIdAndTargetNodeName(getDocumentNumber(), newNodeName);
1361             desiredActions.add(ActionRequestType.APPROVE.getCode());
1362             desiredActions.add(ActionRequestType.COMPLETE.getCode());
1363             if (KewApiServiceLocator.getWorkflowDocumentActionsService().documentWillHaveAtLeastOneActionRequest(
1364                     reportCriteria.build(), desiredActions, false)) {
1365                 if (StringUtils.isNotBlank(newNodeName)) {
1366                     if (StringUtils.isNotBlank(newNodeName)) {
1367                         if (newNodeName.equalsIgnoreCase(PurapWorkflowConstants.BUDGET_NODE)
1368                                 || newNodeName.equalsIgnoreCase(PurapWorkflowConstants.FYI_BUDGET)) {
1369                             String note = OLEConstants.SufficientFundCheck.PREQ_NOTE;
1370                             DocumentService documentService = SpringContext.getBean(DocumentService.class);
1371                             Note apoNote = documentService.createNoteFromDocument(this, note);
1372                             this.addNote(apoNote);
1373                             documentService.saveDocumentNotes(this);
1374                         }
1375                     }
1376                 }
1377             }
1378         } catch (Exception e) {
1379             String errorMsg = "Workflow Error found checking actions requests on document with id "
1380                     + getDocumentNumber() + ". *** WILL NOT UPDATE PURAP STATUS ***";
1381             LOG.error(errorMsg, e);
1382         }
1383     }
1384 
1385     private void populateVendorAliasName() {
1386         Map vendorDetailMap = new HashMap();
1387         vendorDetailMap.put(OLEConstants.VENDOR_HEADER_IDENTIFIER, this.getVendorHeaderGeneratedIdentifier());
1388         vendorDetailMap.put(OLEConstants.VENDOR_DETAIL_IDENTIFIER, this.getVendorDetailAssignedIdentifier());
1389         List<VendorAlias> vendorDetailList = (List) getBusinessObjectService().findMatching(VendorAlias.class, vendorDetailMap);
1390         if (vendorDetailList != null && vendorDetailList.size() > 0) {
1391             this.setVendorAliasName(vendorDetailList.get(0).getVendorAliasName());
1392         }
1393     }
1394     
1395     @Override
1396     public boolean generateGeneralLedgerPendingEntries(GeneralLedgerPendingEntrySourceDetail glpeSourceDetail, GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
1397         LOG.debug("processGenerateGeneralLedgerPendingEntries(AccountingDocument, AccountingLine, GeneralLedgerPendingEntrySequenceHelper) - start");
1398 
1399         // handle the explicit entry
1400         // create a reference to the explicitEntry to be populated, so we can pass to the offset method later
1401         GeneralLedgerPendingEntry explicitEntry = new GeneralLedgerPendingEntry();
1402         processExplicitGeneralLedgerPendingEntry(sequenceHelper, glpeSourceDetail, explicitEntry);
1403         // increment the sequence counter
1404         sequenceHelper.increment();
1405 
1406         // handle the offset entry
1407 
1408         GeneralLedgerPendingEntry offsetEntry = new GeneralLedgerPendingEntry(explicitEntry);
1409         boolean success = processOffsetGeneralLedgerPendingEntry(sequenceHelper, glpeSourceDetail, explicitEntry, offsetEntry);
1410 
1411         LOG.debug("processGenerateGeneralLedgerPendingEntries(AccountingDocument, AccountingLine, GeneralLedgerPendingEntrySequenceHelper) - end");
1412         return success;
1413     }
1414 
1415     /**
1416      * This method processes an accounting line's information to build an offset entry, and then adds that to the document.
1417      *
1418      * @param sequenceHelper
1419      * @param explicitEntry
1420      * @param offsetEntry
1421      * @return boolean True if the offset generation is successful.
1422      */
1423     protected boolean processOffsetGeneralLedgerPendingEntry(GeneralLedgerPendingEntrySequenceHelper sequenceHelper, GeneralLedgerPendingEntrySourceDetail postable, GeneralLedgerPendingEntry explicitEntry, GeneralLedgerPendingEntry offsetEntry) {
1424         LOG.debug("processOffsetGeneralLedgerPendingEntry(AccountingDocument, GeneralLedgerPendingEntrySequenceHelper, AccountingLine, GeneralLedgerPendingEntry, GeneralLedgerPendingEntry) - start");
1425 
1426         // populate the offset entry
1427         boolean success = SpringContext.getBean(GeneralLedgerPendingEntryService.class).populateOffsetGeneralLedgerPendingEntry(getPostingYear(), explicitEntry, sequenceHelper, offsetEntry);
1428 
1429         // hook for children documents to implement document specific field mappings for the GLPE
1430         success &= customizeOffsetGeneralLedgerPendingEntry(postable, explicitEntry, offsetEntry);
1431 
1432         if (SpringContext.getBean(OlePaymentRequestService.class).getPaymentMethod(this.getPaymentMethodId()).equals(OLEConstants.DEPOSIT)) {
1433             if (offsetEntry.getFinancialBalanceTypeCode().equals(OLEConstants.BALANCE_TYPE_ACTUAL) && offsetEntry.isTransactionEntryOffsetIndicator()) {
1434                 Integer purapDocumentIdentifier = this.getPurapDocumentIdentifier();
1435                 Map itemMap = new HashMap();
1436                 itemMap.put("purapDocumentIdentifier", purapDocumentIdentifier);
1437                 List<OlePaymentRequestItem> paymentRequestItems = (List<OlePaymentRequestItem>) getBusinessObjectService().findMatching(OlePaymentRequestItem.class, itemMap);
1438                 if (paymentRequestItems.size() > 0) {
1439                     for (OlePaymentRequestItem item : paymentRequestItems) {
1440                         for (int i = 0; i < item.getSourceAccountingLines().size(); i++) {
1441                             if (item.getSourceAccountingLine(i).getAccountNumber().equals(explicitEntry.getAccountNumber())) {
1442                                 Integer poItemIdentifier = item.getPoItemIdentifier();
1443                                 Map offMap = new HashMap();
1444                                 offMap.put("itemIdentifier", poItemIdentifier);
1445                                 List<OLEInvoiceOffsetAccountingLine> offsetAccountingLines = (List<OLEInvoiceOffsetAccountingLine>) getBusinessObjectService().findMatching(OLEInvoiceOffsetAccountingLine.class, offMap);
1446                                 if (offsetAccountingLines.size() > 0) {
1447                                     int size = offsetAccountingLines.size();
1448                                     for (OLEInvoiceOffsetAccountingLine accLine : offsetAccountingLines) {
1449                                         offsetEntry.setChartOfAccountsCode(accLine.getChartOfAccountsCode());
1450                                         offsetEntry.setAccountNumber(accLine.getAccountNumber());
1451                                         offsetEntry.setFinancialObjectCode(accLine.getFinancialObjectCode());
1452                                         offsetEntry.setFinancialBalanceTypeCode("AC");
1453                                         offsetEntry.setFinancialObjectTypeCode("AS");
1454                                         offsetEntry.setTransactionDebitCreditCode(OLEConstants.GL_CREDIT_CODE);
1455                                         offsetEntry.setTransactionLedgerEntryAmount(accLine.getAmount());
1456                                         offsetEntry.setAcctSufficientFundsFinObjCd(accLine.getFinancialObjectCode());
1457                                         addPendingEntry(offsetEntry);
1458                                     }
1459                                 }
1460                             }
1461                         }
1462                     }
1463                 }
1464 
1465             } else {
1466                 addPendingEntry(offsetEntry);
1467             }
1468         } else {
1469             addPendingEntry(offsetEntry);
1470         }
1471 
1472         LOG.debug("processOffsetGeneralLedgerPendingEntry(AccountingDocument, GeneralLedgerPendingEntrySequenceHelper, AccountingLine, GeneralLedgerPendingEntry, GeneralLedgerPendingEntry) - end");
1473         return success;
1474     }
1475 
1476 
1477     /**
1478      * This method processes all necessary information to build an explicit general ledger entry, and then adds that to the
1479      * document.
1480      *
1481      * @param sequenceHelper
1482      * @param explicitEntry
1483      * @return boolean True if the explicit entry generation was successful, false otherwise.
1484      */
1485     protected void processExplicitGeneralLedgerPendingEntry(GeneralLedgerPendingEntrySequenceHelper sequenceHelper, GeneralLedgerPendingEntrySourceDetail glpeSourceDetail, GeneralLedgerPendingEntry explicitEntry) {
1486         LOG.debug("processExplicitGeneralLedgerPendingEntry(AccountingDocument, GeneralLedgerPendingEntrySequenceHelper, AccountingLine, GeneralLedgerPendingEntry) - start");
1487 
1488         // populate the explicit entry
1489         SpringContext.getBean(GeneralLedgerPendingEntryService.class).populateExplicitGeneralLedgerPendingEntry(this, glpeSourceDetail, sequenceHelper, explicitEntry);
1490 
1491         // hook for children documents to implement document specific GLPE field mappings
1492         customizeExplicitGeneralLedgerPendingEntry(glpeSourceDetail, explicitEntry);
1493 
1494         if ((SpringContext.getBean(OlePaymentRequestService.class).getPaymentMethod(this.getPaymentMethodId()).equals(OLEConstants.DEPOSIT)) && explicitEntry.getFinancialBalanceTypeCode().equals(OLEConstants.BALANCE_TYPE_ACTUAL)) {
1495             explicitEntry.setTransactionDebitCreditCode(OLEConstants.GL_DEBIT_CODE);
1496             addPendingEntry(explicitEntry);
1497         } else {
1498             addPendingEntry(explicitEntry);
1499         }
1500 
1501         LOG.debug("processExplicitGeneralLedgerPendingEntry(AccountingDocument, GeneralLedgerPendingEntrySequenceHelper, AccountingLine, GeneralLedgerPendingEntry) - end");
1502     }
1503 
1504 }
1505