View Javadoc
1   /*
2    * Copyright 2006 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  
17  package org.kuali.ole.module.purap.document;
18  
19  import org.apache.commons.lang.StringUtils;
20  import org.joda.time.DateTime;
21  import org.kuali.ole.module.purap.PurapConstants;
22  import org.kuali.ole.module.purap.PurapConstants.RequisitionStatuses;
23  import org.kuali.ole.module.purap.PurapKeyConstants;
24  import org.kuali.ole.module.purap.PurapParameterConstants;
25  import org.kuali.ole.module.purap.PurapWorkflowConstants;
26  import org.kuali.ole.module.purap.businessobject.*;
27  import org.kuali.ole.module.purap.document.service.*;
28  import org.kuali.ole.sys.OLEConstants;
29  import org.kuali.ole.sys.businessobject.Building;
30  import org.kuali.ole.sys.businessobject.ChartOrgHolder;
31  import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper;
32  import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntrySourceDetail;
33  import org.kuali.ole.sys.context.SpringContext;
34  import org.kuali.ole.sys.service.FinancialSystemUserService;
35  import org.kuali.ole.sys.service.UniversityDateService;
36  import org.kuali.ole.vnd.businessobject.VendorContract;
37  import org.kuali.ole.vnd.businessobject.VendorDetail;
38  import org.kuali.ole.vnd.document.service.VendorService;
39  import org.kuali.ole.vnd.service.PhoneNumberService;
40  import org.kuali.rice.core.api.config.property.ConfigurationService;
41  import org.kuali.rice.core.api.datetime.DateTimeService;
42  import org.kuali.rice.core.api.util.type.KualiDecimal;
43  import org.kuali.rice.core.web.format.DateViewDateObjectFormatter;
44  import org.kuali.rice.core.web.format.Formatter;
45  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
46  import org.kuali.rice.kew.api.KewApiConstants;
47  import org.kuali.rice.kew.api.action.ActionTaken;
48  import org.kuali.rice.kew.api.exception.WorkflowException;
49  import org.kuali.rice.kew.framework.postprocessor.DocumentRouteLevelChange;
50  import org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange;
51  import org.kuali.rice.kim.api.identity.Person;
52  import org.kuali.rice.kim.api.identity.PersonService;
53  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
54  import org.kuali.rice.krad.document.Copyable;
55  import org.kuali.rice.krad.exception.ValidationException;
56  import org.kuali.rice.krad.service.BusinessObjectService;
57  import org.kuali.rice.krad.service.PersistenceService;
58  import org.kuali.rice.krad.util.GlobalVariables;
59  import org.kuali.rice.krad.util.ObjectUtils;
60  import org.kuali.rice.krad.workflow.service.WorkflowDocumentService;
61  
62  import java.util.*;
63  
64  //import org.kuali.ole.module.purap.document.service.impl.PurapServiceImpl;
65  
66  /**
67   * Document class for the Requisition.
68   */
69  public class RequisitionDocument extends PurchasingDocumentBase implements Copyable {
70      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(RequisitionDocument.class);
71  
72      protected String requisitionOrganizationReference1Text;
73      protected String requisitionOrganizationReference2Text;
74      protected String requisitionOrganizationReference3Text;
75      protected String alternate1VendorName;
76      protected String alternate2VendorName;
77      protected String alternate3VendorName;
78      protected String alternate4VendorName;
79      protected String alternate5VendorName;
80      protected KualiDecimal organizationAutomaticPurchaseOrderLimit;
81      protected List reqStatusList;
82  
83      // non-persistent property used for controlling validation for accounting lines when doc is request for blanket approve.
84      protected boolean isBlanketApproveRequest = false;
85  
86      /**
87       * Default constructor.
88       */
89      public RequisitionDocument() {
90          super();
91      }
92  
93      @Override
94      public PurchasingDocumentSpecificService getDocumentSpecificService() {
95          return SpringContext.getBean(RequisitionService.class);
96      }
97  
98      /**
99       * Provides answers to the following splits:
100      * AmountRequiresSeparationOfDutiesReview
101      *
102      * @see org.kuali.ole.sys.document.FinancialSystemTransactionalDocumentBase#answerSplitNodeQuestion(java.lang.String)
103      */
104     @Override
105     public boolean answerSplitNodeQuestion(String nodeName) throws UnsupportedOperationException {
106         if (nodeName.equals(PurapWorkflowConstants.HAS_ACCOUNTING_LINES)) {
107             return !isMissingAccountingLines();
108         }
109         if (nodeName.equals(PurapWorkflowConstants.AMOUNT_REQUIRES_SEPARATION_OF_DUTIES_REVIEW_SPLIT)) {
110             return isSeparationOfDutiesReviewRequired();
111         }
112         return super.answerSplitNodeQuestion(nodeName);
113     }
114 
115     protected boolean isMissingAccountingLines() {
116         for (Iterator iterator = getItems().iterator(); iterator.hasNext(); ) {
117             RequisitionItem item = (RequisitionItem) iterator.next();
118             if (item.isConsideredEntered() && item.isAccountListEmpty()) {
119                 return true;
120             }
121         }
122 
123         return false;
124     }
125 
126     protected boolean isSeparationOfDutiesReviewRequired() {
127         try {
128             Set<Person> priorApprovers = this.getAllPriorApprovers();
129 
130             boolean noPriorApprover = (priorApprovers.size() == 0);
131 
132             // if there are more than 0 prior approvers which means there had been at least another approver than the current approver
133             // then no need for separation of duties
134             if (priorApprovers.size() > 0) {
135                 return false;
136             }
137 
138             //If there was no prior approver, then we have to check the amounts to determine whether to route to separation of duties,
139             //as mentioned below.
140             if (noPriorApprover) {
141                 ParameterService parameterService = SpringContext.getBean(ParameterService.class);
142                 KualiDecimal maxAllowedAmount = new KualiDecimal(parameterService.getParameterValueAsString(RequisitionDocument.class, PurapParameterConstants.SEPARATION_OF_DUTIES_DOLLAR_AMOUNT));
143                 // if app param amount is greater than or equal to documentTotalAmount... no need for separation of duties
144                 KualiDecimal totalAmount = getFinancialSystemDocumentHeader().getFinancialDocumentTotalAmount();
145                 if (ObjectUtils.isNotNull(maxAllowedAmount) && ObjectUtils.isNotNull(totalAmount) && (maxAllowedAmount.compareTo(totalAmount) >= 0)) {
146                     return false;
147                 } else {
148                     return true;
149                 }
150             }
151 
152         } catch (WorkflowException we) {
153             LOG.error("Exception while attempting to retrieve all prior approvers from workflow: ", we);
154         }
155 
156         return false;
157 
158     }
159 
160     public Set<Person> getAllPriorApprovers() throws WorkflowException {
161         PersonService personService = KimApiServiceLocator.getPersonService();
162         List<ActionTaken> actionsTaken = this.getFinancialSystemDocumentHeader().getWorkflowDocument().getActionsTaken();
163         Set<String> principalIds = new HashSet<String>();
164         Set<Person> persons = new HashSet<Person>();
165 
166         for (ActionTaken actionTaken : actionsTaken) {
167             if (KewApiConstants.ACTION_TAKEN_APPROVED_CD.equals(actionTaken.getActionTaken().getCode())) {
168                 String principalId = actionTaken.getPrincipalId();
169                 if (!principalIds.contains(principalId)) {
170                     principalIds.add(principalId);
171                     persons.add(personService.getPerson(principalId));
172                 }
173             }
174         }
175         return persons;
176     }
177 
178     /**
179      * Overrides the method in PurchasingAccountsPayableDocumentBase to add the criteria
180      * specific to Requisition Document.
181      *
182      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocumentBase#isInquiryRendered()
183      */
184     @Override
185     public boolean isInquiryRendered() {
186         if (isPostingYearPrior() &&
187                 (getApplicationDocumentStatus().equals(PurapConstants.RequisitionStatuses.APPDOC_CLOSED) ||
188                         getApplicationDocumentStatus().equals(PurapConstants.RequisitionStatuses.APPDOC_CANCELLED))) {
189             return false;
190         } else {
191             return true;
192         }
193     }
194 
195     /**
196      * Performs logic needed to initiate Requisition Document.
197      */
198     public void initiateDocument() throws WorkflowException {
199         this.setupAccountDistributionMethod();
200         this.setRequisitionSourceCode(PurapConstants.RequisitionSources.STANDARD_ORDER);
201         updateAndSaveAppDocStatus(PurapConstants.RequisitionStatuses.APPDOC_IN_PROCESS);
202         this.setPurchaseOrderCostSourceCode(PurapConstants.POCostSources.ESTIMATE);
203         this.setPurchaseOrderTransmissionMethodCode(determinePurchaseOrderTransmissionMethod());
204         this.setDocumentFundingSourceCode(SpringContext.getBean(ParameterService.class).getParameterValueAsString(RequisitionDocument.class, PurapParameterConstants.DEFAULT_FUNDING_SOURCE));
205         this.setUseTaxIndicator(SpringContext.getBean(PurchasingService.class).getDefaultUseTaxIndicatorValue(this));
206 
207         Person currentUser = GlobalVariables.getUserSession().getPerson();
208         ChartOrgHolder purapChartOrg = SpringContext.getBean(FinancialSystemUserService.class).getPrimaryOrganization(currentUser, PurapConstants.PURAP_NAMESPACE);
209         if (ObjectUtils.isNotNull(purapChartOrg)) {
210             this.setChartOfAccountsCode(purapChartOrg.getChartOfAccountsCode());
211             this.setOrganizationCode(purapChartOrg.getOrganizationCode());
212         }
213         this.setDeliveryCampusCode(currentUser.getCampusCode());
214         this.setDeliveryToName(currentUser.getName());
215         this.setDeliveryToEmailAddress(currentUser.getEmailAddressUnmasked());
216         this.setDeliveryToPhoneNumber(SpringContext.getBean(PhoneNumberService.class).formatNumberIfPossible(currentUser.getPhoneNumber()));
217         this.setRequestorPersonName(currentUser.getName());
218         this.setRequestorPersonEmailAddress(currentUser.getEmailAddressUnmasked());
219         this.setRequestorPersonPhoneNumber(SpringContext.getBean(PhoneNumberService.class).formatNumberIfPossible(currentUser.getPhoneNumber()));
220 
221         DefaultPrincipalAddress defaultPrincipalAddress = new DefaultPrincipalAddress(currentUser.getPrincipalId());
222         Map addressKeys = SpringContext.getBean(PersistenceService.class).getPrimaryKeyFieldValues(defaultPrincipalAddress);
223         defaultPrincipalAddress = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(DefaultPrincipalAddress.class, addressKeys);
224         if (ObjectUtils.isNotNull(defaultPrincipalAddress) && ObjectUtils.isNotNull(defaultPrincipalAddress.getBuilding())) {
225             if (defaultPrincipalAddress.getBuilding().isActive()) {
226                 this.setDeliveryCampusCode(defaultPrincipalAddress.getCampusCode());
227                 this.templateBuildingToDeliveryAddress(defaultPrincipalAddress.getBuilding());
228                 this.setDeliveryBuildingRoomNumber(defaultPrincipalAddress.getBuildingRoomNumber());
229             } else {
230                 //since building is now inactive, delete default building record
231                 SpringContext.getBean(BusinessObjectService.class).delete(defaultPrincipalAddress);
232             }
233         }
234 
235         // set the APO limit
236         this.setOrganizationAutomaticPurchaseOrderLimit(SpringContext.getBean(PurapService.class).getApoLimit(this.getVendorContractGeneratedIdentifier(), this.getChartOfAccountsCode(), this.getOrganizationCode()));
237 
238         // populate billing address
239         BillingAddress billingAddress = SpringContext.getBean(BusinessObjectService.class).findBySinglePrimaryKey(BillingAddress.class, getDeliveryCampusCode());
240         this.templateBillingAddress(billingAddress);
241 
242         // populate receiving address with the default one for the chart/org
243         loadReceivingAddress();
244 
245         // Load Requistion Statuses
246         //   RequisitionStatusValuesFinder requisitionStatusValuesFinder = new RequisitionStatusValuesFinder();
247         //   reqStatusList = requisitionStatusValuesFinder.getKeyValues();
248 
249 
250         SpringContext.getBean(PurapService.class).addBelowLineItems(this);
251         this.refreshNonUpdateableReferences();
252     }
253 
254     public void templateBuildingToDeliveryAddress(Building building) {
255         if (ObjectUtils.isNotNull(building)) {
256             setDeliveryBuildingCode(building.getBuildingCode());
257             setDeliveryBuildingName(building.getBuildingName());
258             setDeliveryBuildingLine1Address(building.getBuildingStreetAddress());
259             setDeliveryCityName(building.getBuildingAddressCityName());
260             setDeliveryStateCode(building.getBuildingAddressStateCode());
261             setDeliveryPostalCode(building.getBuildingAddressZipCode());
262             setDeliveryCountryCode(building.getBuildingAddressCountryCode());
263         }
264     }
265 
266     /**
267      * Determines what PO transmission method to use.
268      *
269      * @return the PO PO transmission method to use.
270      */
271     protected String determinePurchaseOrderTransmissionMethod() {
272 
273         return SpringContext.getBean(ParameterService.class).getParameterValueAsString(RequisitionDocument.class, PurapParameterConstants.PURAP_DEFAULT_PO_TRANSMISSION_CODE);
274     }
275 
276     /**
277      * Checks whether copying of this document should be allowed. Copying is not allowed if this is a B2B requistion, and more than
278      * a set number of days have passed since the document's creation.
279      *
280      * @return True if copying of this requisition is allowed.
281      * @see org.kuali.rice.kns.document.Document#getAllowsCopy()
282      */
283     @Override
284     public boolean getAllowsCopy() {
285         boolean allowsCopy = super.getAllowsCopy();
286         if (PurapConstants.RequisitionSources.B2B.equals(getRequisitionSourceCode())) {
287             DateTimeService dateTimeService = SpringContext.getBean(DateTimeService.class);
288             Calendar c = Calendar.getInstance();
289 
290             // The allowed copy date is the document creation date plus a set number of days.
291             DateTime createDate = this.getFinancialSystemDocumentHeader().getWorkflowDocument().getDateCreated();
292             c.setTime(createDate.toDate());
293             String allowedCopyDays = SpringContext.getBean(ParameterService.class).getParameterValueAsString(RequisitionDocument.class, PurapParameterConstants.B2B_ALLOW_COPY_DAYS);
294             c.add(Calendar.DATE, Integer.parseInt(allowedCopyDays));
295             Date allowedCopyDate = c.getTime();
296             Date currentDate = dateTimeService.getCurrentDate();
297 
298             // Return true if the current time is before the allowed copy date.
299             allowsCopy = (dateTimeService.dateDiff(currentDate, allowedCopyDate, false) > 0);
300         }
301         return allowsCopy;
302     }
303 
304     /**
305      * Performs logic needed to copy Requisition Document.
306      *
307      * @see org.kuali.rice.kns.document.Document#toCopy()
308      */
309     @Override
310     public void toCopy() throws WorkflowException, ValidationException {
311         super.toCopy();
312 
313         // Clear related views
314         this.setAccountsPayablePurchasingDocumentLinkIdentifier(null);
315         this.setRelatedViews(null);
316 
317         Person currentUser = GlobalVariables.getUserSession().getPerson();
318         ChartOrgHolder purapChartOrg = SpringContext.getBean(FinancialSystemUserService.class).getPrimaryOrganization(currentUser, PurapConstants.PURAP_NAMESPACE);
319         this.setPurapDocumentIdentifier(null);
320 
321         // Set req status to INPR.
322         //for app doc status
323         updateAndSaveAppDocStatus(PurapConstants.RequisitionStatuses.APPDOC_IN_PROCESS);
324         /*this.setLicensingRequirementCode(PurapConstants.LicenseRequestStatus.NO_LICENSE_REQUIRED);*/
325         /*this.setLicensingRequirementIndicator(false);*/
326         // Set fields from the user.
327         if (ObjectUtils.isNotNull(purapChartOrg)) {
328             this.setChartOfAccountsCode(purapChartOrg.getChartOfAccountsCode());
329             this.setOrganizationCode(purapChartOrg.getOrganizationCode());
330         }
331         this.setPostingYear(SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear());
332 
333         boolean activeVendor = true;
334         boolean activeContract = true;
335         Date today = SpringContext.getBean(DateTimeService.class).getCurrentDate();
336         VendorContract vendorContract = new VendorContract();
337         vendorContract.setVendorContractGeneratedIdentifier(this.getVendorContractGeneratedIdentifier());
338         Map keys = SpringContext.getBean(PersistenceService.class).getPrimaryKeyFieldValues(vendorContract);
339         vendorContract = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(VendorContract.class, keys);
340         if (!(vendorContract != null && today.after(vendorContract.getVendorContractBeginningDate()) && today.before(vendorContract.getVendorContractEndDate()))) {
341             activeContract = false;
342         }
343 
344         VendorDetail vendorDetail = SpringContext.getBean(VendorService.class).getVendorDetail(this.getVendorHeaderGeneratedIdentifier(), this.getVendorDetailAssignedIdentifier());
345         if (!(vendorDetail != null && vendorDetail.isActiveIndicator())) {
346             activeVendor = false;
347         }
348 
349         // B2B - only copy if contract and vendor are both active (throw separate errors to print to screen)
350         if (this.getRequisitionSourceCode().equals(PurapConstants.RequisitionSources.B2B)) {
351             if (!activeContract) {
352                 throw new ValidationException(PurapKeyConstants.ERROR_REQ_COPY_EXPIRED_CONTRACT);
353             }
354             if (!activeVendor) {
355                 throw new ValidationException(PurapKeyConstants.ERROR_REQ_COPY_INACTIVE_VENDOR);
356             }
357         }
358 
359         if (!activeVendor) {
360             this.setVendorContractGeneratedIdentifier(null);
361         }
362         if (!activeContract) {
363             this.setVendorContractGeneratedIdentifier(null);
364         }
365 
366         // These fields should not be set in this method; force to be null
367         this.setOrganizationAutomaticPurchaseOrderLimit(null);
368         this.setPurchaseOrderAutomaticIndicator(false);
369 
370         for (Iterator iter = this.getItems().iterator(); iter.hasNext(); ) {
371             RequisitionItem item = (RequisitionItem) iter.next();
372             item.setPurapDocumentIdentifier(null);
373             item.setItemIdentifier(null);
374             for (Iterator acctIter = item.getSourceAccountingLines().iterator(); acctIter.hasNext(); ) {
375                 RequisitionAccount account = (RequisitionAccount) acctIter.next();
376                 account.setAccountIdentifier(null);
377                 account.setItemIdentifier(null);
378                 account.setObjectId(null);
379                 account.setVersionNumber(null);
380             }
381         }
382 
383         if (!PurapConstants.RequisitionSources.B2B.equals(this.getRequisitionSourceCode())) {
384             SpringContext.getBean(PurapService.class).addBelowLineItems(this);
385         }
386         this.setOrganizationAutomaticPurchaseOrderLimit(SpringContext.getBean(PurapService.class).getApoLimit(this.getVendorContractGeneratedIdentifier(), this.getChartOfAccountsCode(), this.getOrganizationCode()));
387         clearCapitalAssetFields();
388         SpringContext.getBean(PurapService.class).clearTax(this, this.isUseTaxIndicator());
389 
390         this.refreshNonUpdateableReferences();
391     }
392 
393     @Override
394     public List<String> getWorkflowEngineDocumentIdsToLock() {
395         List<String> docIdStrings = new ArrayList<String>();
396         docIdStrings.add(getDocumentNumber());
397 
398         //  PROCESSED
399         if (this.getFinancialSystemDocumentHeader().getWorkflowDocument().isProcessed()) {
400             // creates a new PO but no way to know what the docID will be ahead of time
401         }
402 
403         return docIdStrings;
404     }
405 
406     /**
407      * @see org.kuali.rice.kns.document.DocumentBase#doRouteStatusChange()
408      */
409     @Override
410     public void doRouteStatusChange(DocumentRouteStatusChange statusChangeEvent) {
411         LOG.debug("doRouteStatusChange() started");
412         super.doRouteStatusChange(statusChangeEvent);
413 
414         try {
415             // DOCUMENT PROCESSED
416             if (this.getFinancialSystemDocumentHeader().getWorkflowDocument().isProcessed()) {
417                 String newRequisitionStatus = PurapConstants.RequisitionStatuses.APPDOC_IN_PROCESS;
418                 if (SpringContext.getBean(RequisitionService.class).isAutomaticPurchaseOrderAllowed(this)) {
419                     newRequisitionStatus = PurapConstants.RequisitionStatuses.APPDOC_CLOSED;
420                     SpringContext.getBean(PurchaseOrderService.class).createAutomaticPurchaseOrderDocument(this);
421                 }
422                 // for app doc status
423                 String reqStatus = PurapConstants.RequisitionStatuses.getRequistionAppDocStatuses().get(newRequisitionStatus);
424                 updateAndSaveAppDocStatus(reqStatus);
425             }
426             // DOCUMENT DISAPPROVED
427             else if (this.getFinancialSystemDocumentHeader().getWorkflowDocument().isDisapproved()) {
428                 String nodeName = SpringContext.getBean(WorkflowDocumentService.class).getCurrentRouteLevelName(this.getFinancialSystemDocumentHeader().getWorkflowDocument());
429                 String disapprovalStatus = RequisitionStatuses.getRequistionAppDocStatuses().get(nodeName);
430 
431                 if (StringUtils.isNotBlank(disapprovalStatus)) {
432                     updateAndSaveAppDocStatus(disapprovalStatus);
433                 } else {
434                     logAndThrowRuntimeException("No status found to set for document being disapproved in node '" + nodeName + "'");
435                 }
436             }
437             // DOCUMENT CANCELED
438             else if (this.getFinancialSystemDocumentHeader().getWorkflowDocument().isCanceled()) {
439                 String reqStatus = RequisitionStatuses.getRequistionAppDocStatuses().get(RequisitionStatuses.APPDOC_CANCELLED);
440                 updateAndSaveAppDocStatus(reqStatus);
441             }
442         } catch (WorkflowException e) {
443             logAndThrowRuntimeException("Error saving routing data while saving document with id " + getDocumentNumber(), e);
444         }
445         LOG.debug("doRouteStatusChange() ending");
446     }
447 
448     /**
449      * @see org.kuali.rice.kns.document.DocumentBase#handleRouteLevelChange(org.kuali.rice.kew.clientapp.vo.DocumentRouteLevelChangeDTO)
450      */
451     @Override
452     public void doRouteLevelChange(DocumentRouteLevelChange change) {
453         LOG.debug("handleRouteLevelChange() started");
454         super.doRouteLevelChange(change);
455 /*
456   FIXME: Remove this code
457         try {
458             String newNodeName = change.getNewNodeName();
459             if (StringUtils.isNotBlank(newNodeName)) {
460                 ReportCriteriaDTO reportCriteriaDTO = new ReportCriteriaDTO(Long.valueOf(getDocumentNumber()));
461                 reportCriteriaDTO.setTargetNodeName(newNodeName);
462                 if (SpringContext.getBean(KualiWorkflowInfo.class).documentWillHaveAtLeastOneActionRequest(reportCriteriaDTO, new String[] { KewApiConstants.ACTION_REQUEST_APPROVE_REQ, KewApiConstants.ACTION_REQUEST_COMPLETE_REQ }, false)) {
463                     NodeDetails currentNode = NodeDetailEnum.getNodeDetailEnumByName(newNodeName);
464                     if (ObjectUtils.isNotNull(currentNode)) {
465                         if (StringUtils.isNotBlank(currentNode.getAwaitingStatusCode())) {
466                             updateStatusAndSave(currentNode.getAwaitingStatusCode());
467                         }
468                     }
469                 }
470                 else {
471                     if (LOG.isDebugEnabled()) {
472                         LOG.debug("Document with id " + getDocumentNumber() + " will not stop in route node '" + newNodeName + "'");
473                     }
474                 }
475             }
476         }
477         catch (WorkflowException e) {
478             String errorMsg = "Workflow Error found checking actions requests on document with id " + getDocumentNumber() + ". *** WILL NOT UPDATE PURAP STATUS ***";
479             LOG.warn(errorMsg, e);
480         }
481         */
482     }
483 
484     /**
485      * @see org.kuali.ole.sys.document.AccountingDocument#getSourceAccountingLineClass()
486      */
487     @Override
488     public Class getSourceAccountingLineClass() {
489         //NOTE: do not do anything with this method as it is used by routing etc!
490         return super.getSourceAccountingLineClass();
491     }
492 
493     public String getRequisitionOrganizationReference1Text() {
494         return requisitionOrganizationReference1Text;
495     }
496 
497     public void setRequisitionOrganizationReference1Text(String requisitionOrganizationReference1Text) {
498         this.requisitionOrganizationReference1Text = requisitionOrganizationReference1Text;
499     }
500 
501     public String getRequisitionOrganizationReference2Text() {
502         return requisitionOrganizationReference2Text;
503     }
504 
505     public void setRequisitionOrganizationReference2Text(String requisitionOrganizationReference2Text) {
506         this.requisitionOrganizationReference2Text = requisitionOrganizationReference2Text;
507     }
508 
509     public String getRequisitionOrganizationReference3Text() {
510         return requisitionOrganizationReference3Text;
511     }
512 
513     public void setRequisitionOrganizationReference3Text(String requisitionOrganizationReference3Text) {
514         this.requisitionOrganizationReference3Text = requisitionOrganizationReference3Text;
515     }
516 
517     public String getAlternate1VendorName() {
518         return alternate1VendorName;
519     }
520 
521     public void setAlternate1VendorName(String alternate1VendorName) {
522         this.alternate1VendorName = alternate1VendorName;
523     }
524 
525     public String getAlternate2VendorName() {
526         return alternate2VendorName;
527     }
528 
529     public void setAlternate2VendorName(String alternate2VendorName) {
530         this.alternate2VendorName = alternate2VendorName;
531     }
532 
533     public String getAlternate3VendorName() {
534         return alternate3VendorName;
535     }
536 
537     public void setAlternate3VendorName(String alternate3VendorName) {
538         this.alternate3VendorName = alternate3VendorName;
539     }
540 
541     public String getAlternate4VendorName() {
542         return alternate4VendorName;
543     }
544 
545     public void setAlternate4VendorName(String alternate4VendorName) {
546         this.alternate4VendorName = alternate4VendorName;
547     }
548 
549     public String getAlternate5VendorName() {
550         return alternate5VendorName;
551     }
552 
553     public void setAlternate5VendorName(String alternate5VendorName) {
554         this.alternate5VendorName = alternate5VendorName;
555     }
556 
557     public KualiDecimal getOrganizationAutomaticPurchaseOrderLimit() {
558         return organizationAutomaticPurchaseOrderLimit;
559     }
560 
561     public void setOrganizationAutomaticPurchaseOrderLimit(KualiDecimal organizationAutomaticPurchaseOrderLimit) {
562         this.organizationAutomaticPurchaseOrderLimit = organizationAutomaticPurchaseOrderLimit;
563     }
564 
565     /**
566      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocumentBase#getItemClass()
567      */
568     @Override
569     public Class getItemClass() {
570         return RequisitionItem.class;
571     }
572 
573     @Override
574     public Class getItemUseTaxClass() {
575         return PurchaseRequisitionItemUseTax.class;
576     }
577 
578     /**
579      * Returns null as requistion has no source document.
580      *
581      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocumentBase#getPurApSourceDocumentIfPossible()
582      */
583     @Override
584     public PurchasingAccountsPayableDocument getPurApSourceDocumentIfPossible() {
585         return null;
586     }
587 
588     /**
589      * Returns null as requistion has no source document.
590      *
591      * @see org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocumentBase#getPurApSourceDocumentLabelIfPossible()
592      */
593     @Override
594     public String getPurApSourceDocumentLabelIfPossible() {
595         return null;
596     }
597 
598     /**
599      * @see org.kuali.rice.kns.document.Document#getDocumentTitle()
600      */
601     @Override
602     public String getDocumentTitle() {
603         String title = "";
604         if (SpringContext.getBean(ParameterService.class).getParameterValueAsBoolean(RequisitionDocument.class, PurapParameterConstants.PURAP_OVERRIDE_REQ_DOC_TITLE)) {
605             String docIdStr = "";
606             if ((this.getPurapDocumentIdentifier() != null) && (StringUtils.isNotBlank(this.getPurapDocumentIdentifier().toString()))) {
607                 docIdStr = "Requisition: " + this.getPurapDocumentIdentifier().toString();
608             }
609             String chartAcct = this.getFirstChartAccount();
610             String chartAcctStr = (chartAcct == null ? "" : " - Account Number:  " + chartAcct);
611             title = docIdStr + chartAcctStr;
612         } else {
613             title = super.getDocumentTitle();
614         }
615         return title;
616     }
617 
618     /**
619      * Gets this requisition's Chart/Account of the first accounting line from the first item.
620      *
621      * @return The first Chart and Account, or an empty string if there is none.
622      */
623     protected String getFirstChartAccount() {
624         String chartAcct = null;
625         RequisitionItem item = (RequisitionItem) this.getItem(0);
626         if (ObjectUtils.isNotNull(item)) {
627             if (item.getSourceAccountingLines().size() > 0) {
628                 PurApAccountingLine accountLine = item.getSourceAccountingLine(0);
629                 if (ObjectUtils.isNotNull(accountLine) && ObjectUtils.isNotNull(accountLine.getChartOfAccountsCode()) && ObjectUtils.isNotNull(accountLine.getAccountNumber())) {
630                     chartAcct = accountLine.getChartOfAccountsCode() + "-" + accountLine.getAccountNumber();
631                 }
632             }
633         }
634         return chartAcct;
635     }
636 
637     public Date getCreateDate() {
638         return this.getFinancialSystemDocumentHeader().getWorkflowDocument().getDateCreated().toDate();
639     }
640 
641     public String getUrl() {
642         return SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(OLEConstants.WORKFLOW_URL_KEY) + "/DocHandler.do?docId=" + getDocumentNumber() + "&command=displayDocSearchView";
643     }
644 
645     /**
646      * This is a "do nothing" version of the method - it just won't create GLPEs
647      *
648      * @see org.kuali.ole.sys.document.AccountingDocumentBase#generateGeneralLedgerPendingEntries(org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntrySourceDetail, org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper)
649      */
650     @Override
651     public boolean generateGeneralLedgerPendingEntries(GeneralLedgerPendingEntrySourceDetail glpeSourceDetail, GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
652         return true;
653     }
654 
655     @Override
656     public Class getPurchasingCapitalAssetItemClass() {
657         return RequisitionCapitalAssetItem.class;
658     }
659 
660     @Override
661     public Class getPurchasingCapitalAssetSystemClass() {
662         return RequisitionCapitalAssetSystem.class;
663     }
664 
665     @Override
666     public boolean shouldGiveErrorForEmptyAccountsProration() {
667         //to be removed
668         //for app doc status
669         //remove   isDocumentStoppedInRouteNode(NodeDetailEnum.CONTENT_REVIEW) kfsmi - 4592
670         if (isDocumentStoppedInRouteNode(RequisitionStatuses.NODE_CONTENT_REVIEW) ||
671                 getApplicationDocumentStatus().equals(PurapConstants.RequisitionStatuses.APPDOC_IN_PROCESS)) {
672             return false;
673         }
674         return true;
675     }
676 
677     public Date getCreateDateForResult() {
678         Formatter formatter = new DateViewDateObjectFormatter();
679         return (Date) formatter.format(this.getFinancialSystemDocumentHeader().getWorkflowDocument().getDateCreated().toDate());
680     }
681 
682     /**
683      * Gets the isBlanketApproveRequest attribute.
684      *
685      * @return Returns the isBlanketApproveRequest.
686      */
687     public boolean isBlanketApproveRequest() {
688         return isBlanketApproveRequest;
689     }
690 
691     /**
692      * Sets the isBlanketApproveRequest attribute value.
693      *
694      * @param isBlanketApproveRequest The isBlanketApproveRequest to set.
695      */
696     public void setBlanketApproveRequest(boolean isBlanketApproveRequest) {
697         this.isBlanketApproveRequest = isBlanketApproveRequest;
698     }
699 
700     /**
701      * retrieves the system parameter value for account distribution method and determines
702      * if the drop-down box on the form should be read only or not.  Sets the default
703      * value for account distribution method property on the document.
704      */
705     public void setupAccountDistributionMethod() {
706         // OLE-3405 : disabling the distribution method choice
707         //String defaultDistributionMethod = SpringContext.getBean(ParameterService.class).getParameterValueAsString(PurapConstants.PURAP_NAMESPACE, "Document", PurapParameterConstants.DISTRIBUTION_METHOD_FOR_ACCOUNTING_LINES);
708         String defaultDistributionMethodCode = "P";//PurapConstants.AccountDistributionMethodCodes.PROPORTIONAL_CODE;
709 
710 //        if (PurapConstants.AccountDistributionMethodCodes.PROPORTIONAL_CODE.equalsIgnoreCase(defaultDistributionMethod) || PurapConstants.AccountDistributionMethodCodes.SEQUENTIAL_CODE.equalsIgnoreCase(defaultDistributionMethod)) {
711 //            defaultDistributionMethodCode = defaultDistributionMethod;
712 //        }
713 //        else {
714 //            if (PurapConstants.AccountDistributionMethodCodes.BOTH_WITH_DEFAULT_PROPORTIONAL_CODE.equalsIgnoreCase(defaultDistributionMethod)) {
715 //                defaultDistributionMethodCode = PurapConstants.AccountDistributionMethodCodes.PROPORTIONAL_CODE;
716 //            }
717 //            else if (PurapConstants.AccountDistributionMethodCodes.BOTH_WITH_DEFAULT_SEQUENTIAL_CODE.equalsIgnoreCase(defaultDistributionMethod)){
718 //                defaultDistributionMethodCode = PurapConstants.AccountDistributionMethodCodes.SEQUENTIAL_CODE;
719 //                }
720 //                else {
721 //                    new RuntimeException("Error in reading system parameter values for DISTRIBUTION_METHOD_FOR_ACCOUNTING_LINES");
722 //                }
723 //        }
724         setAccountDistributionMethod(defaultDistributionMethodCode);
725     }
726 
727 }
728