/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kuali.kfs.module.purap.document; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.joda.time.DateTime; import org.kuali.kfs.module.purap.PurapConstants; import org.kuali.kfs.module.purap.PurapConstants.RequisitionStatuses; import org.kuali.kfs.module.purap.PurapKeyConstants; import org.kuali.kfs.module.purap.PurapParameterConstants; import org.kuali.kfs.module.purap.PurapWorkflowConstants; import org.kuali.kfs.module.purap.businessobject.BillingAddress; import org.kuali.kfs.module.purap.businessobject.DefaultPrincipalAddress; import org.kuali.kfs.module.purap.businessobject.PurApAccountingLine; import org.kuali.kfs.module.purap.businessobject.PurchaseRequisitionItemUseTax; import org.kuali.kfs.module.purap.businessobject.RequisitionAccount; import org.kuali.kfs.module.purap.businessobject.RequisitionCapitalAssetItem; import org.kuali.kfs.module.purap.businessobject.RequisitionCapitalAssetSystem; import org.kuali.kfs.module.purap.businessobject.RequisitionItem; import org.kuali.kfs.module.purap.businessobject.options.RequisitionStatusValuesFinder; import org.kuali.kfs.module.purap.document.service.PurapService; import org.kuali.kfs.module.purap.document.service.PurchaseOrderService; import org.kuali.kfs.module.purap.document.service.PurchasingDocumentSpecificService; import org.kuali.kfs.module.purap.document.service.PurchasingService; import org.kuali.kfs.module.purap.document.service.RequisitionService; import org.kuali.kfs.sys.KFSConstants; import org.kuali.kfs.sys.businessobject.Building; import org.kuali.kfs.sys.businessobject.ChartOrgHolder; import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper; import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.kfs.sys.service.FinancialSystemUserService; import org.kuali.kfs.sys.service.UniversityDateService; import org.kuali.kfs.vnd.businessobject.VendorContract; import org.kuali.kfs.vnd.businessobject.VendorDetail; import org.kuali.kfs.vnd.document.service.VendorService; import org.kuali.kfs.vnd.service.PhoneNumberService; import org.kuali.rice.core.api.config.property.ConfigurationService; import org.kuali.rice.core.api.datetime.DateTimeService; import org.kuali.rice.core.api.util.type.KualiDecimal; import org.kuali.rice.core.web.format.DateViewDateObjectFormatter; import org.kuali.rice.core.web.format.Formatter; import org.kuali.rice.coreservice.framework.parameter.ParameterService; import org.kuali.rice.kew.api.KewApiConstants; import org.kuali.rice.kew.api.action.ActionTaken; import org.kuali.rice.kew.api.exception.WorkflowException; import org.kuali.rice.kew.framework.postprocessor.DocumentRouteLevelChange; import org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange; import org.kuali.rice.kim.api.identity.Person; import org.kuali.rice.kim.api.identity.PersonService; import org.kuali.rice.kim.api.services.KimApiServiceLocator; import org.kuali.rice.krad.document.Copyable; import org.kuali.rice.krad.exception.ValidationException; import org.kuali.rice.krad.service.BusinessObjectService; import org.kuali.rice.krad.service.PersistenceService; import org.kuali.rice.krad.util.GlobalVariables; import org.kuali.rice.krad.util.ObjectUtils; import org.kuali.rice.krad.workflow.service.WorkflowDocumentService; /** * Document class for the Requisition. */ public class RequisitionDocument extends PurchasingDocumentBase implements Copyable { private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(RequisitionDocument.class); protected String requisitionOrganizationReference1Text; protected String requisitionOrganizationReference2Text; protected String requisitionOrganizationReference3Text; protected String alternate1VendorName; protected String alternate2VendorName; protected String alternate3VendorName; protected String alternate4VendorName; protected String alternate5VendorName; protected KualiDecimal organizationAutomaticPurchaseOrderLimit; protected List reqStatusList; // non-persistent property used for controlling validation for accounting lines when doc is request for blanket approve. protected boolean isBlanketApproveRequest = false; private static final int ALLOW_REQS_UNLIMITED_COPY_DAYS=9999; /** * Default constructor. */ public RequisitionDocument() { super(); } @Override public PurchasingDocumentSpecificService getDocumentSpecificService() { return SpringContext.getBean(RequisitionService.class); } /** * Provides answers to the following splits: * AmountRequiresSeparationOfDutiesReview * * @see org.kuali.kfs.sys.document.FinancialSystemTransactionalDocumentBase#answerSplitNodeQuestion(java.lang.String) */ @Override public boolean answerSplitNodeQuestion(String nodeName) throws UnsupportedOperationException { if (nodeName.equals(PurapWorkflowConstants.HAS_ACCOUNTING_LINES)) { return !isMissingAccountingLines(); } if (nodeName.equals(PurapWorkflowConstants.AMOUNT_REQUIRES_SEPARATION_OF_DUTIES_REVIEW_SPLIT)) { return isSeparationOfDutiesReviewRequired(); } return super.answerSplitNodeQuestion(nodeName); } public boolean isMissingAccountingLines() { List<RequisitionItem> itemsWithMissingAccountingLines = getListOfItemsMissingAccountingLines(); return !(itemsWithMissingAccountingLines.isEmpty()); } public List<RequisitionItem> getListOfItemsMissingAccountingLines() { List<RequisitionItem> itemsWithMissingAccountingLines = new ArrayList<RequisitionItem>(); for (Iterator iterator = getItems().iterator(); iterator.hasNext();) { RequisitionItem item = (RequisitionItem) iterator.next(); if (item.isConsideredEntered() && item.isAccountListEmpty()) { itemsWithMissingAccountingLines.add(item); } } return itemsWithMissingAccountingLines; } protected boolean isSeparationOfDutiesReviewRequired() { try { Set<Person> priorApprovers = this.getAllPriorApprovers(); // If there are more than 1 prior approvers there is no need for SOD. // If 1 approver exists, check that approver is not the initiator. if (priorApprovers.size() > 0) { if (priorApprovers.size() > 1) { return false; } else { for (Person priorApprover : priorApprovers) { String initiatorPrincipalId = this.getDocumentHeader().getWorkflowDocument().getInitiatorPrincipalId(); if (!initiatorPrincipalId.equals(priorApprover.getPrincipalId())) { return false; } } } } // If there was no prior approver or if the initiator and the approver are the same person, // then we have to check the amounts to determine whether to route to separation of duties. ParameterService parameterService = SpringContext.getBean(ParameterService.class); KualiDecimal maxAllowedAmount = new KualiDecimal(parameterService.getParameterValueAsString(RequisitionDocument.class, PurapParameterConstants.SEPARATION_OF_DUTIES_DOLLAR_AMOUNT)); // if app param amount is greater than or equal to documentTotalAmount... no need for separation of duties KualiDecimal totalAmount = getFinancialSystemDocumentHeader().getFinancialDocumentTotalAmount(); if (ObjectUtils.isNotNull(maxAllowedAmount) && ObjectUtils.isNotNull(totalAmount) && (maxAllowedAmount.compareTo(totalAmount) >= 0)) { return false; } else { return true; } } catch (WorkflowException we) { LOG.error("Exception while attempting to retrieve all prior approvers from workflow: ", we); } return false; } public Set<Person> getAllPriorApprovers() throws WorkflowException { PersonService personService = KimApiServiceLocator.getPersonService(); List<ActionTaken> actionsTaken = this.getFinancialSystemDocumentHeader().getWorkflowDocument().getActionsTaken(); Set<String> principalIds = new HashSet<String>(); Set<Person> persons = new HashSet<Person>(); for (ActionTaken actionTaken : actionsTaken) { if (KewApiConstants.ACTION_TAKEN_APPROVED_CD.equals(actionTaken.getActionTaken().getCode())) { String principalId = actionTaken.getPrincipalId(); if (!principalIds.contains(principalId)) { principalIds.add(principalId); persons.add(personService.getPerson(principalId)); } } } return persons; } /** * Overrides the method in PurchasingAccountsPayableDocumentBase to add the criteria * specific to Requisition Document. * * @see org.kuali.kfs.module.purap.document.PurchasingAccountsPayableDocumentBase#isInquiryRendered() */ @Override public boolean isInquiryRendered() { if ( isPostingYearPrior() && ( getApplicationDocumentStatus().equals(PurapConstants.RequisitionStatuses.APPDOC_CLOSED) || getApplicationDocumentStatus().equals(PurapConstants.RequisitionStatuses.APPDOC_CANCELLED) ) ) { return false; } else { return true; } } /** * Performs logic needed to initiate Requisition Document. */ public void initiateDocument() throws WorkflowException { this.setupAccountDistributionMethod(); this.setRequisitionSourceCode(PurapConstants.RequisitionSources.STANDARD_ORDER); updateAndSaveAppDocStatus(PurapConstants.RequisitionStatuses.APPDOC_IN_PROCESS); this.setPurchaseOrderCostSourceCode(PurapConstants.POCostSources.ESTIMATE); this.setPurchaseOrderTransmissionMethodCode(determinePurchaseOrderTransmissionMethod()); this.setDocumentFundingSourceCode(SpringContext.getBean(ParameterService.class).getParameterValueAsString(RequisitionDocument.class, PurapParameterConstants.DEFAULT_FUNDING_SOURCE)); this.setUseTaxIndicator(SpringContext.getBean(PurchasingService.class).getDefaultUseTaxIndicatorValue(this)); Person currentUser = GlobalVariables.getUserSession().getPerson(); ChartOrgHolder purapChartOrg = SpringContext.getBean(FinancialSystemUserService.class).getPrimaryOrganization(currentUser, PurapConstants.PURAP_NAMESPACE); if (ObjectUtils.isNotNull(purapChartOrg)) { this.setChartOfAccountsCode(purapChartOrg.getChartOfAccountsCode()); this.setOrganizationCode(purapChartOrg.getOrganizationCode()); } this.setDeliveryCampusCode(currentUser.getCampusCode()); this.setDeliveryToName(currentUser.getName()); this.setDeliveryToEmailAddress(currentUser.getEmailAddressUnmasked()); this.setDeliveryToPhoneNumber(SpringContext.getBean(PhoneNumberService.class).formatNumberIfPossible(currentUser.getPhoneNumber())); this.setRequestorPersonName(currentUser.getName()); this.setRequestorPersonEmailAddress(currentUser.getEmailAddressUnmasked()); this.setRequestorPersonPhoneNumber(SpringContext.getBean(PhoneNumberService.class).formatNumberIfPossible(currentUser.getPhoneNumber())); DefaultPrincipalAddress defaultPrincipalAddress = new DefaultPrincipalAddress(currentUser.getPrincipalId()); Map addressKeys = SpringContext.getBean(PersistenceService.class).getPrimaryKeyFieldValues(defaultPrincipalAddress); defaultPrincipalAddress = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(DefaultPrincipalAddress.class, addressKeys); if (ObjectUtils.isNotNull(defaultPrincipalAddress) && ObjectUtils.isNotNull(defaultPrincipalAddress.getBuilding())) { if (defaultPrincipalAddress.getBuilding().isActive()) { this.setDeliveryCampusCode(defaultPrincipalAddress.getCampusCode()); this.templateBuildingToDeliveryAddress(defaultPrincipalAddress.getBuilding()); this.setDeliveryBuildingRoomNumber(defaultPrincipalAddress.getBuildingRoomNumber()); } else { //since building is now inactive, delete default building record SpringContext.getBean(BusinessObjectService.class).delete(defaultPrincipalAddress); } } // set the APO limit this.setOrganizationAutomaticPurchaseOrderLimit(SpringContext.getBean(PurapService.class).getApoLimit(this.getVendorContractGeneratedIdentifier(), this.getChartOfAccountsCode(), this.getOrganizationCode())); // populate billing address BillingAddress billingAddress = SpringContext.getBean(BusinessObjectService.class).findBySinglePrimaryKey(BillingAddress.class, getDeliveryCampusCode()); this.templateBillingAddress(billingAddress); // populate receiving address with the default one for the chart/org loadReceivingAddress(); // Load Requistion Statuses RequisitionStatusValuesFinder requisitionStatusValuesFinder = new RequisitionStatusValuesFinder(); reqStatusList = requisitionStatusValuesFinder.getKeyValues(); SpringContext.getBean(PurapService.class).addBelowLineItems(this); this.refreshNonUpdateableReferences(); } public void templateBuildingToDeliveryAddress(Building building) { if (ObjectUtils.isNotNull(building)) { setDeliveryBuildingCode(building.getBuildingCode()); setDeliveryBuildingName(building.getBuildingName()); setDeliveryBuildingLine1Address(building.getBuildingStreetAddress()); setDeliveryCityName(building.getBuildingAddressCityName()); setDeliveryStateCode(building.getBuildingAddressStateCode()); setDeliveryPostalCode(building.getBuildingAddressZipCode()); setDeliveryCountryCode(building.getBuildingAddressCountryCode()); } } /** * Determines what PO transmission method to use. * * @return the PO PO transmission method to use. */ protected String determinePurchaseOrderTransmissionMethod() { return SpringContext.getBean(ParameterService.class).getParameterValueAsString(RequisitionDocument.class, PurapParameterConstants.PURAP_DEFAULT_PO_TRANSMISSION_CODE); } /** * Checks whether copying of this document should be allowed. Copying is not allowed if this is a B2B requistion, and more than * a set number of days have passed since the document's creation. * * @return True if copying of this requisition is allowed. * @see org.kuali.rice.kns.document.Document#getAllowsCopy() */ @Override public boolean getAllowsCopy() { boolean allowsCopy = super.getAllowsCopy(); Integer allowedCopyDays=getRequisitionSource().getAllowCopyDays(); if(allowedCopyDays.intValue()==0){ return false; }else if(allowedCopyDays.intValue() >= ALLOW_REQS_UNLIMITED_COPY_DAYS){ return true; }else if(allowedCopyDays.intValue() > 0){ DateTimeService dateTimeService = SpringContext.getBean(DateTimeService.class); Calendar c = Calendar.getInstance(); // The allowed copy date is the document creation date plus a set number of days. DateTime createDate = this.getFinancialSystemDocumentHeader().getWorkflowDocument().getDateCreated(); c.setTime(createDate.toDate()); c.add(Calendar.DATE,(allowedCopyDays.intValue())); Date allowedCopyDate = c.getTime(); Date currentDate = dateTimeService.getCurrentDate(); // Return true if the current time is before the allowed copy date. allowsCopy = currentDate.before(allowedCopyDate); } return allowsCopy; } /** * Performs logic needed to copy Requisition Document. * * @see org.kuali.rice.kns.document.Document#toCopy() */ @Override public void toCopy() throws WorkflowException, ValidationException { super.toCopy(); // Clear related views this.setAccountsPayablePurchasingDocumentLinkIdentifier(null); this.setRelatedViews(null); Person currentUser = GlobalVariables.getUserSession().getPerson(); ChartOrgHolder purapChartOrg = SpringContext.getBean(FinancialSystemUserService.class).getPrimaryOrganization(currentUser, PurapConstants.PURAP_NAMESPACE); this.setPurapDocumentIdentifier(null); // Set req status to INPR. //for app doc status updateAndSaveAppDocStatus(PurapConstants.RequisitionStatuses.APPDOC_IN_PROCESS); // Set fields from the user. if (ObjectUtils.isNotNull(purapChartOrg)) { this.setChartOfAccountsCode(purapChartOrg.getChartOfAccountsCode()); this.setOrganizationCode(purapChartOrg.getOrganizationCode()); } this.setPostingYear(SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear()); boolean activeVendor = true; boolean activeContract = true; Date today = SpringContext.getBean(DateTimeService.class).getCurrentDate(); VendorContract vendorContract = new VendorContract(); vendorContract.setVendorContractGeneratedIdentifier(this.getVendorContractGeneratedIdentifier()); Map keys = SpringContext.getBean(PersistenceService.class).getPrimaryKeyFieldValues(vendorContract); vendorContract = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(VendorContract.class, keys); if (!(vendorContract != null && today.after(vendorContract.getVendorContractBeginningDate()) && today.before(vendorContract.getVendorContractEndDate()))) { activeContract = false; } VendorDetail vendorDetail = SpringContext.getBean(VendorService.class).getVendorDetail(this.getVendorHeaderGeneratedIdentifier(), this.getVendorDetailAssignedIdentifier()); if (!(vendorDetail != null && vendorDetail.isActiveIndicator())) { activeVendor = false; } // B2B - only copy if contract and vendor are both active (throw separate errors to print to screen) if (this.getRequisitionSourceCode().equals(PurapConstants.RequisitionSources.B2B)) { if (!activeContract) { throw new ValidationException(PurapKeyConstants.ERROR_REQ_COPY_EXPIRED_CONTRACT); } if (!activeVendor) { throw new ValidationException(PurapKeyConstants.ERROR_REQ_COPY_INACTIVE_VENDOR); } } if (!activeVendor) { this.setVendorContractGeneratedIdentifier(null); } if (!activeContract) { this.setVendorContractGeneratedIdentifier(null); } // These fields should not be set in this method; force to be null this.setOrganizationAutomaticPurchaseOrderLimit(null); this.setPurchaseOrderAutomaticIndicator(false); for (Iterator iter = this.getItems().iterator(); iter.hasNext();) { RequisitionItem item = (RequisitionItem) iter.next(); item.setPurapDocumentIdentifier(null); item.setItemIdentifier(null); for (Iterator acctIter = item.getSourceAccountingLines().iterator(); acctIter.hasNext();) { RequisitionAccount account = (RequisitionAccount) acctIter.next(); account.setAccountIdentifier(null); account.setItemIdentifier(null); account.setObjectId(null); account.setVersionNumber(null); } } if (!PurapConstants.RequisitionSources.B2B.equals(this.getRequisitionSourceCode())) { SpringContext.getBean(PurapService.class).addBelowLineItems(this); } this.setOrganizationAutomaticPurchaseOrderLimit(SpringContext.getBean(PurapService.class).getApoLimit(this.getVendorContractGeneratedIdentifier(), this.getChartOfAccountsCode(), this.getOrganizationCode())); clearCapitalAssetFields(); SpringContext.getBean(PurapService.class).clearTax(this, this.isUseTaxIndicator()); this.refreshNonUpdateableReferences(); } @Override public List<String> getWorkflowEngineDocumentIdsToLock() { List<String> docIdStrings = new ArrayList<String>(); docIdStrings.add(getDocumentNumber()); // PROCESSED if (this.getFinancialSystemDocumentHeader().getWorkflowDocument().isProcessed()) { // creates a new PO but no way to know what the docID will be ahead of time } return docIdStrings; } /** * @see org.kuali.rice.kns.document.DocumentBase#doRouteStatusChange() */ @Override public void doRouteStatusChange(DocumentRouteStatusChange statusChangeEvent) { LOG.debug("doRouteStatusChange() started"); super.doRouteStatusChange(statusChangeEvent); try { // DOCUMENT PROCESSED if (this.getFinancialSystemDocumentHeader().getWorkflowDocument().isProcessed()) { String newRequisitionStatus = PurapConstants.RequisitionStatuses.APPDOC_AWAIT_CONTRACT_MANAGER_ASSGN; if (SpringContext.getBean(RequisitionService.class).isAutomaticPurchaseOrderAllowed(this)) { newRequisitionStatus = PurapConstants.RequisitionStatuses.APPDOC_CLOSED; SpringContext.getBean(PurchaseOrderService.class).createAutomaticPurchaseOrderDocument(this); } // for app doc status String reqStatus = PurapConstants.RequisitionStatuses.getRequistionAppDocStatuses().get(newRequisitionStatus); updateAndSaveAppDocStatus(reqStatus); } // DOCUMENT DISAPPROVED else if (this.getFinancialSystemDocumentHeader().getWorkflowDocument().isDisapproved()) { String nodeName = SpringContext.getBean(WorkflowDocumentService.class).getCurrentRouteLevelName(this.getFinancialSystemDocumentHeader().getWorkflowDocument()); String disapprovalStatus = RequisitionStatuses.getRequistionAppDocStatuses().get(nodeName); if (StringUtils.isNotBlank(disapprovalStatus)) { updateAndSaveAppDocStatus(disapprovalStatus); }else{ logAndThrowRuntimeException("No status found to set for document being disapproved in node '" + nodeName + "'"); } } // DOCUMENT CANCELED else if (this.getFinancialSystemDocumentHeader().getWorkflowDocument().isCanceled()) { String reqStatus = RequisitionStatuses.getRequistionAppDocStatuses().get(RequisitionStatuses.APPDOC_CANCELLED); updateAndSaveAppDocStatus(reqStatus); } } catch (WorkflowException e) { logAndThrowRuntimeException("Error saving routing data while saving document with id " + getDocumentNumber(), e); } LOG.debug("doRouteStatusChange() ending"); } /** * @see org.kuali.rice.kns.document.DocumentBase#handleRouteLevelChange(org.kuali.rice.kew.clientapp.vo.DocumentRouteLevelChangeDTO) */ @Override public void doRouteLevelChange(DocumentRouteLevelChange change) { LOG.debug("handleRouteLevelChange() started"); super.doRouteLevelChange(change); /* FIXME: Remove this code try { String newNodeName = change.getNewNodeName(); if (StringUtils.isNotBlank(newNodeName)) { ReportCriteriaDTO reportCriteriaDTO = new ReportCriteriaDTO(Long.valueOf(getDocumentNumber())); reportCriteriaDTO.setTargetNodeName(newNodeName); if (SpringContext.getBean(KualiWorkflowInfo.class).documentWillHaveAtLeastOneActionRequest(reportCriteriaDTO, new String[] { KewApiConstants.ACTION_REQUEST_APPROVE_REQ, KewApiConstants.ACTION_REQUEST_COMPLETE_REQ }, false)) { NodeDetails currentNode = NodeDetailEnum.getNodeDetailEnumByName(newNodeName); if (ObjectUtils.isNotNull(currentNode)) { if (StringUtils.isNotBlank(currentNode.getAwaitingStatusCode())) { updateStatusAndSave(currentNode.getAwaitingStatusCode()); } } } else { if (LOG.isDebugEnabled()) { LOG.debug("Document with id " + getDocumentNumber() + " will not stop in route node '" + newNodeName + "'"); } } } } catch (WorkflowException e) { String errorMsg = "Workflow Error found checking actions requests on document with id " + getDocumentNumber() + ". *** WILL NOT UPDATE PURAP STATUS ***"; LOG.warn(errorMsg, e); } */ } /** * @see org.kuali.kfs.sys.document.AccountingDocument#getSourceAccountingLineClass() */ @Override public Class getSourceAccountingLineClass() { //NOTE: do not do anything with this method as it is used by routing etc! return super.getSourceAccountingLineClass(); } public String getRequisitionOrganizationReference1Text() { return requisitionOrganizationReference1Text; } public void setRequisitionOrganizationReference1Text(String requisitionOrganizationReference1Text) { this.requisitionOrganizationReference1Text = requisitionOrganizationReference1Text; } public String getRequisitionOrganizationReference2Text() { return requisitionOrganizationReference2Text; } public void setRequisitionOrganizationReference2Text(String requisitionOrganizationReference2Text) { this.requisitionOrganizationReference2Text = requisitionOrganizationReference2Text; } public String getRequisitionOrganizationReference3Text() { return requisitionOrganizationReference3Text; } public void setRequisitionOrganizationReference3Text(String requisitionOrganizationReference3Text) { this.requisitionOrganizationReference3Text = requisitionOrganizationReference3Text; } public String getAlternate1VendorName() { return alternate1VendorName; } public void setAlternate1VendorName(String alternate1VendorName) { this.alternate1VendorName = alternate1VendorName; } public String getAlternate2VendorName() { return alternate2VendorName; } public void setAlternate2VendorName(String alternate2VendorName) { this.alternate2VendorName = alternate2VendorName; } public String getAlternate3VendorName() { return alternate3VendorName; } public void setAlternate3VendorName(String alternate3VendorName) { this.alternate3VendorName = alternate3VendorName; } public String getAlternate4VendorName() { return alternate4VendorName; } public void setAlternate4VendorName(String alternate4VendorName) { this.alternate4VendorName = alternate4VendorName; } public String getAlternate5VendorName() { return alternate5VendorName; } public void setAlternate5VendorName(String alternate5VendorName) { this.alternate5VendorName = alternate5VendorName; } public KualiDecimal getOrganizationAutomaticPurchaseOrderLimit() { return organizationAutomaticPurchaseOrderLimit; } public void setOrganizationAutomaticPurchaseOrderLimit(KualiDecimal organizationAutomaticPurchaseOrderLimit) { this.organizationAutomaticPurchaseOrderLimit = organizationAutomaticPurchaseOrderLimit; } /** * @see org.kuali.kfs.module.purap.document.PurchasingAccountsPayableDocumentBase#getItemClass() */ @Override public Class getItemClass() { return RequisitionItem.class; } @Override public Class getItemUseTaxClass() { return PurchaseRequisitionItemUseTax.class; } /** * Returns null as requistion has no source document. * * @see org.kuali.kfs.module.purap.document.PurchasingAccountsPayableDocumentBase#getPurApSourceDocumentIfPossible() */ @Override public PurchasingAccountsPayableDocument getPurApSourceDocumentIfPossible() { return null; } /** * Returns null as requistion has no source document. * * @see org.kuali.kfs.module.purap.document.PurchasingAccountsPayableDocumentBase#getPurApSourceDocumentLabelIfPossible() */ @Override public String getPurApSourceDocumentLabelIfPossible() { return null; } /** * @see org.kuali.rice.kns.document.Document#getDocumentTitle() */ @Override public String getDocumentTitle() { String title = ""; if (SpringContext.getBean(ParameterService.class).getParameterValueAsBoolean(RequisitionDocument.class, PurapParameterConstants.PURAP_OVERRIDE_REQ_DOC_TITLE)) { String docIdStr = ""; if ((this.getPurapDocumentIdentifier() != null) && (StringUtils.isNotBlank(this.getPurapDocumentIdentifier().toString()))) { docIdStr = "Requisition: " + this.getPurapDocumentIdentifier().toString(); } String chartAcct = this.getFirstChartAccount(); String chartAcctStr = (chartAcct == null ? "" : " - Account Number: " + chartAcct); title = docIdStr + chartAcctStr; } else { title = super.getDocumentTitle(); } return title; } /** * Gets this requisition's Chart/Account of the first accounting line from the first item. * * @return The first Chart and Account, or an empty string if there is none. */ protected String getFirstChartAccount() { String chartAcct = null; RequisitionItem item = (RequisitionItem) this.getItem(0); if (ObjectUtils.isNotNull(item)) { if (item.getSourceAccountingLines().size() > 0) { PurApAccountingLine accountLine = item.getSourceAccountingLine(0); if (ObjectUtils.isNotNull(accountLine) && ObjectUtils.isNotNull(accountLine.getChartOfAccountsCode()) && ObjectUtils.isNotNull(accountLine.getAccountNumber())) { chartAcct = accountLine.getChartOfAccountsCode() + "-" + accountLine.getAccountNumber(); } } } return chartAcct; } public Date getCreateDate() { return this.getFinancialSystemDocumentHeader().getWorkflowDocument().getDateCreated().toDate(); } public String getUrl() { return SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(KFSConstants.WORKFLOW_URL_KEY) + "/DocHandler.do?docId=" + getDocumentNumber() + "&command=displayDocSearchView"; } /** * This is a "do nothing" version of the method - it just won't create GLPEs * @see org.kuali.kfs.sys.document.AccountingDocumentBase#generateGeneralLedgerPendingEntries(org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper) */ @Override public boolean generateGeneralLedgerPendingEntries(GeneralLedgerPendingEntrySourceDetail glpeSourceDetail, GeneralLedgerPendingEntrySequenceHelper sequenceHelper) { return true; } @Override public Class getPurchasingCapitalAssetItemClass() { return RequisitionCapitalAssetItem.class; } @Override public Class getPurchasingCapitalAssetSystemClass() { return RequisitionCapitalAssetSystem.class; } @Override public boolean shouldGiveErrorForEmptyAccountsProration() { //to be removed //for app doc status //remove isDocumentStoppedInRouteNode(NodeDetailEnum.CONTENT_REVIEW) kfsmi - 4592 if (isDocumentStoppedInRouteNode(RequisitionStatuses.NODE_CONTENT_REVIEW) || getApplicationDocumentStatus().equals(PurapConstants.RequisitionStatuses.APPDOC_IN_PROCESS)) { return false; } return true; } public Date getCreateDateForResult() { Formatter formatter = new DateViewDateObjectFormatter(); return (Date)formatter.format(this.getFinancialSystemDocumentHeader().getWorkflowDocument().getDateCreated().toDate()); } /** * Gets the isBlanketApproveRequest attribute. * @return Returns the isBlanketApproveRequest. */ public boolean isBlanketApproveRequest() { return isBlanketApproveRequest; } /** * Sets the isBlanketApproveRequest attribute value. * @param isBlanketApproveRequest The isBlanketApproveRequest to set. */ public void setBlanketApproveRequest(boolean isBlanketApproveRequest) { this.isBlanketApproveRequest = isBlanketApproveRequest; } /** * retrieves the system parameter value for account distribution method and determines * if the drop-down box on the form should be read only or not. Sets the default * value for account distribution method property on the document. */ public void setupAccountDistributionMethod() { String defaultDistributionMethod = SpringContext.getBean(ParameterService.class).getParameterValueAsString(PurapConstants.PURAP_NAMESPACE, "Document", PurapParameterConstants.DISTRIBUTION_METHOD_FOR_ACCOUNTING_LINES); String defaultDistributionMethodCode = PurapConstants.AccountDistributionMethodCodes.PROPORTIONAL_CODE; if (PurapConstants.AccountDistributionMethodCodes.PROPORTIONAL_CODE.equalsIgnoreCase(defaultDistributionMethod) || PurapConstants.AccountDistributionMethodCodes.SEQUENTIAL_CODE.equalsIgnoreCase(defaultDistributionMethod)) { defaultDistributionMethodCode = defaultDistributionMethod; } else { if (PurapConstants.AccountDistributionMethodCodes.BOTH_WITH_DEFAULT_PROPORTIONAL_CODE.equalsIgnoreCase(defaultDistributionMethod)) { defaultDistributionMethodCode = PurapConstants.AccountDistributionMethodCodes.PROPORTIONAL_CODE; } else if (PurapConstants.AccountDistributionMethodCodes.BOTH_WITH_DEFAULT_SEQUENTIAL_CODE.equalsIgnoreCase(defaultDistributionMethod)){ defaultDistributionMethodCode = PurapConstants.AccountDistributionMethodCodes.SEQUENTIAL_CODE; } else { new RuntimeException("Error in reading system parameter values for DISTRIBUTION_METHOD_FOR_ACCOUNTING_LINES"); } } setAccountDistributionMethod(defaultDistributionMethodCode); } }