View Javadoc
1   /*
2    * Copyright 2008-2009 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.module.purap.document.authorization;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.ole.module.purap.PurapAuthorizationConstants.PaymentRequestEditMode;
20  import org.kuali.ole.module.purap.PurapConstants;
21  import org.kuali.ole.module.purap.PurapConstants.PaymentRequestStatuses;
22  import org.kuali.ole.module.purap.PurapConstants.PurchaseOrderStatuses;
23  import org.kuali.ole.module.purap.PurapParameterConstants;
24  import org.kuali.ole.module.purap.businessobject.PaymentRequestItem;
25  import org.kuali.ole.module.purap.document.PaymentRequestDocument;
26  import org.kuali.ole.module.purap.document.service.PurapService;
27  import org.kuali.ole.sys.OLEConstants;
28  import org.kuali.ole.sys.OleAuthorizationConstants;
29  import org.kuali.ole.sys.context.SpringContext;
30  import org.kuali.ole.sys.service.FinancialSystemWorkflowHelperService;
31  import org.kuali.ole.sys.service.impl.OleParameterConstants;
32  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
33  import org.kuali.rice.krad.document.Document;
34  import org.kuali.rice.krad.util.GlobalVariables;
35  import org.kuali.rice.krad.util.ObjectUtils;
36  
37  import java.util.ArrayList;
38  import java.util.Iterator;
39  import java.util.List;
40  import java.util.Set;
41  
42  
43  public class PaymentRequestDocumentPresentationController extends PurchasingAccountsPayableDocumentPresentationController {
44  
45      Boolean canHold;
46      Boolean canRequestCancel;
47      Boolean canEditPreExtraction;
48  
49      @Override
50      public boolean canSave(Document document) {
51          PaymentRequestDocument paymentRequestDocument = (PaymentRequestDocument) document;
52  
53          if (StringUtils.equals(paymentRequestDocument.getApplicationDocumentStatus(), PaymentRequestStatuses.APPDOC_INITIATE)) {
54              return false;
55          }
56  
57          if (canEditPreExtraction(paymentRequestDocument)) {
58              return true;
59          }
60  
61          return super.canSave(document);
62      }
63  
64      @Override
65      public boolean canReload(Document document) {
66          PaymentRequestDocument paymentRequestDocument = (PaymentRequestDocument) document;
67  
68          if (StringUtils.equals(paymentRequestDocument.getApplicationDocumentStatus(), PaymentRequestStatuses.APPDOC_INITIATE)) {
69              return false;
70          }
71  
72          if (canEditPreExtraction(paymentRequestDocument)) {
73              return true;
74          }
75  
76          return super.canReload(document);
77      }
78  
79      @Override
80      public boolean canCancel(Document document) {
81          //controlling the cancel button through getExtraButtons in PaymentRequestForm
82          return false;
83      }
84  
85      @Override
86      public boolean canApprove(Document document) {
87          PaymentRequestDocument paymentRequestDocument = (PaymentRequestDocument) document;
88  
89          if (paymentRequestDocument.isPaymentRequestedCancelIndicator() || paymentRequestDocument.isHoldIndicator()) {
90              return false;
91          }
92  
93          return super.canApprove(document);
94      }
95  
96      @Override
97      public boolean canDisapprove(Document document) {
98          //disapprove is never allowed for PREQ
99          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 }