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