001/*
002 * Copyright 2011 The Kuali Foundation.
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.ole.select.document;
017
018import org.apache.commons.lang.StringEscapeUtils;
019import org.apache.commons.lang.StringUtils;
020import org.kuali.ole.docstore.common.client.*;
021import org.kuali.ole.docstore.common.client.impl.DocstoreClientLocatorServiceImpl;
022import org.kuali.ole.docstore.common.document.Bib;
023import org.kuali.ole.docstore.common.document.BibMarc;
024import org.kuali.ole.DocumentUniqueIDPrefix;
025import org.kuali.ole.docstore.model.bo.WorkBibDocument;
026import org.kuali.ole.docstore.model.bo.WorkInstanceDocument;
027import org.kuali.ole.docstore.model.bo.WorkItemDocument;
028import org.kuali.ole.docstore.model.enums.DocType;
029import org.kuali.ole.gl.service.SufficientFundsService;
030import org.kuali.ole.module.purap.PurapWorkflowConstants;
031import org.kuali.ole.module.purap.businessobject.PurchaseOrderType;
032import org.kuali.ole.module.purap.document.PurchaseOrderAmendmentDocument;
033import org.kuali.ole.module.purap.document.RequisitionDocument;
034import org.kuali.ole.module.purap.document.service.OlePurapService;
035import org.kuali.ole.module.purap.service.PurapAccountingService;
036import org.kuali.ole.select.OleSelectConstant;
037import org.kuali.ole.select.businessobject.*;
038import org.kuali.ole.select.document.service.*;
039import org.kuali.ole.sys.OLEConstants;
040import org.kuali.ole.sys.OLEPropertyConstants;
041import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntry;
042import org.kuali.ole.sys.businessobject.SourceAccountingLine;
043import org.kuali.ole.sys.businessobject.SufficientFundsItem;
044import org.kuali.ole.sys.context.SpringContext;
045import org.kuali.ole.sys.service.GeneralLedgerPendingEntryService;
046import org.kuali.ole.sys.service.UniversityDateService;
047import org.kuali.ole.vnd.businessobject.VendorAlias;
048import org.kuali.rice.core.api.util.type.KualiDecimal;
049import org.kuali.rice.core.api.util.type.KualiInteger;
050import org.kuali.rice.kew.api.action.RoutingReportCriteria;
051import org.kuali.rice.kew.framework.postprocessor.DocumentRouteLevelChange;
052import org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange;
053import org.kuali.rice.krad.bo.Note;
054import org.kuali.rice.krad.rules.rule.event.KualiDocumentEvent;
055import org.kuali.rice.krad.service.BusinessObjectService;
056import org.kuali.rice.krad.service.DocumentService;
057
058import java.math.BigDecimal;
059import java.util.*;
060
061public class OlePurchaseOrderAmendmentDocument extends PurchaseOrderAmendmentDocument {
062    private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(OlePurchaseOrderAmendmentDocument.class);
063
064    private String vendorPoNumber;
065    private static transient OlePatronRecordHandler olePatronRecordHandler;
066    private static transient OlePatronDocumentList olePatronDocumentList;
067    private static transient OleSelectDocumentService oleSelectDocumentService;
068    private static transient OlePurapService olePurapService;
069    private static transient OleCopyHelperService oleCopyHelperService;
070    private String vendorAliasName;
071    private DocstoreClientLocator docstoreClientLocator;
072
073    public DocstoreClientLocator getDocstoreClientLocator() {
074        if (docstoreClientLocator == null) {
075            docstoreClientLocator = SpringContext.getBean(DocstoreClientLocator.class);
076        }
077        return docstoreClientLocator;
078    }
079
080    public static OleSelectDocumentService getOleSelectDocumentService() {
081        if (oleSelectDocumentService == null) {
082            oleSelectDocumentService = SpringContext.getBean(OleSelectDocumentService.class);
083        }
084        return oleSelectDocumentService;
085    }
086
087    public static void setOleSelectDocumentService(OleSelectDocumentService oleSelectDocumentService) {
088        OlePurchaseOrderAmendmentDocument.oleSelectDocumentService = oleSelectDocumentService;
089    }
090
091    public static OlePatronDocumentList getOlePatronDocumentList() {
092        if (olePatronDocumentList == null) {
093            olePatronDocumentList = SpringContext.getBean(OlePatronDocumentList.class);
094        }
095        return olePatronDocumentList;
096    }
097
098    public static void setOlePatronDocumentList(OlePatronDocumentList olePatronDocumentList) {
099        OlePurchaseOrderAmendmentDocument.olePatronDocumentList = olePatronDocumentList;
100    }
101
102
103    public OlePatronRecordHandler getOlePatronRecordHandler() {
104        if (null == olePatronRecordHandler) {
105            olePatronRecordHandler = new OlePatronRecordHandler();
106        }
107        return olePatronRecordHandler;
108    }
109
110    public void setOlePatronRecordHandler(OlePatronRecordHandler olePatronRecordHandler) {
111        this.olePatronRecordHandler = olePatronRecordHandler;
112    }
113
114    public String getVendorAliasName() {
115        return vendorAliasName;
116    }
117
118    public void setVendorAliasName(String vendorAliasName) {
119        this.vendorAliasName = vendorAliasName;
120    }
121
122    public static OlePurapService getOlePurapService() {
123        if (olePurapService == null) {
124            olePurapService = SpringContext.getBean(OlePurapService.class);
125        }
126        return olePurapService;
127    }
128
129    public static void setOlePurapService(OlePurapService olePurapService) {
130        OlePurchaseOrderAmendmentDocument.olePurapService = olePurapService;
131    }
132
133    public static OleCopyHelperService getOleCopyHelperService() {
134        if(oleCopyHelperService  == null){
135            oleCopyHelperService = SpringContext.getBean(OleCopyHelperService.class);
136        }
137        return oleCopyHelperService;
138    }
139
140    public static void setOleCopyHelperService(OleCopyHelperService oleCopyHelperService) {
141        OlePurchaseOrderAmendmentDocument.oleCopyHelperService = oleCopyHelperService;
142    }
143
144    @Override
145    public void doRouteStatusChange(DocumentRouteStatusChange statusChangeEvent) {
146        super.doRouteStatusChange(statusChangeEvent);
147        if (getDocumentHeader().getWorkflowDocument().isProcessed()) {
148            SpringContext.getBean(OlePurchaseOrderService.class).setStatusCompletePurchaseOrderAmendment(this);
149        }
150    }
151
152    /**
153     * This method is overridden to populate newly added ole fields from requisition into Ole Purchase Order Amendment Document.
154     *
155     * @see org.kuali.ole.module.purap.document.PurchaseOrderDocument#populatePurchaseOrderFromRequisition(org.kuali.ole.module.purap.document.RequisitionDocument)
156     */
157    @Override
158    public void populatePurchaseOrderFromRequisition(RequisitionDocument requisitionDocument) {
159
160        LOG.debug("Inside populatePurchaseOrderFromRequisition of OlePurchaseOrderAmendmentDocument");
161        SpringContext.getBean(OlePurchaseOrderDocumentHelperService.class).populatePurchaseOrderFromRequisition(this, requisitionDocument);
162
163
164    }
165
166    /**
167     * This method is overriden to populate bib info in Ole Purchase Order Amendment Document
168     *
169     * @see org.kuali.ole.module.purap.document.PurchaseOrderDocument#prepareForSave(org.kuali.rice.krad.rule.event.KualiDocumentEvent)
170     */
171    @Override
172    public void prepareForSave(KualiDocumentEvent event) {
173
174        LOG.debug("Inside prepareForSave of OlePurchaseOrderAmendmentDocument");
175        //For single copy, if the itemLocation is changed, based on the user input from Location Change prompt, the itemLocation is updated in docstore's item record.
176        OleDocstoreHelperService oleDocstoreHelperService = SpringContext
177                .getBean(OleDocstoreHelperService.class);
178        List<OlePurchaseOrderItem> purItem = this.getItems();
179        for (int i = 0; purItem.size() > i; i++) {
180            OlePurchaseOrderItem item = (OlePurchaseOrderItem) this.getItem(i);
181            if (item.isItemLocationChangeFlag()) {
182                oleDocstoreHelperService.updateItemLocation(this, item);
183            }
184        }
185        SpringContext.getBean(OlePurchaseOrderDocumentHelperService.class).prepareForSave(this, event);
186        super.prepareForSave(event);
187    }
188
189    /**
190     * This method is overriden to populate bib info in Ole Purchase Order Amendment Document
191     *
192     * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocumentBase#processAfterRetrieve()
193     */
194    @Override
195    public void processAfterRetrieve() {
196        LOG.debug("Inside processAfterRetrieve of OlePurchaseOrderAmendmentDocument");
197        if (this.getVendorAliasName() == null) {
198            populateVendorAliasName();
199        }
200        try {
201            PurchaseOrderType purchaseOrderTypeDoc = getOlePurapService().getPurchaseOrderType(this.getPurchaseOrderTypeId());
202            if(purchaseOrderTypeDoc != null){
203                this.setOrderType(purchaseOrderTypeDoc);
204            }
205        } catch (Exception e) {
206            LOG.error("Error in OlePurchaseOrderDocument:processAfterRetrieve for OleRequisitionItem " + e.getMessage());
207            throw new RuntimeException(e);
208        }
209        try {
210            List<OlePurchaseOrderItem> items = this.getItems();
211            Iterator iterator = items.iterator();
212            while (iterator.hasNext()) {
213                Object object = iterator.next();
214                if (object instanceof OlePurchaseOrderItem) {
215                    OlePurchaseOrderItem singleItem = (OlePurchaseOrderItem) object;
216                    setItemDetailWhileProcessAfterRetrive(singleItem);
217                }
218            }
219        } catch (Exception e) {
220            LOG.error("Exception in OlePurchaseOrderDocument:processAfterRetrieve for OlePurchaseOrderItem " + e.getMessage());
221            throw new RuntimeException(e);
222        }
223    }
224
225    /**
226     * This method is used to set the item detail while processafterretrive method is executed
227     * @param olePurchaseOrderItem
228     */
229    private void setItemDetailWhileProcessAfterRetrive(OlePurchaseOrderItem olePurchaseOrderItem)throws Exception{
230        if (olePurchaseOrderItem.getRequestorId() != null) {
231            olePurchaseOrderItem.setRequestorFirstName(getOlePurapService().getPatronName(olePurchaseOrderItem.getRequestorId()));
232        }
233        olePurchaseOrderItem.setPreviousItemQuantity(olePurchaseOrderItem.getItemQuantity());
234        olePurchaseOrderItem.setPreviousItemNoOfParts(olePurchaseOrderItem.getItemNoOfParts());
235        // Added for jira OLE-2811 ends
236        if (olePurchaseOrderItem.getBibInfoBean() == null) {
237            olePurchaseOrderItem.setBibInfoBean(new BibInfoBean());
238        }
239        if ((!StringUtils.isEmpty(olePurchaseOrderItem.getInternalRequestorId()) || !StringUtils.isEmpty(olePurchaseOrderItem
240                .getRequestorId())) && olePurchaseOrderItem.getBibInfoBean().getRequestorType() == null) {
241            String requestorType = OleSelectConstant.REQUESTOR_TYPE_STAFF;
242            Map<String, Object> criteria = new HashMap<String, Object>();
243            criteria.put(OleSelectConstant.REQUESTOR_TYPE, requestorType);
244            Collection<OleRequestorType> requestorTypeList = SpringContext.getBean(BusinessObjectService.class).findMatching(OleRequestorType.class, criteria);
245            LOG.debug("###########inside prepareForSave getting requestor type###########");
246            olePurchaseOrderItem.setRequestorTypeId(requestorTypeList.iterator().next().getRequestorTypeId());
247        }
248        if(olePurchaseOrderItem.getItemUnitPrice()!=null){
249            olePurchaseOrderItem.setItemUnitPrice(olePurchaseOrderItem.getItemUnitPrice().setScale(2, BigDecimal.ROUND_HALF_UP));
250        }
251        if (olePurchaseOrderItem.getItemTitleId() != null) {
252            LOG.debug("###########inside processAfterRetrieve OlePurchaseOrderAmendmentDocument ###########");
253            Bib bib = new BibMarc();
254            if (olePurchaseOrderItem.getItemTitleId() != null && olePurchaseOrderItem.getItemTitleId() != "") {
255                bib = getDocstoreClientLocator().getDocstoreClient().retrieveBib(olePurchaseOrderItem.getItemTitleId());
256                olePurchaseOrderItem.setBibUUID(bib.getId());
257            }
258            olePurchaseOrderItem.setDocFormat(DocumentUniqueIDPrefix.getBibFormatType(olePurchaseOrderItem.getItemTitleId()));
259            olePurchaseOrderItem.setBibInfoBean(new BibInfoBean());
260            olePurchaseOrderItem.setItemDescription(getOlePurapService().getItemDescription(bib));
261        }
262        if (olePurchaseOrderItem.getItemType() != null && olePurchaseOrderItem.getItemType().isQuantityBasedGeneralLedgerIndicator()) {
263            populateCopiesSection(olePurchaseOrderItem);
264        }
265        if(olePurchaseOrderItem.getCopyList().size() > 0) {
266            getOlePurapService().setInvoiceDocumentsForPO(olePurchaseOrderItem);
267        }
268    }
269
270    /**
271     * This method is used to populated the copies section details
272     * @param singleItem
273     */
274    private void populateCopiesSection(OlePurchaseOrderItem singleItem) {
275        if (singleItem.getCopies().size() > 0) {
276            List<OleCopy> copyList = getOleCopyHelperService().setCopyValuesForList(singleItem.getCopies(), singleItem.getItemTitleId(), null);
277            if (copyList.size() >= singleItem.getCopyList().size()) {
278                int copyCount = 0;
279                for (OleCopy oleCopy : singleItem.getCopyList()) {
280                    OleCopy copy = copyList.get(copyCount);
281                    oleCopy.setLocation(copy.getLocation());
282                    oleCopy.setEnumeration(copy.getEnumeration());
283                    oleCopy.setCopyNumber(copy.getCopyNumber());
284                    oleCopy.setPartNumber(copy.getPartNumber());
285                    copyCount++;
286                }
287                for(int i = copyCount ; i<copyList.size() ; i++){
288                    singleItem.getCopyList().add(copyList.get(copyCount));
289                    copyCount++;
290                }
291            }
292        }
293        else {
294            if (singleItem.getItemQuantity() != null && singleItem.getItemNoOfParts() != null && (singleItem.getItemQuantity().isGreaterThan(new KualiDecimal(1))
295                    || singleItem.getItemNoOfParts().isGreaterThan(new KualiInteger(1)))) {
296                singleItem.setCopies(getOleCopyHelperService().setCopiesToLineItem(singleItem.getCopyList(), singleItem.getItemNoOfParts(), singleItem.getItemTitleId()));
297            }
298        }
299        if (singleItem.getItemQuantity() != null && singleItem.getItemNoOfParts() != null && !singleItem.getItemQuantity().isGreaterThan(new KualiDecimal(1))
300                && !singleItem.getItemNoOfParts().isGreaterThan(new KualiInteger(1))&&singleItem.getCopyList().size()>0) {
301            singleItem.setSingleCopyNumber(singleItem.getCopyList().get(0).getCopyNumber());
302        }
303    }
304
305    // Added for Jira OLE-1900 Starts
306
307    /**
308     * This method will set copies into list of copies for LineItem.
309     *
310     * @param singleItem
311     * @param workBibDocument
312     * @return
313     */
314    public List<OleCopies> setCopiesToLineItem(OlePurchaseOrderItem singleItem, WorkBibDocument workBibDocument) {
315        List<WorkInstanceDocument> instanceDocuments = workBibDocument.getWorkInstanceDocumentList();
316        List<OleCopies> copies = new ArrayList<OleCopies>();
317        for (WorkInstanceDocument workInstanceDocument : instanceDocuments) {
318            List<WorkItemDocument> itemDocuments = workInstanceDocument.getItemDocumentList();
319            StringBuffer enumeration = new StringBuffer();
320            for (int itemDocs = 0; itemDocs < itemDocuments.size(); itemDocs++) {
321                if (itemDocs + 1 == itemDocuments.size()) {
322                    enumeration = enumeration.append(itemDocuments.get(itemDocs).getEnumeration());
323                } else {
324                    enumeration = enumeration.append(itemDocuments.get(itemDocs).getEnumeration() + ",");
325                }
326
327            }
328            int startingCopy = 0;
329            if (singleItem.getItemNoOfParts().intValue() != 0 && null != enumeration) {
330                String enumerationSplit = enumeration.substring(1, 2);
331                boolean isint = checkIsEnumerationSplitIsIntegerOrNot(enumerationSplit);
332                if (isint) {
333                    startingCopy = Integer.parseInt(enumerationSplit);
334                }
335            }
336            if (singleItem.getItemQuantity().isGreaterThan(new KualiDecimal(1))
337                    || singleItem.getItemNoOfParts().isGreaterThan(new KualiInteger(1))) {
338                boolean isValid = checkForEnumeration(enumeration);
339                if (isValid) {
340                    int noOfCopies = workInstanceDocument.getItemDocumentList().size()
341                            / singleItem.getItemNoOfParts().intValue();
342                    OleRequisitionCopies copy = new OleRequisitionCopies();
343                    copy.setParts(singleItem.getItemNoOfParts());
344                    copy.setLocationCopies(workInstanceDocument.getHoldingsDocument().getLocationName());
345                    copy.setItemCopies(new KualiDecimal(noOfCopies));
346                    copy.setPartEnumeration(enumeration.toString());
347                    copy.setStartingCopyNumber(new KualiInteger(startingCopy));
348                    copies.add(copy);
349                }
350            }
351        }
352        return copies;
353    }
354
355    public boolean checkForEnumeration(StringBuffer enumeration) {
356        if (null != enumeration && !(enumeration.equals("")) && !(enumeration.toString().equals("null"))) {
357            return true;
358        } else {
359            return false;
360        }
361    }
362
363    public boolean checkIsEnumerationSplitIsIntegerOrNot(String enumerationSplit) {
364        try {
365            int startingCopy = Integer.parseInt(enumerationSplit);
366        } catch (NumberFormatException e) {
367            return false;
368        }
369        return true;
370    }
371
372    /**
373     * This method takes List of UUids as parameter and creates a LinkedHashMap with instance as key and id as value. and calls
374     * Docstore's QueryServiceImpl class getWorkBibRecords method and return workBibDocument for passed instance Id.
375     *
376     * @param instanceIdsList
377     * @return List<WorkBibDocument>
378     */
379//    private List<WorkBibDocument> getWorkBibDocuments(List<String> instanceIdsList) {
380//        List<LinkedHashMap<String, String>> instanceIdMapList = new ArrayList<LinkedHashMap<String, String>>();
381//        for (String instanceId : instanceIdsList) {
382//            LinkedHashMap<String, String> instanceIdMap = new LinkedHashMap<String, String>();
383//            instanceIdMap.put(DocType.INSTANCE.getDescription(), instanceId);
384//            instanceIdMapList.add(instanceIdMap);
385//        }
386//
387//        QueryService queryService = QueryServiceImpl.getInstance();
388//        List<WorkBibDocument> workBibDocuments = new ArrayList<WorkBibDocument>();
389//        try {
390//            workBibDocuments = queryService.getWorkBibRecords(instanceIdMapList);
391//        } catch (Exception ex) {
392//            // TODO Auto-generated catch block
393//            ex.printStackTrace();
394//        }
395//        return workBibDocuments;
396//    }
397
398    // Added for Jira OLE-1900 Ends
399
400    @Override
401    public List getItemsActiveOnly() {
402        LOG.debug("Inside getItemsActiveOnly of OlePurchaseOrderReopenDocument");
403        return SpringContext.getBean(OlePurchaseOrderDocumentHelperService.class).getItemsActiveOnly(this);
404    }
405
406    /**
407     * Gets the active items in this Purchase Order, and sets up the alternate amount for GL entry creation.
408     *
409     * @return the list of all active items in this Purchase Order.
410     */
411    @Override
412    public List getItemsActiveOnlySetupAlternateAmount() {
413        LOG.debug("Inside getItemsActiveOnlySetupAlternateAmount of OlePurchaseOrderReopenDocument");
414        return SpringContext.getBean(OlePurchaseOrderDocumentHelperService.class).getItemsActiveOnlySetupAlternateAmount(this);
415    }
416
417    @Override
418    public boolean getAdditionalChargesExist() {
419        LOG.debug("Inside getAdditionalChargesExist of OlePurchaseOrderReopenDocument");
420        return SpringContext.getBean(OlePurchaseOrderDocumentHelperService.class).getAdditionalChargesExist(this);
421    }
422
423    /**
424     * This method returns if Purchase Order Document created is in Final Status
425     *
426     * @return
427     */
428    public boolean getIsFinalReqs() {
429        LOG.debug("Inside getIsFinalReqs of OlePurchaseOrderAmendmentDocument");
430
431        return SpringContext.getBean(OlePurchaseOrderDocumentHelperService.class).getIsFinalReqs(this);
432    }
433
434    public boolean getIsSplitPO() {
435        LOG.debug("Inside getIsSplitPO of OlePurchaseOrderAmendmentDocument");
436        return SpringContext.getBean(OlePurchaseOrderDocumentHelperService.class).getIsSplitPO(this);
437    }
438
439    public boolean getIsReOpenPO() {
440        LOG.debug("Inside getIsReOpenPO of OlePurchaseOrderAmendmentDocument");
441        return SpringContext.getBean(OlePurchaseOrderDocumentHelperService.class).getIsReOpenPO(this);
442    }
443
444    /**
445     * This method is used to get the bibedtior creat url from propertie file
446     *
447     * @return Bibeditor creat url string
448     */
449    public String getBibeditorCreateURL() {
450        LOG.debug("Inside getBibeditorCreateURL of OlePurchaseOrderAmendmentDocument");
451        return SpringContext.getBean(OlePurchaseOrderDocumentHelperService.class).getBibeditorCreateURL();
452    }
453
454    public String getBibSearchURL() {
455        LOG.debug("Inside getBibSearchURL of OlePurchaseOrderAmendmentDocument");
456        return SpringContext.getBean(OlePurchaseOrderDocumentHelperService.class).getBibSearchURL();
457    }
458
459    /**
460     * This method is used to get the bibedtior edit url from propertie file
461     *
462     * @return Bibeditor edit url string
463     */
464    public String getBibeditorEditURL() {
465        LOG.debug("Inside getBibeditorEditURL of OlePurchaseOrderAmendmentDocument");
466        return SpringContext.getBean(OlePurchaseOrderDocumentHelperService.class).getBibeditorEditURL();
467    }
468
469    /**
470     * This method is used to get the dublinedtior edit url from propertie file
471     *
472     * @return Dublineditor edit url string
473     */
474    public String getDublinEditorEditURL() {
475        return SpringContext.getBean(OlePurchaseOrderDocumentHelperService.class).getDublinEditorEditURL();
476    }
477    /**
478     * This method is used to get the Instanceeditor url from propertie file
479     *
480     * @return Instanceeditor url string
481     */
482    public String getInstanceEditorURL() {
483        return SpringContext.getBean(OlePurchaseOrderDocumentHelperService.class).getInstanceEditorURL();
484    }
485
486    /**
487     * This method is used to get the bibedtior view url from propertie file
488     *
489     * @return Bibeditor view url string
490     */
491    public String getBibeditorViewURL() {
492        return SpringContext.getBean(OlePurchaseOrderDocumentHelperService.class).getBibeditorViewURL();
493    }
494    /**
495     * This method is used to get the dublinedtior view url from propertie file
496     *
497     * @return dublineditor view url string
498     */
499    public String getDublinEditorViewURL() {
500        return SpringContext.getBean(OlePurchaseOrderDocumentHelperService.class).getDublinEditorViewURL();
501    }
502    /**
503     * This method is used to get the directory path where the marc xml files need to be created
504     *
505     * @return Directory path string
506     */
507    public String getMarcXMLFileDirLocation() throws Exception {
508        LOG.debug("Inside getMarcXMLFileDirLocation of OlePurchaseOrderAmendmentDocument");
509        return SpringContext.getBean(OlePurchaseOrderDocumentHelperService.class).getMarcXMLFileDirLocation();
510    }
511
512    @Override
513    public Class getItemClass() {
514        return OlePurchaseOrderItem.class;
515    }
516
517
518    @Override
519    public boolean answerSplitNodeQuestion(String nodeName) throws UnsupportedOperationException {
520        if (nodeName.equals(PurapWorkflowConstants.HAS_NEW_UNORDERED_ITEMS)) {
521            return isNewUnorderedItem();
522        }
523        if (nodeName.equals(PurapWorkflowConstants.CONTRACT_MANAGEMENT_REVIEW_REQUIRED)) {
524            return isContractManagementReviewRequired();
525        }
526        if (nodeName.equals(PurapWorkflowConstants.AWARD_REVIEW_REQUIRED)) {
527            return isAwardReviewRequired();
528        }
529        if (nodeName.equals(PurapWorkflowConstants.BUDGET_REVIEW_REQUIRED)) {
530            return isBudgetReviewRequired();
531        }
532        if (nodeName.equals(PurapWorkflowConstants.VENDOR_IS_EMPLOYEE_OR_NON_RESIDENT_ALIEN)) {
533            return isVendorEmployeeOrNonResidentAlien();
534        }
535
536        if (nodeName.equals(PurapWorkflowConstants.NOTIFY_BUDGET_REVIEW)) {
537            return isNotificationRequired();
538        }
539        throw new UnsupportedOperationException("Cannot answer split question for this node you call \"" + nodeName + "\"");
540    }
541
542    public String getVendorPoNumber() {
543        return vendorPoNumber;
544    }
545
546    public void setVendorPoNumber(String vendorPoNumber) {
547        this.vendorPoNumber = vendorPoNumber;
548    }
549
550    /**
551     * This method is used to check the status of the document for displaying view and edit buttons in line item
552     *
553     * @return boolean
554     */
555    public boolean getIsSaved() {
556        if (this.getDocumentHeader().getWorkflowDocument().isSaved() || this.getDocumentHeader().getWorkflowDocument().isInitiated()) {
557            return true;
558        }
559        return false;
560    }
561
562    public boolean getIsATypeOfRCVGDoc() {
563        return false;
564    }
565
566    public boolean getIsATypeOfCORRDoc() {
567        return false;
568    }
569
570
571    @Override
572    public void doRouteLevelChange(DocumentRouteLevelChange levelChangeEvent) {
573        super.doRouteLevelChange(levelChangeEvent);
574        try {
575            String newNodeName = levelChangeEvent.getNewNodeName();
576            String documentId = this.getDocumentNumber();
577            if (!OLEConstants.PO_NOTE_MAP.containsKey(documentId)
578                    && newNodeName != null
579                    && (newNodeName.equalsIgnoreCase(PurapWorkflowConstants.BUDGET_NODE) || newNodeName
580                    .equalsIgnoreCase(PurapWorkflowConstants.FYI_BUDGET))) {
581                addPurchaseOrderNote(levelChangeEvent);
582                OLEConstants.PO_NOTE_MAP.put(documentId, true);
583
584            }
585        } catch (Exception e) {
586            String errorMsg = "Workflow Error found checking actions requests on document with id "
587                    + getDocumentNumber() + ". *** WILL NOT UPDATE PURAP STATUS ***";
588            LOG.error(errorMsg, e);
589        }
590    }
591
592    public void addPurchaseOrderNote(DocumentRouteLevelChange levelChangeEvent) {
593
594        String newNodeName = levelChangeEvent.getNewNodeName();
595        RoutingReportCriteria.Builder reportCriteria = RoutingReportCriteria.Builder
596                .createByDocumentIdAndTargetNodeName(getDocumentNumber(), newNodeName);
597        if (newNodeName != null
598                && (newNodeName.equalsIgnoreCase(PurapWorkflowConstants.BUDGET_NODE) || newNodeName
599                .equalsIgnoreCase(PurapWorkflowConstants.FYI_BUDGET))) {
600            String note = "";
601            if(newNodeName.equalsIgnoreCase(PurapWorkflowConstants.BUDGET_NODE)){
602                 note = OLEConstants.SufficientFundCheck.POA_NOTE;
603            }
604            if(newNodeName.equalsIgnoreCase(PurapWorkflowConstants.FYI_BUDGET)){
605                note = OLEConstants.SufficientFundCheck.FYI_NOTE;
606            }
607            DocumentService documentService = SpringContext.getBean(DocumentService.class);
608            Note apoNote = documentService.createNoteFromDocument(this, note);
609            this.addNote(apoNote);
610            String documentTypeName = this.getDocumentHeader().getWorkflowDocument().getDocumentTypeName();
611            if (documentTypeName != null
612                    && documentTypeName.equals(OLEConstants.FinancialDocumentTypeCodes.PURCHASE_ORDER_AMENDMENT)) {
613                documentService.saveDocumentNotes(this);
614            }
615
616        }
617
618    }
619
620    /**
621     * Method overridden for Fund Check Makes sure that accounts for routing has been generated, so that other information can be
622     * retrieved from that
623     */
624    @Override
625    protected void populateAccountsForRouting() {
626        List<SufficientFundsItem> fundsItems = new ArrayList<SufficientFundsItem>();
627        String documentId = this.getDocumentNumber();
628        try {
629            String nodeName = getFinancialSystemDocumentHeader().getWorkflowDocument().getCurrentNodeNames().iterator()
630                    .next();
631            if (nodeName != null
632                    && (nodeName.equalsIgnoreCase(PurapWorkflowConstants.BUDGET_NODE) || nodeName
633                    .equalsIgnoreCase(PurapWorkflowConstants.BUDGET_REVIEW_REQUIRED))) {
634                if (SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear()
635                        .compareTo(getPostingYear()) >= 0) {
636                    List<GeneralLedgerPendingEntry> pendingEntries = getPendingLedgerEntriesForSufficientFundsChecking();
637                    for (GeneralLedgerPendingEntry glpe : pendingEntries) {
638                        glpe.getChartOfAccountsCode();
639                    }
640                    SpringContext.getBean(GeneralLedgerPendingEntryService.class).delete(getDocumentNumber());
641                    fundsItems = SpringContext.getBean(SufficientFundsService.class).checkSufficientFunds(
642                            pendingEntries);
643                    SpringContext.getBean(GeneralLedgerPendingEntryService.class).generateGeneralLedgerPendingEntries(
644                            this);
645                    SpringContext.getBean(BusinessObjectService.class).save(getGeneralLedgerPendingEntries());
646                }
647                SpringContext.getBean(PurapAccountingService.class).updateAccountAmounts(this);
648                accountsForRouting = (SpringContext.getBean(PurapAccountingService.class).generateSummary(getItems()));
649                String documentFiscalYearString = this.getPostingYear().toString();
650                List<String> fundsItemList = new ArrayList<String>();
651                List<String> accountsList = new ArrayList<String>();
652                for (SufficientFundsItem fundsItem : fundsItems) {
653                    fundsItemList.add(fundsItem.getAccount().getChartOfAccountsCode());
654                }
655                setAccountsForRouting(accountsForRouting);
656                refreshNonUpdateableReferences();
657                for (SourceAccountingLine sourceLine : getAccountsForRouting()) {
658                    sourceLine.refreshNonUpdateableReferences();
659                }
660            } else {
661                super.populateAccountsForRouting();
662            }
663        } catch (Exception e) {
664            logAndThrowRuntimeException("Error in populateAccountsForRouting while submitting document with id "
665                    + getDocumentNumber(), e);
666        }
667    }
668
669
670    @Override
671    protected boolean isBudgetReviewRequired() {
672        OleRequisitionDocumentService oleRequisitionDocumentService = (OleRequisitionDocumentService) SpringContext
673                .getBean("oleRequisitionDocumentService");
674        boolean sufficientFundCheck = false;
675        List<SourceAccountingLine> sourceAccountingLineList = this.getSourceAccountingLines();
676        for (SourceAccountingLine accLine : sourceAccountingLineList) {
677            Map searchMap = new HashMap();
678            String notificationOption = null;
679            Map<String, Object> key = new HashMap<String, Object>();
680            String chartCode = accLine.getChartOfAccountsCode();
681            String accNo = accLine.getAccountNumber();
682            String objectCd = accLine.getFinancialObjectCode();
683            key.put(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, chartCode);
684            key.put(OLEPropertyConstants.ACCOUNT_NUMBER, accNo);
685            OleSufficientFundCheck account = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(
686                    OleSufficientFundCheck.class, key);
687            if (account != null) {
688                notificationOption = account.getNotificationOption();
689            }
690            if (notificationOption != null
691                    && (notificationOption.equals(OLEPropertyConstants.BUD_REVIEW))) {
692                sufficientFundCheck = oleRequisitionDocumentService.hasSufficientFundsOnRequisition(accLine);
693                if (sufficientFundCheck) {
694                    return true;
695                }
696            }
697        }
698        return sufficientFundCheck;
699    }
700
701    private boolean isNotificationRequired() {
702        OleRequisitionDocumentService oleRequisitionDocumentService = (OleRequisitionDocumentService) SpringContext
703                .getBean("oleRequisitionDocumentService");
704        List<SourceAccountingLine> sourceAccountingLineList = this.getSourceAccountingLines();
705        boolean sufficientFundCheck = false;
706        for (SourceAccountingLine accLine : sourceAccountingLineList) {
707            Map searchMap = new HashMap();
708            String notificationOption = null;
709            Map<String, Object> key = new HashMap<String, Object>();
710            String chartCode = accLine.getChartOfAccountsCode();
711            String accNo = accLine.getAccountNumber();
712            String objectCd = accLine.getFinancialObjectCode();
713            key.put(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, chartCode);
714            key.put(OLEPropertyConstants.ACCOUNT_NUMBER, accNo);
715            OleSufficientFundCheck account = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(
716                    OleSufficientFundCheck.class, key);
717            if (account != null) {
718                notificationOption = account.getNotificationOption();
719            }
720            if (notificationOption != null && notificationOption.equals(OLEPropertyConstants.NOTIFICATION)) {
721                sufficientFundCheck =  oleRequisitionDocumentService.hasSufficientFundsOnRequisition(accLine);
722                if (sufficientFundCheck) {
723                    return true;
724                }
725            }
726        }
727        return sufficientFundCheck;
728    }
729
730    private void populateVendorAliasName() {
731        Map vendorDetailMap = new HashMap();
732        vendorDetailMap.put(OLEConstants.VENDOR_HEADER_IDENTIFIER, this.getVendorHeaderGeneratedIdentifier());
733        vendorDetailMap.put(OLEConstants.VENDOR_DETAIL_IDENTIFIER, this.getVendorDetailAssignedIdentifier());
734        List<VendorAlias> vendorDetailList = (List) getBusinessObjectService().findMatching(VendorAlias.class, vendorDetailMap);
735        if (vendorDetailList != null && vendorDetailList.size() > 0) {
736            this.setVendorAliasName(vendorDetailList.get(0).getVendorAliasName());
737        }
738    }
739
740}