001 /* 002 * Copyright 2011 The Kuali Foundation. 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.kfs.module.purap.document.authorization; 017 018 import java.util.List; 019 import java.util.Set; 020 021 import org.apache.commons.lang.StringUtils; 022 import org.kuali.kfs.module.purap.PurapAuthorizationConstants; 023 import org.kuali.kfs.module.purap.PurapConstants; 024 import org.kuali.kfs.module.purap.PurapParameterConstants; 025 import org.kuali.kfs.module.purap.PurapWorkflowConstants; 026 import org.kuali.kfs.module.purap.PurapAuthorizationConstants.PurchaseOrderEditMode; 027 import org.kuali.kfs.module.purap.PurapConstants.PurchaseOrderStatuses; 028 import org.kuali.kfs.module.purap.PurapConstants.RequisitionSources; 029 import org.kuali.kfs.module.purap.document.PurchaseOrderDocument; 030 import org.kuali.kfs.module.purap.document.service.PurapService; 031 import org.kuali.kfs.sys.context.SpringContext; 032 import org.kuali.kfs.sys.service.impl.KfsParameterConstants; 033 import org.kuali.rice.kns.document.Document; 034 import org.kuali.rice.kns.service.ParameterService; 035 import org.kuali.rice.kns.util.ObjectUtils; 036 import org.kuali.rice.kns.workflow.service.KualiWorkflowDocument; 037 038 039 public class PurchaseOrderDocumentPresentationController extends PurchasingAccountsPayableDocumentPresentationController { 040 041 @Override 042 protected boolean canEdit(Document document) { 043 PurchaseOrderDocument poDocument = (PurchaseOrderDocument)document; 044 045 if (!PurchaseOrderStatuses.IN_PROCESS.equals(poDocument.getStatusCode()) && 046 !PurchaseOrderStatuses.WAITING_FOR_DEPARTMENT.equals(poDocument.getStatusCode()) && 047 !PurchaseOrderStatuses.WAITING_FOR_VENDOR.equals(poDocument.getStatusCode()) && 048 !PurchaseOrderStatuses.QUOTE.equals(poDocument.getStatusCode()) && 049 !PurchaseOrderStatuses.AWAIT_PURCHASING_REVIEW.equals(poDocument.getStatusCode()) && 050 !PurchaseOrderStatuses.AWAIT_NEW_UNORDERED_ITEM_REVIEW.equals(poDocument.getStatusCode()) && 051 !PurchaseOrderStatuses.CHANGE_IN_PROCESS.equals(poDocument.getStatusCode())) { 052 return false; 053 } 054 return super.canEdit(document); 055 } 056 057 @Override 058 protected boolean canFyi(Document document) { 059 PurchaseOrderDocument poDocument = (PurchaseOrderDocument) document; 060 if (PurchaseOrderStatuses.PENDING_PRINT.equals(poDocument.getStatusCode())) { 061 return false; 062 } 063 return super.canFyi(document); 064 } 065 066 @Override 067 protected boolean canCancel(Document document) { 068 PurchaseOrderDocument poDocument = (PurchaseOrderDocument)document; 069 070 if (poDocument.isPendingSplit() || poDocument.getAssigningSensitiveData()) { 071 return false; 072 } 073 074 return super.canCancel(document); 075 } 076 077 @Override 078 protected boolean canClose(Document document) { 079 PurchaseOrderDocument poDocument = (PurchaseOrderDocument)document; 080 081 if (poDocument.isPendingSplit() || poDocument.getAssigningSensitiveData()) { 082 return false; 083 } 084 085 return super.canClose(document); 086 } 087 088 @Override 089 protected boolean canReload(Document document) { 090 PurchaseOrderDocument poDocument = (PurchaseOrderDocument)document; 091 092 if (poDocument.isPendingSplit() || poDocument.getAssigningSensitiveData()) { 093 return false; 094 } 095 096 return super.canReload(document); 097 } 098 099 @Override 100 protected boolean canSave(Document document) { 101 PurchaseOrderDocument poDocument = (PurchaseOrderDocument)document; 102 103 if (poDocument.isPendingSplit() || poDocument.getAssigningSensitiveData()) { 104 return false; 105 } 106 107 return super.canSave(document); 108 } 109 110 @Override 111 protected boolean canRoute(Document document) { 112 PurchaseOrderDocument poDocument = (PurchaseOrderDocument)document; 113 String statusCode = poDocument.getStatusCode(); 114 115 if (StringUtils.equals(statusCode, PurchaseOrderStatuses.WAITING_FOR_DEPARTMENT) || 116 StringUtils.equals(statusCode, PurchaseOrderStatuses.WAITING_FOR_VENDOR) || 117 StringUtils.equals(statusCode, PurchaseOrderStatuses.QUOTE)) { 118 return false; 119 } 120 121 if (poDocument.isPendingSplit()) { 122 return false; 123 } 124 125 return super.canRoute(document); 126 } 127 128 @Override 129 public Set<String> getEditModes(Document document) { 130 Set<String> editModes = super.getEditModes(document); 131 KualiWorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument(); 132 PurchaseOrderDocument poDocument = (PurchaseOrderDocument)document; 133 String statusCode = poDocument.getStatusCode(); 134 135 editModes.add(PurchaseOrderEditMode.ASSIGN_SENSITIVE_DATA); 136 137 //if the ENABLE_COMMODITY_CODE_IND system parameter is Y then add this edit mode so that the commodity code fields would display on the document. 138 boolean enableCommodityCode = SpringContext.getBean(ParameterService.class).getIndicatorParameter(KfsParameterConstants.PURCHASING_DOCUMENT.class, PurapParameterConstants.ENABLE_COMMODITY_CODE_IND); 139 if (enableCommodityCode) { 140 editModes.add(PurchaseOrderEditMode.ENABLE_COMMODITY_CODE); 141 } 142 143 if (canFirstTransmitPrintPo(poDocument)) { 144 editModes.add(PurchaseOrderEditMode.PRINT_PURCHASE_ORDER); 145 } 146 147 if (canPreviewPrintPo(poDocument)) { 148 editModes.add(PurchaseOrderEditMode.PREVIEW_PRINT_PURCHASE_ORDER); 149 } 150 151 if (canResendCxml(poDocument)) { 152 editModes.add(PurchaseOrderEditMode.RESEND_PURCHASE_ORDER); 153 } 154 155 // if vendor has been selected from DB, certain vendor fields are not allowed to be edited 156 if (ObjectUtils.isNotNull(poDocument.getVendorHeaderGeneratedIdentifier())) { 157 editModes.add(PurchaseOrderEditMode.LOCK_VENDOR_ENTRY); 158 } 159 160 // if B2B purchase order, certain fields are not allowed to be edited 161 if (RequisitionSources.B2B.equals(poDocument.getRequisitionSourceCode())) { 162 editModes.add(PurchaseOrderEditMode.LOCK_B2B_ENTRY); 163 } 164 165 // if not B2B requisition, users can edit the posting year if within a given amount of time set in a parameter 166 if (!RequisitionSources.B2B.equals(poDocument.getRequisitionSourceCode()) && 167 SpringContext.getBean(PurapService.class).allowEncumberNextFiscalYear() && 168 (PurchaseOrderStatuses.IN_PROCESS.equals(statusCode) || 169 PurchaseOrderStatuses.WAITING_FOR_VENDOR.equals(statusCode) || 170 PurchaseOrderStatuses.WAITING_FOR_DEPARTMENT.equals(statusCode) || 171 PurchaseOrderStatuses.QUOTE.equals(statusCode) || 172 PurchaseOrderStatuses.AWAIT_PURCHASING_REVIEW.equals(statusCode))) { 173 editModes.add(PurchaseOrderEditMode.ALLOW_POSTING_YEAR_ENTRY); 174 } 175 176 // check if purap tax is enabled 177 boolean salesTaxInd = SpringContext.getBean(ParameterService.class).getIndicatorParameter(KfsParameterConstants.PURCHASING_DOCUMENT.class, PurapParameterConstants.ENABLE_SALES_TAX_IND); 178 if (salesTaxInd) { 179 editModes.add(PurapAuthorizationConstants.PURAP_TAX_ENABLED); 180 181 if (poDocument.isUseTaxIndicator()) { 182 // if use tax, don't allow editing of tax fields 183 editModes.add(PurchaseOrderEditMode.LOCK_TAX_AMOUNT_ENTRY); 184 } 185 else { 186 // display the "clear all taxes" button if doc is not using use tax 187 editModes.add(PurchaseOrderEditMode.CLEAR_ALL_TAXES); 188 } 189 } 190 191 // set display mode for Receiving Address section according to parameter value 192 boolean displayReceivingAddress = SpringContext.getBean(ParameterService.class).getIndicatorParameter(KfsParameterConstants.PURCHASING_DOCUMENT.class, PurapParameterConstants.ENABLE_RECEIVING_ADDRESS_IND); 193 if (displayReceivingAddress) { 194 editModes.add(PurchaseOrderEditMode.DISPLAY_RECEIVING_ADDRESS); 195 } 196 197 // PRE_ROUTE_CHANGEABLE mode is used for fields that are editable only before PO is routed 198 // for ex, contract manager, manual status change, and quote etc 199 //if (workflowDocument.stateIsInitiated() || workflowDocument.stateIsSaved()) { 200 if (PurchaseOrderStatuses.IN_PROCESS.equals(statusCode) || 201 PurchaseOrderStatuses.WAITING_FOR_VENDOR.equals(statusCode) || 202 PurchaseOrderStatuses.WAITING_FOR_DEPARTMENT.equals(statusCode) || 203 PurchaseOrderStatuses.QUOTE.equals(statusCode)) { 204 editModes.add(PurchaseOrderEditMode.PRE_ROUTE_CHANGEABLE); 205 } 206 207 // INTERNAL PURCHASING ROUTE LEVEL - Approvers can edit full detail on Purchase Order except they cannot change the CHART/ORG. 208 if (poDocument.isDocumentStoppedInRouteNode(PurapWorkflowConstants.PurchaseOrderDocument.NodeDetailEnum.INTERNAL_PURCHASING_REVIEW)) { 209 editModes.add(PurchaseOrderEditMode.LOCK_INTERNAL_PURCHASING_ENTRY); 210 } 211 212 //FIXME figure out how to get this to work 213 // /** 214 // * CONTRACTS & GRANTS ROUTE LEVEL, BUDGET OFFICE ROUTE LEVEL, VENDOR TAX ROUTE LEVEL, DOCUMENT TRANSMISSION ROUTE LEVEL, 215 // * and Adhoc - Approvers in these route levels cannot edit any detail on PO. 216 // */ 217 // else { 218 // // VIEW_ENTRY that is already being set is sufficient, but need to remove FULL_ENTRY 219 // editModeMap.remove(AuthorizationConstants.EditMode.FULL_ENTRY); 220 // } 221 222 // Set display mode for Split PO. 223 if (poDocument.isPendingSplit()) { 224 editModes.add(PurchaseOrderEditMode.SPLITTING_ITEM_SELECTION); 225 } 226 227 return editModes; 228 } 229 230 /** 231 * Determines whether to display the button to print the pdf for the first time transmit. 232 * Conditions: PO status is Pending Print or the transmission method is changed to PRINT during the amendment. 233 * 234 * @return boolean true if the print first transmit button can be displayed. 235 */ 236 protected boolean canFirstTransmitPrintPo(PurchaseOrderDocument poDocument) { 237 // status shall be Pending Print, or the transmission method is changed to PRINT during amendment, 238 boolean can = PurchaseOrderStatuses.PENDING_PRINT.equals(poDocument.getStatusCode()); 239 if (!can) { 240 can = PurchaseOrderStatuses.OPEN.equals(poDocument.getStatusCode()); 241 can = can && poDocument.getDocumentHeader().getWorkflowDocument().stateIsFinal(); 242 can = can && poDocument.getPurchaseOrderLastTransmitTimestamp() == null; 243 can = can && PurapConstants.POTransmissionMethods.PRINT.equals(poDocument.getPurchaseOrderTransmissionMethodCode()); 244 } 245 246 return can; 247 } 248 249 /** 250 * Determines whether to display the print preview button for the first time transmit. Conditions are: 251 * available while the document is saved or enroute; 252 * available for only a certain number of PO transmission types which are stored in a parameter (default to PRIN and FAX) 253 * 254 * @return boolean true if the preview print button can be displayed. 255 */ 256 protected boolean canPreviewPrintPo(PurchaseOrderDocument poDocument) { 257 // PO is saved or enroute 258 boolean can = poDocument.getDocumentHeader().getWorkflowDocument().stateIsSaved() || poDocument.getDocumentHeader().getWorkflowDocument().stateIsEnroute(); 259 260 // transmission method must be one of those specified by the parameter 261 if (can) { 262 List<String> methods = SpringContext.getBean(ParameterService.class).getParameterValues(PurchaseOrderDocument.class, PurapParameterConstants.PURAP_PO_PRINT_PREVIEW_TRANSMISSION_METHOD_TYPES); 263 String method = poDocument.getPurchaseOrderTransmissionMethodCode(); 264 can = (methods == null || methods.contains(method)); 265 } 266 267 return can; 268 } 269 270 /** 271 * Determines whether to display the resend po button for the purchase order document. 272 * Conditions: PO status must be error sending cxml and must be current and not pending. 273 * 274 * @return boolean true if the resend po button shall be displayed. 275 */ 276 protected boolean canResendCxml(PurchaseOrderDocument poDocument) { 277 // check PO status etc 278 boolean can = PurchaseOrderStatuses.CXML_ERROR.equals(poDocument.getStatusCode()); 279 can = can && poDocument.isPurchaseOrderCurrentIndicator() && !poDocument.isPendingActionIndicator(); 280 281 return can; 282 } 283 284 }