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.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