001/* 002 * Copyright 2008-2009 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.ole.module.purap.document.authorization; 017 018import org.apache.commons.lang.StringUtils; 019import org.kuali.ole.module.purap.PurapAuthorizationConstants.PaymentRequestEditMode; 020import org.kuali.ole.module.purap.PurapConstants; 021import org.kuali.ole.module.purap.PurapConstants.PaymentRequestStatuses; 022import org.kuali.ole.module.purap.PurapConstants.PurchaseOrderStatuses; 023import org.kuali.ole.module.purap.PurapParameterConstants; 024import org.kuali.ole.module.purap.businessobject.PaymentRequestItem; 025import org.kuali.ole.module.purap.document.PaymentRequestDocument; 026import org.kuali.ole.module.purap.document.service.PurapService; 027import org.kuali.ole.sys.OLEConstants; 028import org.kuali.ole.sys.OleAuthorizationConstants; 029import org.kuali.ole.sys.context.SpringContext; 030import org.kuali.ole.sys.service.FinancialSystemWorkflowHelperService; 031import org.kuali.ole.sys.service.impl.OleParameterConstants; 032import org.kuali.rice.coreservice.framework.parameter.ParameterService; 033import org.kuali.rice.krad.document.Document; 034import org.kuali.rice.krad.util.GlobalVariables; 035import org.kuali.rice.krad.util.ObjectUtils; 036 037import java.util.ArrayList; 038import java.util.Iterator; 039import java.util.List; 040import java.util.Set; 041 042 043public class PaymentRequestDocumentPresentationController extends PurchasingAccountsPayableDocumentPresentationController { 044 045 Boolean canHold; 046 Boolean canRequestCancel; 047 Boolean canEditPreExtraction; 048 049 @Override 050 public boolean canSave(Document document) { 051 PaymentRequestDocument paymentRequestDocument = (PaymentRequestDocument) document; 052 053 if (StringUtils.equals(paymentRequestDocument.getApplicationDocumentStatus(), PaymentRequestStatuses.APPDOC_INITIATE)) { 054 return false; 055 } 056 057 if (canEditPreExtraction(paymentRequestDocument)) { 058 return true; 059 } 060 061 return super.canSave(document); 062 } 063 064 @Override 065 public boolean canReload(Document document) { 066 PaymentRequestDocument paymentRequestDocument = (PaymentRequestDocument) document; 067 068 if (StringUtils.equals(paymentRequestDocument.getApplicationDocumentStatus(), PaymentRequestStatuses.APPDOC_INITIATE)) { 069 return false; 070 } 071 072 if (canEditPreExtraction(paymentRequestDocument)) { 073 return true; 074 } 075 076 return super.canReload(document); 077 } 078 079 @Override 080 public boolean canCancel(Document document) { 081 //controlling the cancel button through getExtraButtons in PaymentRequestForm 082 return false; 083 } 084 085 @Override 086 public boolean canApprove(Document document) { 087 PaymentRequestDocument paymentRequestDocument = (PaymentRequestDocument) document; 088 089 if (paymentRequestDocument.isPaymentRequestedCancelIndicator() || paymentRequestDocument.isHoldIndicator()) { 090 return false; 091 } 092 093 return super.canApprove(document); 094 } 095 096 @Override 097 public boolean canDisapprove(Document document) { 098 //disapprove is never allowed for PREQ 099 return false; 100 } 101 102 /** 103 * @see org.kuali.rice.kns.document.authorization.DocumentPresentationControllerBase#canEdit(org.kuali.rice.kns.document.Document) 104 */ 105 @Override 106 public boolean canEdit(Document document) { 107 PaymentRequestDocument paymentRequestDocument = (PaymentRequestDocument) document; 108 boolean fullDocEntryCompleted = SpringContext.getBean(PurapService.class).isFullDocumentEntryCompleted(paymentRequestDocument); 109 110 // if the hold or cancel indicator is true, don't allow editing 111 if (paymentRequestDocument.isHoldIndicator() || paymentRequestDocument.isPaymentRequestedCancelIndicator()) { 112 return false; 113 } 114 if (fullDocEntryCompleted) { 115 // after fullDocEntry is completed, only fiscal officer reviewers can edit 116 if (paymentRequestDocument.isDocumentStoppedInRouteNode(PaymentRequestStatuses.NODE_ACCOUNT_REVIEW)) { 117 return true; 118 } 119 return false; 120 } else { 121 //before fullDocEntry is completed, document can be edited (could be preroute or enroute) 122 return true; 123 } 124 } 125 126 /** 127 * @see org.kuali.rice.kns.document.authorization.TransactionalDocumentPresentationControllerBase#getEditModes(org.kuali.rice.kns.document.Document) 128 */ 129 @Override 130 public Set<String> getEditModes(Document document) { 131 Set<String> editModes = super.getEditModes(document); 132 133 PaymentRequestDocument paymentRequestDocument = (PaymentRequestDocument) document; 134 135 if (canProcessorCancel(paymentRequestDocument)) { 136 editModes.add(PaymentRequestEditMode.ACCOUNTS_PAYABLE_PROCESSOR_CANCEL); 137 } 138 139 if (canManagerCancel(paymentRequestDocument)) { 140 editModes.add(PaymentRequestEditMode.ACCOUNTS_PAYABLE_MANAGER_CANCEL); 141 } 142 143 if (canHold(paymentRequestDocument)) { 144 editModes.add(PaymentRequestEditMode.HOLD); 145 } 146 147 if (canRequestCancel(paymentRequestDocument)) { 148 editModes.add(PaymentRequestEditMode.REQUEST_CANCEL); 149 } 150 151 if (canRemoveHold(paymentRequestDocument)) { 152 editModes.add(PaymentRequestEditMode.REMOVE_HOLD); 153 } 154 155 if (canRemoveRequestCancel(paymentRequestDocument)) { 156 editModes.add(PaymentRequestEditMode.REMOVE_REQUEST_CANCEL); 157 } 158 159 if (canProcessorInit(paymentRequestDocument)) { 160 editModes.add(PaymentRequestEditMode.DISPLAY_INIT_TAB); 161 } 162 163 if (ObjectUtils.isNotNull(paymentRequestDocument.getVendorHeaderGeneratedIdentifier())) { 164 editModes.add(PaymentRequestEditMode.LOCK_VENDOR_ENTRY); 165 } 166 167 if (SpringContext.getBean(PurapService.class).isFullDocumentEntryCompleted(paymentRequestDocument)) { 168 editModes.add(PaymentRequestEditMode.FULL_DOCUMENT_ENTRY_COMPLETED); 169 } else if (ObjectUtils.isNotNull(paymentRequestDocument.getPurchaseOrderDocument()) && PurapConstants.PurchaseOrderStatuses.APPDOC_OPEN.equals(paymentRequestDocument.getPurchaseOrderDocument().getApplicationDocumentStatus())) { 170 /* 171 String documentTypeName = OLEConstants.FinancialDocumentTypeCodes.PAYMENT_REQUEST; 172 String nameSpaceCode = OLEConstants.CoreModuleNamespaces.SELECT; 173 174 AttributeSet permissionDetails = new AttributeSet(); 175 permissionDetails.put(KimAttributes.DOCUMENT_TYPE_NAME,documentTypeName); 176 177 boolean canClosePO = KIMServiceLocator.getIdentityManagementService().hasPermission(GlobalVariables.getUserSession().getPerson().getPrincipalId(), nameSpaceCode, 178 OLEConstants.OlePaymentRequest.CAN_CLOSE_PO, permissionDetails); 179 if(canClosePO) { 180 editModes.add(PaymentRequestEditMode.ALLOW_CLOSE_PURCHASE_ORDER); 181 }*/ 182 editModes.add(PaymentRequestEditMode.ALLOW_CLOSE_PURCHASE_ORDER); 183 } 184 185 //FIXME hjs: alter to restrict what AP shouldn't be allowed to edit 186 if (canEditPreExtraction(paymentRequestDocument)) { 187 editModes.add(PaymentRequestEditMode.EDIT_PRE_EXTRACT); 188 } 189 190 // See if purap tax is enabled 191 boolean salesTaxInd = SpringContext.getBean(ParameterService.class).getParameterValueAsBoolean(OleParameterConstants.PURCHASING_DOCUMENT.class, PurapParameterConstants.ENABLE_SALES_TAX_IND); 192 if (salesTaxInd) { 193 editModes.add(PaymentRequestEditMode.PURAP_TAX_ENABLED); 194 195 if (paymentRequestDocument.isUseTaxIndicator()) { 196 // if use tax, don't allow editing of tax fields 197 editModes.add(PaymentRequestEditMode.LOCK_TAX_AMOUNT_ENTRY); 198 } else { 199 // display the "clear all taxes" button if doc is not using use tax 200 editModes.add(PaymentRequestEditMode.CLEAR_ALL_TAXES); 201 202 } 203 } 204 205 // tax area tab is editable while waiting for tax review 206 if (paymentRequestDocument.isDocumentStoppedInRouteNode(PaymentRequestStatuses.NODE_VENDOR_TAX_REVIEW)) { 207 editModes.add(PaymentRequestEditMode.TAX_AREA_EDITABLE); 208 } 209 210 if (PurchaseOrderStatuses.APPDOC_AWAIT_TAX_REVIEW 211 .equals(paymentRequestDocument.getApplicationDocumentStatus())) { 212 editModes.add(PaymentRequestEditMode.TAX_AREA_EDITABLE); 213 } 214 215 216 // the tax tab is viewable to everyone after tax is approved 217 if (PaymentRequestStatuses.APPDOC_DEPARTMENT_APPROVED.equals(paymentRequestDocument.getApplicationDocumentStatus()) && 218 // if and only if the preq has gone through tax review would TaxClassificationCode be non-empty 219 !StringUtils.isEmpty(paymentRequestDocument.getTaxClassificationCode())) { 220 editModes.add(PaymentRequestEditMode.TAX_INFO_VIEWABLE); 221 } 222 223 if (paymentRequestDocument.isDocumentStoppedInRouteNode(PaymentRequestStatuses.NODE_ACCOUNT_REVIEW)) { 224 // remove FULL_ENTRY because FO cannot edit rest of doc; only their own acct lines 225 editModes.add(PaymentRequestEditMode.RESTRICT_FISCAL_ENTRY); 226 227 // only do line item check if the hold/cancel indicator is false, otherwise document editing should be turned off. 228 if (!paymentRequestDocument.isHoldIndicator() && !paymentRequestDocument.isPaymentRequestedCancelIndicator()) { 229 List lineList = new ArrayList(); 230 for (Iterator iter = paymentRequestDocument.getItems().iterator(); iter.hasNext(); ) { 231 PaymentRequestItem item = (PaymentRequestItem) iter.next(); 232 lineList.addAll(item.getSourceAccountingLines()); 233 // If FO has deleted the last accounting line for an item, set entry mode to full so they can add another one 234 if (item.getItemType().isLineItemIndicator() && item.getSourceAccountingLines().size() == 0) { 235 editModes.add(OleAuthorizationConstants.TransactionalEditMode.EXPENSE_ENTRY); 236 } 237 } 238 } 239 } 240 241 // Remove editBank edit mode if the document has been extracted 242 if (paymentRequestDocument.isExtracted()) { 243 editModes.remove(OLEConstants.BANK_ENTRY_EDITABLE_EDITING_MODE); 244 } 245 246 return editModes; 247 } 248 249 protected boolean canProcessorInit(PaymentRequestDocument paymentRequestDocument) { 250 // if Payment Request is in INITIATE status or NULL returned from getAppDocStatus 251 String status = paymentRequestDocument.getApplicationDocumentStatus(); 252 if (StringUtils.equals(status, PaymentRequestStatuses.APPDOC_INITIATE)) { 253 return true; 254 } 255 return false; 256 } 257 258 259 protected boolean canProcessorCancel(PaymentRequestDocument paymentRequestDocument) { 260 // if Payment Request is in INITIATE status, user cannot cancel doc 261 if (canProcessorInit(paymentRequestDocument)) { 262 return false; 263 } 264 265 String docStatus = paymentRequestDocument.getApplicationDocumentStatus(); 266 boolean requestCancelIndicator = paymentRequestDocument.getPaymentRequestedCancelIndicator(); 267 boolean holdIndicator = paymentRequestDocument.isHoldIndicator(); 268 boolean extracted = paymentRequestDocument.isExtracted(); 269 270 boolean preroute = 271 PaymentRequestStatuses.APPDOC_IN_PROCESS.equals(docStatus) || 272 PaymentRequestStatuses.APPDOC_AWAITING_ACCOUNTS_PAYABLE_REVIEW.equals(docStatus); 273 boolean enroute = 274 PaymentRequestStatuses.APPDOC_AWAITING_SUB_ACCT_MGR_REVIEW.equals(docStatus) || 275 PaymentRequestStatuses.APPDOC_AWAITING_FISCAL_REVIEW.equals(docStatus) || 276 PaymentRequestStatuses.APPDOC_AWAITING_ORG_REVIEW.equals(docStatus) || 277 PaymentRequestStatuses.APPDOC_AWAITING_PAYMENT_REVIEW.equals(docStatus) 278 || 279 PaymentRequestStatuses.APPDOC_AWAITING_TAX_REVIEW.equals(docStatus); 280 boolean postroute = 281 PaymentRequestStatuses.APPDOC_DEPARTMENT_APPROVED.equals(docStatus) || 282 PaymentRequestStatuses.APPDOC_AUTO_APPROVED.equals(docStatus); 283 284 boolean can = false; 285 if (PaymentRequestStatuses.STATUSES_PREROUTE.contains(docStatus)) { 286 can = true; 287 } else if (PaymentRequestStatuses.STATUSES_ENROUTE.contains(docStatus)) { 288 can = requestCancelIndicator; 289 } else if (PaymentRequestStatuses.STATUSES_POSTROUTE.contains(docStatus)) { 290 can = !requestCancelIndicator && !holdIndicator && !extracted; 291 } 292 293 return can; 294 } 295 296 protected boolean canManagerCancel(PaymentRequestDocument paymentRequestDocument) { 297 // if Payment Request is in INITIATE status, user cannot cancel doc 298 if (canProcessorInit(paymentRequestDocument)) { 299 return false; 300 } 301 302 String docStatus = paymentRequestDocument.getApplicationDocumentStatus(); 303 boolean requestCancelIndicator = paymentRequestDocument.getPaymentRequestedCancelIndicator(); 304 boolean holdIndicator = paymentRequestDocument.isHoldIndicator(); 305 boolean extracted = paymentRequestDocument.isExtracted(); 306 307 boolean preroute = 308 PaymentRequestStatuses.APPDOC_IN_PROCESS.equals(docStatus) || 309 PaymentRequestStatuses.APPDOC_AWAITING_ACCOUNTS_PAYABLE_REVIEW.equals(docStatus); 310 boolean enroute = 311 PaymentRequestStatuses.APPDOC_AWAITING_SUB_ACCT_MGR_REVIEW.equals(docStatus) || 312 PaymentRequestStatuses.APPDOC_AWAITING_FISCAL_REVIEW.equals(docStatus) || 313 PaymentRequestStatuses.APPDOC_AWAITING_ORG_REVIEW.equals(docStatus) || 314 PaymentRequestStatuses.APPDOC_AWAITING_PAYMENT_REVIEW.equals(docStatus) 315 || 316 PaymentRequestStatuses.APPDOC_AWAITING_TAX_REVIEW.equals(docStatus); 317 boolean postroute = 318 PaymentRequestStatuses.APPDOC_DEPARTMENT_APPROVED.equals(docStatus) || 319 PaymentRequestStatuses.APPDOC_AUTO_APPROVED.equals(docStatus); 320 321 boolean can = false; 322 if (PaymentRequestStatuses.STATUSES_PREROUTE.contains(docStatus) || 323 PaymentRequestStatuses.STATUSES_ENROUTE.contains(docStatus)) { 324 can = true; 325 } else if (PaymentRequestStatuses.STATUSES_POSTROUTE.contains(docStatus)) { 326 can = !requestCancelIndicator && !holdIndicator && !extracted; 327 } 328 329 return can; 330 } 331 332 /** 333 * Determines whether the PaymentRequest Hold button shall be available. Conditions: 334 * - Payment Request is not already on hold, and 335 * - Payment Request is not already being requested to be canceled, and 336 * - Payment Request has not already been extracted to PDP, and 337 * - Payment Request status is not in the list of "STATUSES_DISALLOWING_HOLD" or document is being adhoc routed; and 338 * 339 * @return True if the document state allows placing the Payment Request on hold. 340 */ 341 protected boolean canHold(PaymentRequestDocument paymentRequestDocument) { 342 if (canHold == null) { 343 344 boolean can = !paymentRequestDocument.isHoldIndicator() 345 && !paymentRequestDocument.isPaymentRequestedCancelIndicator() 346 && !paymentRequestDocument.isExtracted(); 347 if (can) { 348 can = SpringContext.getBean(FinancialSystemWorkflowHelperService.class) 349 .isAdhocApprovalRequestedForPrincipal( 350 paymentRequestDocument.getFinancialSystemDocumentHeader().getWorkflowDocument(), 351 GlobalVariables.getUserSession().getPrincipalId()); 352 can = can 353 || !PaymentRequestStatuses.STATUSES_DISALLOWING_HOLD.contains(paymentRequestDocument 354 .getApplicationDocumentStatus()); 355 } 356 canHold = can; 357 } 358 359 return canHold; 360 } 361 362 /** 363 * Determines whether the Request Cancel PaymentRequest button shall be available. Conditions: 364 * - Payment Request is not already on hold, and 365 * - Payment Request is not already being requested to be canceled, and 366 * - Payment Request has not already been extracted to PDP, and 367 * - Payment Request status is not in the list of "STATUSES_DISALLOWING_REQUEST_CANCEL" or document is being adhoc routed; and 368 * 369 * @return True if the document state allows placing the request that the Payment Request be canceled. 370 */ 371 protected boolean canRequestCancel(PaymentRequestDocument paymentRequestDocument) { 372 if (canRequestCancel == null) { 373 boolean can = !paymentRequestDocument.isPaymentRequestedCancelIndicator() 374 && !paymentRequestDocument.isHoldIndicator() && !paymentRequestDocument.isExtracted(); 375 if (can) { 376 can = SpringContext.getBean(FinancialSystemWorkflowHelperService.class) 377 .isAdhocApprovalRequestedForPrincipal( 378 paymentRequestDocument.getFinancialSystemDocumentHeader().getWorkflowDocument(), 379 GlobalVariables.getUserSession().getPrincipalId()); 380 can = can 381 || !PaymentRequestStatuses.STATUSES_DISALLOWING_REQUEST_CANCEL.contains(paymentRequestDocument 382 .getApplicationDocumentStatus()); 383 } 384 canRequestCancel = can; 385 } 386 return canRequestCancel; 387 } 388 389 /** 390 * Determines whether the Remove Hold button shall be available. Conditions: 391 * - the hold indicator is set to true 392 * <p/> 393 * Because the state of the Payment Request cannot be changed while the document is on hold, 394 * we should not have to check the state of the document to remove the hold. 395 * For example, the document should not be allowed to be approved or extracted while on hold. 396 * 397 * @return True if the document state allows removing the Payment Request from hold. 398 */ 399 protected boolean canRemoveHold(PaymentRequestDocument paymentRequestDocument) { 400 return paymentRequestDocument.isHoldIndicator(); 401 } 402 403 /** 404 * Determines whether the Remove Request Cancel button shall be available. Conditions: 405 * - the request cancel indicator is set to true; and 406 * <p/> 407 * Because the state of the Payment Request cannot be changed while the document is set to request cancel, 408 * we should not have to check the state of the document to remove the request cancel. 409 * For example, the document should not be allowed to be approved or extracted while set to request cancel. 410 * 411 * @return True if the document state allows removing a request that the Payment Request be canceled. 412 */ 413 protected boolean canRemoveRequestCancel(PaymentRequestDocument paymentRequestDocument) { 414 return paymentRequestDocument.isPaymentRequestedCancelIndicator(); 415 } 416 417 protected boolean canEditPreExtraction(PaymentRequestDocument paymentRequestDocument) { 418 if (canEditPreExtraction == null) { 419 boolean can = (!paymentRequestDocument.isExtracted() 420 && !SpringContext.getBean(FinancialSystemWorkflowHelperService.class) 421 .isAdhocApprovalRequestedForPrincipal( 422 paymentRequestDocument.getFinancialSystemDocumentHeader().getWorkflowDocument(), 423 GlobalVariables.getUserSession().getPrincipalId()) && !PurapConstants.PaymentRequestStatuses.CANCELLED_STATUSES 424 .contains(paymentRequestDocument.getApplicationDocumentStatus())); 425 canEditPreExtraction = can; 426 } 427 return canEditPreExtraction; 428 } 429 430}