/* * 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.web.struts; import java.math.BigDecimal; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang.StringUtils; import org.kuali.kfs.integration.purap.CapitalAssetLocation; import org.kuali.kfs.module.purap.PurapAuthorizationConstants; import org.kuali.kfs.module.purap.PurapConstants; import org.kuali.kfs.module.purap.PurapConstants.PaymentRequestStatuses; import org.kuali.kfs.module.purap.PurapConstants.PurchaseOrderStatuses; import org.kuali.kfs.module.purap.PurapPropertyConstants; import org.kuali.kfs.module.purap.businessobject.PaymentRequestView; import org.kuali.kfs.module.purap.businessobject.PurApGenericAttributes; import org.kuali.kfs.module.purap.businessobject.PurApItem; import org.kuali.kfs.module.purap.businessobject.PurchaseOrderAccount; import org.kuali.kfs.module.purap.businessobject.PurchaseOrderCapitalAssetLocation; import org.kuali.kfs.module.purap.businessobject.PurchaseOrderItem; import org.kuali.kfs.module.purap.businessobject.PurchaseOrderItemCapitalAsset; import org.kuali.kfs.module.purap.businessobject.PurchaseOrderVendorQuote; import org.kuali.kfs.module.purap.businessobject.PurchaseOrderVendorStipulation; import org.kuali.kfs.module.purap.businessobject.RequisitionCapitalAssetLocation; import org.kuali.kfs.module.purap.businessobject.SensitiveData; import org.kuali.kfs.module.purap.businessobject.SensitiveDataAssignment; import org.kuali.kfs.module.purap.document.PurchaseOrderAmendmentDocument; import org.kuali.kfs.module.purap.document.PurchaseOrderDocument; import org.kuali.kfs.module.purap.document.PurchaseOrderSplitDocument; import org.kuali.kfs.module.purap.document.service.PaymentRequestService; import org.kuali.kfs.module.purap.document.service.PurchaseOrderService; import org.kuali.kfs.module.purap.document.service.ReceivingService; import org.kuali.kfs.module.purap.util.PurApItemUtils; import org.kuali.kfs.sys.KFSConstants; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.rice.core.api.datetime.DateTimeService; import org.kuali.rice.kew.api.WorkflowDocument; import org.kuali.rice.kew.api.document.DocumentStatusCategory; import org.kuali.rice.kim.api.KimConstants; import org.kuali.rice.kim.api.services.IdentityManagementService; import org.kuali.rice.kns.document.authorization.DocumentAuthorizer; import org.kuali.rice.kns.service.DataDictionaryService; import org.kuali.rice.kns.service.DocumentHelperService; import org.kuali.rice.kns.web.ui.ExtraButton; import org.kuali.rice.kns.web.ui.HeaderField; import org.kuali.rice.krad.util.GlobalVariables; import org.kuali.rice.krad.util.KRADConstants; import org.kuali.rice.krad.util.ObjectUtils; /** * Struts Action Form for Purchase Order document. */ public class PurchaseOrderForm extends PurchasingFormBase { protected PurchaseOrderVendorStipulation newPurchaseOrderVendorStipulationLine; protected PurchaseOrderVendorQuote newPurchaseOrderVendorQuote; protected Long awardedVendorNumber; // Retransmit. protected String[] retransmitItemsSelected = {}; protected String retransmitTransmissionMethod; protected String retransmitFaxNumber; protected String retransmitHeader; // Need this for amendment for accounting line only protected Map accountingLineEditingMode; protected String splitNoteText; // Assign Sensitive Data related fields protected String sensitiveDataAssignmentReason = null; // reason for current assignment of sensitive data to the PO protected SensitiveDataAssignment lastSensitiveDataAssignment = null; // last sensitive data assignment info for the PO protected SensitiveData newSensitiveDataLine = null; // new sensitive data entry to be added to the PO protected List<SensitiveData> sensitiveDatasAssigned = null; // sensitive data entries currently assigned to the PO protected final String PURCHASING_PROCESSOR_ROLE_NAME = "Purchasing Processor"; /** * Constructs a PurchaseOrderForm instance and sets up the appropriately casted document. */ public PurchaseOrderForm() { super(); setNewPurchaseOrderVendorStipulationLine(new PurchaseOrderVendorStipulation()); setNewPurchaseOrderVendorQuote(new PurchaseOrderVendorQuote()); this.accountingLineEditingMode = new HashMap(); //on PO, account distribution should be read only setReadOnlyAccountDistributionMethod(true); } @Override protected String getDefaultDocumentTypeName() { return "PO"; } public Map getAccountingLineEditingMode() { return accountingLineEditingMode; } public void setAccountingLineEditingMode(Map accountingLineEditingMode) { this.accountingLineEditingMode = accountingLineEditingMode; } public Long getAwardedVendorNumber() { return awardedVendorNumber; } public void setAwardedVendorNumber(Long awardedVendorNumber) { this.awardedVendorNumber = awardedVendorNumber; } public PurchaseOrderVendorStipulation getNewPurchaseOrderVendorStipulationLine() { return newPurchaseOrderVendorStipulationLine; } public void setNewPurchaseOrderVendorStipulationLine(PurchaseOrderVendorStipulation newPurchaseOrderVendorStipulationLine) { this.newPurchaseOrderVendorStipulationLine = newPurchaseOrderVendorStipulationLine; } public PurchaseOrderVendorQuote getNewPurchaseOrderVendorQuote() { return newPurchaseOrderVendorQuote; } public void setNewPurchaseOrderVendorQuote(PurchaseOrderVendorQuote newPurchaseOrderVendorQuote) { this.newPurchaseOrderVendorQuote = newPurchaseOrderVendorQuote; } public String[] getRetransmitItemsSelected() { return retransmitItemsSelected; } public void setRetransmitItemsSelected(String[] retransmitItemsSelected) { this.retransmitItemsSelected = retransmitItemsSelected; } public PurchaseOrderDocument getPurchaseOrderDocument() { return (PurchaseOrderDocument) getDocument(); } public void setPurchaseOrderDocument(PurchaseOrderDocument purchaseOrderDocument) { setDocument(purchaseOrderDocument); } public String getSplitNoteText() { return splitNoteText; } public void setSplitNoteText(String splitNoteText) { this.splitNoteText = splitNoteText; } public String getSensitiveDataAssignmentReason() { return sensitiveDataAssignmentReason; } public void setSensitiveDataAssignmentReason(String sensitiveDataAssignmentReason) { this.sensitiveDataAssignmentReason = sensitiveDataAssignmentReason; } public SensitiveDataAssignment getLastSensitiveDataAssignment() { return lastSensitiveDataAssignment; } public void setLastSensitiveDataAssignment(SensitiveDataAssignment lastSensitiveDataAssignment) { this.lastSensitiveDataAssignment = lastSensitiveDataAssignment; } public SensitiveData getNewSensitiveDataLine() { return newSensitiveDataLine; } public void setNewSensitiveDataLine(SensitiveData newSensitiveDataLine) { this.newSensitiveDataLine = newSensitiveDataLine; } public List<SensitiveData> getSensitiveDatasAssigned() { return sensitiveDatasAssigned; } public void setSensitiveDatasAssigned(List<SensitiveData> poSensitiveData) { this.sensitiveDatasAssigned = poSensitiveData; } @Override public Class getCapitalAssetLocationClass() { return PurchaseOrderCapitalAssetLocation.class; } @Override public Class getItemCapitalAssetClass() { return PurchaseOrderItemCapitalAsset.class; } @Override public CapitalAssetLocation setupNewPurchasingCapitalAssetLocationLine() { CapitalAssetLocation location = new RequisitionCapitalAssetLocation(); return location; } /** * @see org.kuali.kfs.module.purap.document.web.struts.PurchasingFormBase#setupNewPurchasingItemLine() */ @Override public PurApItem setupNewPurchasingItemLine() { return new PurchaseOrderItem(); } /** * @see org.kuali.kfs.module.purap.document.web.struts.PurchasingFormBase#setupNewPurchasingAccountingLine() */ @Override public PurchaseOrderAccount setupNewPurchasingAccountingLine() { return new PurchaseOrderAccount(); } /** * @see org.kuali.kfs.module.purap.document.web.struts.PurchasingFormBase#setupNewAccountDistributionAccountingLine() */ @Override public PurchaseOrderAccount setupNewAccountDistributionAccountingLine() { PurchaseOrderAccount account = setupNewPurchasingAccountingLine(); account.setAccountLinePercent(new BigDecimal(100)); return account; } public boolean isReadOnlyReceivingRequired() { PurchaseOrderDocument poDoc = getPurchaseOrderDocument(); if (poDoc instanceof PurchaseOrderAmendmentDocument) { if (!poDoc.isReceivingDocumentRequiredIndicator()) { if (GlobalVariables.getMessageMap().hasNoErrors()) { // only check whether the PO has active payment requests if there is currently no error in the MessageMap, // otherwise // we're going to get WorkflowServiceErrorException("Document Search Validation Errors") in the // DocumentSearchService // when this next line execute return SpringContext.getBean(PaymentRequestService.class).hasActivePaymentRequestsForPurchaseOrder(poDoc.getPurapDocumentIdentifier()); } else { return true; } } } return false; } /** * Returns the new Purchase Order Vendor Stipulation Line and resets it. * * @return the new Purchase Order Vendor Stipulation Line. */ public PurchaseOrderVendorStipulation getAndResetNewPurchaseOrderVendorStipulationLine() { PurchaseOrderVendorStipulation aPurchaseOrderVendorStipulationLine = getNewPurchaseOrderVendorStipulationLine(); setNewPurchaseOrderVendorStipulationLine(new PurchaseOrderVendorStipulation()); aPurchaseOrderVendorStipulationLine.setDocumentNumber(getPurchaseOrderDocument().getDocumentNumber()); aPurchaseOrderVendorStipulationLine.setVendorStipulationAuthorEmployeeIdentifier(GlobalVariables.getUserSession().getPerson().getPrincipalId()); aPurchaseOrderVendorStipulationLine.setVendorStipulationCreateDate(SpringContext.getBean(DateTimeService.class).getCurrentSqlDate()); return aPurchaseOrderVendorStipulationLine; } public String getStatusChange() { if (StringUtils.isNotEmpty(getPurchaseOrderDocument().getStatusChange())){ return getPurchaseOrderDocument().getStatusChange(); } else { if (StringUtils.equals(getPurchaseOrderDocument().getApplicationDocumentStatus(),PurchaseOrderStatuses.APPDOC_IN_PROCESS)){ return PurchaseOrderStatuses.APPDOC_IN_PROCESS; } else if (StringUtils.equals(getPurchaseOrderDocument().getApplicationDocumentStatus(),PurchaseOrderStatuses.APPDOC_WAITING_FOR_DEPARTMENT)){ return PurchaseOrderStatuses.APPDOC_WAITING_FOR_DEPARTMENT; }else if (StringUtils.equals(getPurchaseOrderDocument().getApplicationDocumentStatus(),PurchaseOrderStatuses.APPDOC_WAITING_FOR_VENDOR)){ return PurchaseOrderStatuses.APPDOC_WAITING_FOR_VENDOR; }else{ return null; } } } public void setStatusChange(String statusChange) { getPurchaseOrderDocument().setStatusChange(statusChange); } /** * @see org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase#shouldMethodToCallParameterBeUsed(java.lang.String, java.lang.String, javax.servlet.http.HttpServletRequest) */ @Override public boolean shouldMethodToCallParameterBeUsed(String methodToCallParameterName, String methodToCallParameterValue, HttpServletRequest request) { List<String> methodToCallList = Arrays.asList(new String[]{"printPurchaseOrderPDFOnly", "printingRetransmitPoOnly", "printPoQuoteListOnly"}); if (KRADConstants.DISPATCH_REQUEST_PARAMETER.equals(methodToCallParameterName) && methodToCallList.contains(methodToCallParameterValue)) { return true; } return super.shouldMethodToCallParameterBeUsed(methodToCallParameterName, methodToCallParameterValue, request); } @Override public void populateHeaderFields(WorkflowDocument workflowDocument) { super.populateHeaderFields(workflowDocument); String poIDstr = getPurchaseOrderDocument().getPurapDocumentIdentifier().toString(); //KFSMI-4576 masking/unmasking PO number... //If the document status is not FINAL then check for permissions if (!workflowDocument.getStatus().getCategory().equals(DocumentStatusCategory.SUCCESSFUL)) { String principalId = GlobalVariables.getUserSession().getPerson().getPrincipalId(); String namespaceCode = KFSConstants.ParameterNamespaces.KNS; String permissionTemplateName = KimConstants.PermissionTemplateNames.FULL_UNMASK_FIELD; Map<String,String> roleQualifiers = new HashMap<String,String>(); Map<String,String> permissionDetails = new HashMap<String,String>(); permissionDetails.put(KimConstants.AttributeConstants.COMPONENT_NAME, PurchaseOrderDocument.class.getSimpleName()); permissionDetails.put(KimConstants.AttributeConstants.PROPERTY_NAME, PurapPropertyConstants.PURAP_DOC_ID); IdentityManagementService identityManagementService = SpringContext.getBean(IdentityManagementService.class); Boolean isAuthorized = identityManagementService.isAuthorizedByTemplateName(principalId, namespaceCode, permissionTemplateName, permissionDetails, roleQualifiers); //principalId is not authorized to see the PO number so mask the value. if (!isAuthorized) { DataDictionaryService dataDictionaryService = SpringContext.getBean(DataDictionaryService.class); if (ObjectUtils.isNotNull(getPurchaseOrderDocument().getPurapDocumentIdentifier())) { poIDstr = ""; int strLength = dataDictionaryService.getAttributeMaxLength(PurApGenericAttributes.class.getName(), PurapPropertyConstants.PURAP_DOC_ID); for (int i = 0; i < strLength; i++) { poIDstr = poIDstr.concat("*"); } } } } if (ObjectUtils.isNotNull(getPurchaseOrderDocument().getPurapDocumentIdentifier())) { getDocInfo().add(new HeaderField("DataDictionary.PurchaseOrderDocument.attributes.purapDocumentIdentifier", poIDstr)); } else { getDocInfo().add(new HeaderField("DataDictionary.PurchaseOrderDocument.attributes.purapDocumentIdentifier", PurapConstants.PURAP_APPLICATION_DOCUMENT_ID_NOT_AVAILABLE)); } if (ObjectUtils.isNotNull(getPurchaseOrderDocument().getApplicationDocumentStatus())) { getDocInfo().add(new HeaderField("DataDictionary.PurchaseOrderDocument.attributes.applicationDocumentStatus", getPurchaseOrderDocument().getApplicationDocumentStatus())); } else { getDocInfo().add(new HeaderField("DataDictionary.PurchaseOrderDocument.attributes.applicationDocumentStatus", PurapConstants.PURAP_APPLICATION_DOCUMENT_STATUS_NOT_AVAILABLE)); } } /** * @see org.kuali.kfs.sys.web.struts.KualiAccountingDocumentFormBase#populate(javax.servlet.http.HttpServletRequest) */ // @Override // public void populate(HttpServletRequest request) { // super.populate(request); // // PurchaseOrderDocument po = (PurchaseOrderDocument)getDocument(); // RICE20 : need to determine what to do about documentBusinessObject // if (ObjectUtils.isNotNull(po.getPurapDocumentIdentifier())) { // po.refreshDocumentBusinessObject(); // } // NoteService noteService = SpringContext.getBean(NoteService.class); // for (Note note : noteService.getByRemoteObjectId(po.getObjectId())) { // note.refreshReferenceObject("attachment"); // } // } /** * Processes validation rules having to do with any payment requests that the given purchase order may have. Specifically, * validates that at least one payment request exists, and makes further checks about the status of such payment requests. * * @param document A PurchaseOrderDocument * @return True if the document passes all the validations. */ protected boolean processPaymentRequestRulesForCanClose(PurchaseOrderDocument document) { boolean valid = false; Integer poDocId = document.getPurapDocumentIdentifier(); boolean checkInProcess = false; boolean hasInProcess = false; Map <String, String> processPaymentRequestResult = new HashMap<String, String>(); processPaymentRequestResult = SpringContext.getBean(PaymentRequestService.class).getPaymentRequestsByStatusAndPurchaseOrderId(PaymentRequestStatuses.APPDOC_IN_PROCESS, poDocId); if ("Y".equals(processPaymentRequestResult.get("hasInProcess"))) { hasInProcess = true; } if ("Y".equals(processPaymentRequestResult.get("checkInProcess"))) { checkInProcess = true; } if (checkInProcess && !hasInProcess) { valid = true; } return valid; } /** * Determines whether to display the amend button for the purchase order document. The document status must be open, and the * purchase order must be current and not pending, and the user must be in purchasing group. These are same as the conditions * for displaying the payment hold button. In addition to these conditions, we also have to check that there is no In Process * Payment Requests nor Credit Memos associated with the PO. * * @return boolean true if the amend button can be displayed. */ protected boolean canAmend() { boolean can = SpringContext.getBean(PurchaseOrderService.class).isPurchaseOrderOpenForProcessing(getPurchaseOrderDocument()); // check user authorization if (can) { DocumentAuthorizer documentAuthorizer = SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(getPurchaseOrderDocument()); can = documentAuthorizer.canInitiate(KFSConstants.FinancialDocumentTypeCodes.PURCHASE_ORDER_AMENDMENT, GlobalVariables.getUserSession().getPerson()); } return can; } /** * Determines whether to display the void button for the purchase order document. Conditions: * PO is in Pending Print status, or is in Open status and has no PREQs against it; * PO's current indicator is true and pending indicator is false; * and the user is a member of the purchasing group). * * @return boolean true if the void button can be displayed. */ protected boolean canVoid() { // check PO status etc boolean can = getPurchaseOrderDocument().isPurchaseOrderCurrentIndicator() && !getPurchaseOrderDocument().isPendingActionIndicator(); if (can) { boolean pendingPrint = PurchaseOrderStatuses.APPDOC_PENDING_PRINT.equals(getPurchaseOrderDocument().getApplicationDocumentStatus()); boolean open = PurchaseOrderStatuses.APPDOC_OPEN.equals(getPurchaseOrderDocument().getApplicationDocumentStatus()); boolean errorCxml = PurchaseOrderStatuses.APPDOC_CXML_ERROR.equals(getPurchaseOrderDocument().getApplicationDocumentStatus()); boolean errorFax = PurchaseOrderStatuses.APPDOC_FAX_ERROR.equals(getPurchaseOrderDocument().getApplicationDocumentStatus()); List<PaymentRequestView> preqViews = getPurchaseOrderDocument().getRelatedViews().getRelatedPaymentRequestViews(); boolean hasPaymentRequest = preqViews != null && preqViews.size() > 0; can = pendingPrint || (open && !hasPaymentRequest) || errorCxml || errorFax; } // check user authorization if (can) { DocumentAuthorizer documentAuthorizer = SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(getPurchaseOrderDocument()); can = documentAuthorizer.canInitiate(KFSConstants.FinancialDocumentTypeCodes.PURCHASE_ORDER_VOID, GlobalVariables.getUserSession().getPerson()); } return can; } /** * Determines whether to display the close order button to close the purchase order document. Conditions: * PO must be in Open status; must have at least one Payment Request in any status other than "In Process", * and the PO cannot have any Payment Requests in "In Process" status. * This button is available to all faculty/staff. * * @return boolean true if the close order button can be displayed. */ protected boolean canClose() { // check PO status etc boolean can = PurchaseOrderStatuses.APPDOC_OPEN.equals(getPurchaseOrderDocument().getApplicationDocumentStatus()); can = can && getPurchaseOrderDocument().isPurchaseOrderCurrentIndicator() && !getPurchaseOrderDocument().isPendingActionIndicator(); can = can && processPaymentRequestRulesForCanClose(getPurchaseOrderDocument()); // check user authorization if (can) { DocumentAuthorizer documentAuthorizer = SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(getPurchaseOrderDocument()); can = documentAuthorizer.canInitiate(KFSConstants.FinancialDocumentTypeCodes.PURCHASE_ORDER_CLOSE, GlobalVariables.getUserSession().getPerson()); } return can; } /** * Determines whether to display the open order button to reopen the purchase order document. * Conditions: PO status is close, PO is current and not pending, and the user is in purchasing group. * * @return boolean true if the reopen order button can be displayed. */ protected boolean canReopen() { // check PO status etc boolean can = PurchaseOrderStatuses.APPDOC_CLOSED.equals(getPurchaseOrderDocument().getApplicationDocumentStatus()); can = can && getPurchaseOrderDocument().isPurchaseOrderCurrentIndicator() && !getPurchaseOrderDocument().isPendingActionIndicator(); // check user authorization if (can) { DocumentAuthorizer documentAuthorizer = SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(getPurchaseOrderDocument()); can = documentAuthorizer.canInitiate(KFSConstants.FinancialDocumentTypeCodes.PURCHASE_ORDER_REOPEN, GlobalVariables.getUserSession().getPerson()); } return can; } /** * Determines whether to display the payment hold buttons for the purchase order document. * Conditions: PO status must be open, must be current and not pending, and the user must be in purchasing group. * * @return boolean true if the payment hold button can be displayed. */ protected boolean canHoldPayment() { // check PO status etc boolean can = PurchaseOrderStatuses.APPDOC_OPEN.equals(getPurchaseOrderDocument().getApplicationDocumentStatus()); can = can && getPurchaseOrderDocument().isPurchaseOrderCurrentIndicator() && !getPurchaseOrderDocument().isPendingActionIndicator(); // check user authorization if (can) { DocumentAuthorizer documentAuthorizer = SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(getPurchaseOrderDocument()); can = documentAuthorizer.canInitiate(KFSConstants.FinancialDocumentTypeCodes.PURCHASE_ORDER_PAYMENT_HOLD, GlobalVariables.getUserSession().getPerson()); } return can; } /** * Determines whether to display the remove hold button for the purchase order document. * Conditions are: PO status must be payment hold, must be current and not pending, and the user must be in purchasing group. * * @return boolean true if the remove hold button can be displayed. */ protected boolean canRemoveHold() { // check PO status etc boolean can = PurchaseOrderStatuses.APPDOC_PAYMENT_HOLD.equals(getPurchaseOrderDocument().getApplicationDocumentStatus()); can = can && getPurchaseOrderDocument().isPurchaseOrderCurrentIndicator() && !getPurchaseOrderDocument().isPendingActionIndicator(); // check user authorization if (can) { DocumentAuthorizer documentAuthorizer = SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(getPurchaseOrderDocument()); can = documentAuthorizer.canInitiate(KFSConstants.FinancialDocumentTypeCodes.PURCHASE_ORDER_REMOVE_HOLD, GlobalVariables.getUserSession().getPerson()); } return can; } /** * Determines whether to display the retransmit button. Conditions: * PO status must be open, and must be current and not pending, and the last transmit date must not be null. * If the purchase order is an Automated Purchase Order (APO) and does not have any sensitive data set to true, * then any users can see the retransmit button, otherwise, only users in the purchasing group can see it. * * @return boolean true if the retransmit button can be displayed. */ protected boolean canRetransmit() { // check PO status etc boolean can = PurchaseOrderStatuses.APPDOC_OPEN.equals(getPurchaseOrderDocument().getApplicationDocumentStatus()); can = can && getPurchaseOrderDocument().isPurchaseOrderCurrentIndicator() && !getPurchaseOrderDocument().isPendingActionIndicator(); can = can && getPurchaseOrderDocument().getPurchaseOrderLastTransmitTimestamp() != null; can = can && !PurapConstants.RequisitionSources.B2B.equals(getPurchaseOrderDocument().getRequisitionSourceCode()); can = can && !editingMode.containsKey(PurapAuthorizationConstants.PurchaseOrderEditMode.DISPLAY_RETRANSMIT_TAB); if (!can) { return false; } // check user authorization DocumentAuthorizer documentAuthorizer = SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(getPurchaseOrderDocument()); if (getPurchaseOrderDocument().getPurchaseOrderAutomaticIndicator()) { // for APO use authorization for PurchaseOrderRetransmitDocument, which is anybody can = documentAuthorizer.canInitiate(KFSConstants.FinancialDocumentTypeCodes.PURCHASE_ORDER_RETRANSMIT, GlobalVariables.getUserSession().getPerson()); } else { // for NON_APO use authorization for PurchaseOrderDocument, which is purchasing user can = (documentAuthorizer.canInitiate(KFSConstants.FinancialDocumentTypeCodes.PURCHASE_ORDER, GlobalVariables.getUserSession().getPerson()) || documentAuthorizer.canInitiate(KFSConstants.FinancialDocumentTypeCodes.CONTRACT_MANAGER_ASSIGNMENT, GlobalVariables.getUserSession().getPerson())); } return can; } /** * Determines whether to display the button to print the pdf on a retransmit document. * We're currently sharing the same button image as the button for creating a retransmit document but this may change someday. * This button should only appear on Retransmit Document. If it is an Automated Purchase Order (APO) * then any users can see this button, otherwise, only users in the purchasing group can see it. * * @return boolean true if the print retransmit button can be displayed. */ protected boolean canPrintRetransmit() { // check PO status etc boolean can = getPurchaseOrderDocument().getDocumentHeader().getWorkflowDocument().getDocumentTypeName().equals(PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_RETRANSMIT_DOCUMENT); can = can && editingMode.containsKey(PurapAuthorizationConstants.PurchaseOrderEditMode.DISPLAY_RETRANSMIT_TAB); if (can) { // check user authorization: same as retransmit init, since whoever can init retransmit PO shall be able to print DocumentAuthorizer documentAuthorizer = SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(getPurchaseOrderDocument()); if (getPurchaseOrderDocument().getPurchaseOrderAutomaticIndicator()) { // for APO use authorization for PurchaseOrderRetransmitDocument, which is anybody can = documentAuthorizer.canInitiate(KFSConstants.FinancialDocumentTypeCodes.PURCHASE_ORDER_RETRANSMIT, GlobalVariables.getUserSession().getPerson()); } else { // for NON_APO use authorization for PurchaseOrderDocument, which is purchasing user can = (documentAuthorizer.canInitiate(KFSConstants.FinancialDocumentTypeCodes.PURCHASE_ORDER, GlobalVariables.getUserSession().getPerson()) || documentAuthorizer.canInitiate(KFSConstants.FinancialDocumentTypeCodes.CONTRACT_MANAGER_ASSIGNMENT, GlobalVariables.getUserSession().getPerson())); } } return can; } /** * Determines if a Split PO Document can be created from this purchase order. Conditions: * The parent PO status is either "In Process" or "Awaiting Purchasing Review"; requisition source is not B2B; has at least 2 items, * and PO is not in the process of being split; user must be in purchasing group. * * @return boolean true if the split PO button can be displayed. */ protected boolean canSplitPo() { // PO must be in either "In Process" or "Awaiting Purchasing Review" boolean can = PurchaseOrderStatuses.APPDOC_IN_PROCESS.equals(getPurchaseOrderDocument().getApplicationDocumentStatus()); can = can && !getPurchaseOrderDocument().getDocumentHeader().getWorkflowDocument().isEnroute(); can = can || PurchaseOrderStatuses.APPDOC_AWAIT_PURCHASING_REVIEW.equals(getPurchaseOrderDocument().getApplicationDocumentStatus()); // can't split a SplitPO Document, according to new specs can = can && !(getPurchaseOrderDocument() instanceof PurchaseOrderSplitDocument); // can't initiate another split during the splitting process. can = can && !editingMode.containsKey(PurapAuthorizationConstants.PurchaseOrderEditMode.SPLITTING_ITEM_SELECTION); // Requisition Source must not be B2B. can = can && !getPurchaseOrderDocument().getRequisitionSourceCode().equals(PurapConstants.RequisitionSources.B2B); // PO must have more than one line item. if (can) { List<PurApItem> items = getPurchaseOrderDocument().getItems(); int itemsBelowTheLine = PurApItemUtils.countBelowTheLineItems(items); can = items.size() - itemsBelowTheLine > 1; } // check user authorization if (can) { DocumentAuthorizer documentAuthorizer = SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(getPurchaseOrderDocument()); can = documentAuthorizer.canInitiate(KFSConstants.FinancialDocumentTypeCodes.PURCHASE_ORDER_SPLIT, GlobalVariables.getUserSession().getPerson()); } return can; } /** * Determines whether the PO is in a status that signifies it has enough information to generate a Split PO. * * @return True if the PO can continue to be split. */ protected boolean canContinuePoSplit() { boolean can = editingMode.containsKey(PurapAuthorizationConstants.PurchaseOrderEditMode.SPLITTING_ITEM_SELECTION); // check user authorization if (can) { DocumentAuthorizer documentAuthorizer = SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(getPurchaseOrderDocument()); can = documentAuthorizer.canInitiate(KFSConstants.FinancialDocumentTypeCodes.PURCHASE_ORDER_SPLIT, GlobalVariables.getUserSession().getPerson()); } return can; } /** * Determines if a line item receiving document can be created for the purchase order. * * @return boolean true if the receiving document button can be displayed. */ protected boolean canCreateReceiving() { // check PO status and item info boolean can = SpringContext.getBean(ReceivingService.class).canCreateLineItemReceivingDocument(getPurchaseOrderDocument()); // check user authorization if (can) { DocumentAuthorizer documentAuthorizer = SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(getPurchaseOrderDocument()); can = documentAuthorizer.canInitiate(KFSConstants.FinancialDocumentTypeCodes.LINE_ITEM_RECEIVING, GlobalVariables.getUserSession().getPerson()); } return can; } /** * Creates a MAP for all the buttons to appear on the Purchase Order Form, and sets the attributes of these buttons. * * @return the button map created. */ protected Map<String, ExtraButton> createButtonsMap() { HashMap<String, ExtraButton> result = new HashMap<String, ExtraButton>(); // Retransmit button ExtraButton retransmitButton = new ExtraButton(); retransmitButton.setExtraButtonProperty("methodToCall.retransmitPo"); retransmitButton.setExtraButtonSource("${" + KFSConstants.EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_retransmit.gif"); retransmitButton.setExtraButtonAltText("Retransmit"); // Printing Retransmit button ExtraButton printingRetransmitButton = new ExtraButton(); printingRetransmitButton.setExtraButtonProperty("methodToCall.printingRetransmitPo"); printingRetransmitButton.setExtraButtonSource("${" + KFSConstants.EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_retransmit.gif"); printingRetransmitButton.setExtraButtonAltText("PrintingRetransmit"); // Printing Preview button ExtraButton printingPreviewButton = new ExtraButton(); printingPreviewButton.setExtraButtonProperty("methodToCall.printingPreviewPo"); printingPreviewButton.setExtraButtonSource("${" + KFSConstants.EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_previewpf.gif"); printingPreviewButton.setExtraButtonAltText("PrintingPreview"); // Print button ExtraButton printButton = new ExtraButton(); printButton.setExtraButtonProperty("methodToCall.firstTransmitPrintPo"); printButton.setExtraButtonSource("${" + KFSConstants.EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_print.gif"); printButton.setExtraButtonAltText("Print"); // Reopen PO button ExtraButton reopenButton = new ExtraButton(); reopenButton.setExtraButtonProperty("methodToCall.reopenPo"); reopenButton.setExtraButtonSource("${" + KFSConstants.EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_openorder.gif"); reopenButton.setExtraButtonAltText("Reopen"); // Close PO button ExtraButton closeButton = new ExtraButton(); closeButton.setExtraButtonProperty("methodToCall.closePo"); closeButton.setExtraButtonSource("${" + KFSConstants.EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_closeorder.gif"); closeButton.setExtraButtonAltText("Close PO"); // Void PO button ExtraButton voidButton = new ExtraButton(); voidButton.setExtraButtonProperty("methodToCall.voidPo"); voidButton.setExtraButtonSource("${" + KFSConstants.EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_voidorder.gif"); voidButton.setExtraButtonAltText("Void PO"); // Payment Hold PO button ExtraButton paymentHoldButton = new ExtraButton(); paymentHoldButton.setExtraButtonProperty("methodToCall.paymentHoldPo"); paymentHoldButton.setExtraButtonSource("${" + KFSConstants.EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_paymenthold.gif"); paymentHoldButton.setExtraButtonAltText("Payment Hold"); // Amend button ExtraButton amendButton = new ExtraButton(); amendButton.setExtraButtonProperty("methodToCall.amendPo"); amendButton.setExtraButtonSource("${" + KFSConstants.EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_amend.gif"); amendButton.setExtraButtonAltText("Amend"); // Remove Hold button ExtraButton removeHoldButton = new ExtraButton(); removeHoldButton.setExtraButtonProperty("methodToCall.removeHoldPo"); removeHoldButton.setExtraButtonSource("${" + KFSConstants.EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_removehold.gif"); removeHoldButton.setExtraButtonAltText("Remove Hold"); // Resend PO Cxml button ExtraButton resendPoCxmlButton = new ExtraButton(); resendPoCxmlButton.setExtraButtonProperty("methodToCall.resendPoCxml"); resendPoCxmlButton.setExtraButtonSource("${" + KFSConstants.EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_resendpo.gif"); resendPoCxmlButton.setExtraButtonAltText("Resend PO CXML"); // Receiving button ExtraButton receivingButton = new ExtraButton(); receivingButton.setExtraButtonProperty("methodToCall.createReceivingLine"); receivingButton.setExtraButtonSource("${" + KFSConstants.EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_receiving.gif"); receivingButton.setExtraButtonAltText("Receiving"); // Split PO button ExtraButton splitPoButton = new ExtraButton(); splitPoButton.setExtraButtonProperty("methodToCall.splitPo"); splitPoButton.setExtraButtonSource("${" + KFSConstants.EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_splitorder.gif"); splitPoButton.setExtraButtonAltText("Split this PO"); // Continue button ExtraButton continueButton = new ExtraButton(); continueButton.setExtraButtonProperty("methodToCall.continuePurchaseOrderSplit"); continueButton.setExtraButtonSource("${" + KFSConstants.RICE_EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_continue.gif"); continueButton.setExtraButtonAltText("Continue"); // Cancel Split button ExtraButton cancelSplitButton = new ExtraButton(); cancelSplitButton.setExtraButtonProperty("methodToCall.cancelPurchaseOrderSplit"); cancelSplitButton.setExtraButtonSource("${" + KFSConstants.EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_cancelsplit.gif"); cancelSplitButton.setExtraButtonAltText("Cancel Splitting the PO"); // Assign Sensitive Data button ExtraButton assignSensitiveDataButton = new ExtraButton(); assignSensitiveDataButton.setExtraButtonProperty("methodToCall.assignSensitiveData"); assignSensitiveDataButton.setExtraButtonSource("${" + KFSConstants.EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_sensitivedata.gif "); assignSensitiveDataButton.setExtraButtonAltText("Assign sensitive data to the PO"); // Submit Sensitive Data Assignment button ExtraButton submitSensitiveDataButton = new ExtraButton(); submitSensitiveDataButton.setExtraButtonProperty("methodToCall.submitSensitiveData"); submitSensitiveDataButton.setExtraButtonSource("${" + KFSConstants.RICE_EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_submit.gif"); submitSensitiveDataButton.setExtraButtonAltText("Submit sensitive data assignment"); // Cancel Sensitive Data Assignment button ExtraButton cancelSensitiveDataButton = new ExtraButton(); cancelSensitiveDataButton.setExtraButtonProperty("methodToCall.cancelSensitiveData"); cancelSensitiveDataButton.setExtraButtonSource("${" + KFSConstants.RICE_EXTERNALIZABLE_IMAGES_URL_KEY + "}buttonsmall_cancel.gif"); cancelSensitiveDataButton.setExtraButtonAltText("Cancel sensitive data assignment"); result.put(retransmitButton.getExtraButtonProperty(), retransmitButton); result.put(printingRetransmitButton.getExtraButtonProperty(), printingRetransmitButton); result.put(printingPreviewButton.getExtraButtonProperty(), printingPreviewButton); result.put(printButton.getExtraButtonProperty(), printButton); result.put(reopenButton.getExtraButtonProperty(), reopenButton); result.put(closeButton.getExtraButtonProperty(), closeButton); result.put(voidButton.getExtraButtonProperty(), voidButton); result.put(paymentHoldButton.getExtraButtonProperty(), paymentHoldButton); result.put(amendButton.getExtraButtonProperty(), amendButton); result.put(removeHoldButton.getExtraButtonProperty(), removeHoldButton); result.put(receivingButton.getExtraButtonProperty(), receivingButton); result.put(splitPoButton.getExtraButtonProperty(), splitPoButton); result.put(continueButton.getExtraButtonProperty(), continueButton); result.put(cancelSplitButton.getExtraButtonProperty(), cancelSplitButton); result.put(assignSensitiveDataButton.getExtraButtonProperty(), assignSensitiveDataButton); result.put(submitSensitiveDataButton.getExtraButtonProperty(), submitSensitiveDataButton); result.put(cancelSensitiveDataButton.getExtraButtonProperty(), cancelSensitiveDataButton); result.put(resendPoCxmlButton.getExtraButtonProperty(), resendPoCxmlButton); return result; } /** * Override the superclass method to add appropriate buttons for * PurchaseOrderDocument. * * @see org.kuali.rice.kns.web.struts.form.KualiForm#getExtraButtons() */ @Override public List<ExtraButton> getExtraButtons() { super.getExtraButtons(); Map buttonsMap = createButtonsMap(); if (getEditingMode().containsKey(PurapAuthorizationConstants.PurchaseOrderEditMode.ASSIGN_SENSITIVE_DATA)) { extraButtons.add((ExtraButton) buttonsMap.get("methodToCall.assignSensitiveData")); if (getPurchaseOrderDocument().getAssigningSensitiveData()) { // no other extra buttons except the following shall appear on "Assign Sensitive Data" page // and these buttons use the same permissions as the "Assign Sensitive Data" button extraButtons.clear(); extraButtons.add((ExtraButton) buttonsMap.get("methodToCall.submitSensitiveData")); extraButtons.add((ExtraButton) buttonsMap.get("methodToCall.cancelSensitiveData")); return extraButtons; } } if (getEditingMode().containsKey(PurapAuthorizationConstants.PurchaseOrderEditMode.PREVIEW_PRINT_PURCHASE_ORDER)) { extraButtons.add((ExtraButton) buttonsMap.get("methodToCall.printingPreviewPo")); } if (getEditingMode().containsKey(PurapAuthorizationConstants.PurchaseOrderEditMode.PRINT_PURCHASE_ORDER)) { extraButtons.add((ExtraButton) buttonsMap.get("methodToCall.firstTransmitPrintPo")); } if (getEditingMode().containsKey(PurapAuthorizationConstants.PurchaseOrderEditMode.RESEND_PURCHASE_ORDER)) { extraButtons.add((ExtraButton) buttonsMap.get("methodToCall.resendPoCxml")); } if (canRetransmit()) { extraButtons.add((ExtraButton) buttonsMap.get("methodToCall.retransmitPo")); } if (canPrintRetransmit()) { extraButtons.add((ExtraButton) buttonsMap.get("methodToCall.printingRetransmitPo")); } if (canReopen()) { extraButtons.add((ExtraButton) buttonsMap.get("methodToCall.reopenPo")); } if (canClose()) { extraButtons.add((ExtraButton) buttonsMap.get("methodToCall.closePo")); } if (canHoldPayment()) { extraButtons.add((ExtraButton) buttonsMap.get("methodToCall.paymentHoldPo")); } if (canAmend()) { extraButtons.add((ExtraButton) buttonsMap.get("methodToCall.amendPo")); } if (canVoid()) { extraButtons.add((ExtraButton) buttonsMap.get("methodToCall.voidPo")); } if (canRemoveHold()) { extraButtons.add((ExtraButton) buttonsMap.get("methodToCall.removeHoldPo")); } if (canCreateReceiving()) { extraButtons.add((ExtraButton) buttonsMap.get("methodToCall.createReceivingLine")); } if (canSplitPo()) { extraButtons.add((ExtraButton) buttonsMap.get("methodToCall.splitPo")); } if (canContinuePoSplit()) { extraButtons.clear(); extraButtons.add((ExtraButton) buttonsMap.get("methodToCall.continuePurchaseOrderSplit")); extraButtons.add((ExtraButton) buttonsMap.get("methodToCall.cancelPurchaseOrderSplit")); } return extraButtons; } }