View Javadoc
1   /**
2    * Copyright 2005-2014 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.rice.krad.document;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
20  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
21  import org.kuali.rice.kew.api.KewApiServiceLocator;
22  import org.kuali.rice.kew.api.WorkflowDocument;
23  import org.kuali.rice.kew.api.WorkflowDocumentFactory;
24  import org.kuali.rice.kew.api.action.ActionRequest;
25  import org.kuali.rice.kew.api.action.ActionRequestType;
26  import org.kuali.rice.kew.api.action.ActionType;
27  import org.kuali.rice.kew.api.document.DocumentStatus;
28  import org.kuali.rice.krad.util.GlobalVariables;
29  import org.kuali.rice.krad.util.KRADConstants;
30  
31  import java.io.Serializable;
32  import java.util.ArrayList;
33  import java.util.List;
34  
35  /**
36   * @author Kuali Rice Team (rice.collab@kuali.org)
37   */
38  public class DocumentPresentationControllerBase implements DocumentPresentationController, Serializable {
39      private static final long serialVersionUID = -9181864754090276024L;
40  
41      private static transient ParameterService parameterService;
42  
43      public boolean canInitiate(String documentTypeName) {
44          return true;
45      }
46  
47      public boolean canEdit(Document document) {
48          boolean canEdit = false;
49          WorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument();
50          if (workflowDocument.isInitiated()
51                  || workflowDocument.isSaved()
52                  || workflowDocument.isEnroute()
53                  || workflowDocument.isException()) {
54              canEdit = true;
55          }
56  
57          return canEdit;
58      }
59  
60      public boolean canAnnotate(Document document) {
61          return true;
62      }
63  
64      public boolean canReload(Document document) {
65          WorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument();
66          return (canEdit(document) && !workflowDocument.isInitiated());
67  
68      }
69  
70      public boolean canClose(Document document) {
71          return true;
72      }
73  
74      public boolean canSave(Document document) {
75          return canEdit(document);
76      }
77  
78      public boolean canRoute(Document document) {
79          boolean canRoute = false;
80          WorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument();
81          if (workflowDocument.isInitiated() || workflowDocument.isSaved()) {
82              canRoute = true;
83          }
84          return canRoute;
85      }
86  
87      public boolean canCancel(Document document) {
88          WorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument();
89          return workflowDocument.isValidAction(ActionType.CANCEL);
90      }
91  
92      public boolean canRecall(Document document) {
93          // Enroute - the most liberal approximation of recallability
94          // DocumentAuthorizer will perform finer-grained authorization
95          return document.getDocumentHeader().getWorkflowDocument().isEnroute();
96      }
97  
98      public boolean canCopy(Document document) {
99          boolean canCopy = false;
100         if (document.getAllowsCopy()) {
101             canCopy = true;
102         }
103         return canCopy;
104     }
105 
106     @Override
107     public boolean canPerformRouteReport(Document document) {
108         return getParameterService().getParameterValueAsBoolean(KRADConstants.KNS_NAMESPACE,
109                 KRADConstants.DetailTypes.DOCUMENT_DETAIL_TYPE,
110                 KRADConstants.SystemGroupParameterNames.DEFAULT_CAN_PERFORM_ROUTE_REPORT_IND);
111     }
112 
113     public boolean canAddAdhocRequests(Document document) {
114         return true;
115     }
116 
117     public boolean canBlanketApprove(Document document) {
118         // check system parameter - if Y, use default workflow behavior: allow a user with the permission
119         // to perform the blanket approve action at any time
120         Boolean allowBlanketApproveNoRequest = getParameterService().getParameterValueAsBoolean(
121                 KRADConstants.KNS_NAMESPACE, KRADConstants.DetailTypes.DOCUMENT_DETAIL_TYPE,
122                 KRADConstants.SystemGroupParameterNames.ALLOW_ENROUTE_BLANKET_APPROVE_WITHOUT_APPROVAL_REQUEST_IND);
123         if (allowBlanketApproveNoRequest != null && allowBlanketApproveNoRequest.booleanValue()) {
124             return canEdit(document);
125         }
126 
127         // otherwise, limit the display of the blanket approve button to only the initiator of the document
128         // (prior to routing)
129         WorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument();
130         if (canRoute(document) && StringUtils.equals(workflowDocument.getInitiatorPrincipalId(),
131                 GlobalVariables.getUserSession().getPrincipalId())) {
132             return true;
133         }
134 
135         // or to a user with an approval action request
136         if (workflowDocument.isApprovalRequested()) {
137             return true;
138         }
139 
140         return false;
141     }
142 
143     public boolean canApprove(Document document) {
144         return !canComplete(document);
145     }
146 
147     public boolean canDisapprove(Document document) {
148         // most of the time, a person who can approve can disapprove
149         return canApprove(document);
150     }
151 
152     public boolean canSendAdhocRequests(Document document) {
153         WorkflowDocument kualiWorkflowDocument = document.getDocumentHeader().getWorkflowDocument();
154         return !(kualiWorkflowDocument.isInitiated() || kualiWorkflowDocument.isSaved());
155     }
156 
157     public boolean canSendNoteFyi(Document document) {
158         return true;
159     }
160 
161     public boolean canEditDocumentOverview(Document document) {
162         WorkflowDocument kualiWorkflowDocument = document.getDocumentHeader().getWorkflowDocument();
163         return (kualiWorkflowDocument.isInitiated() || kualiWorkflowDocument.isSaved());
164     }
165 
166     public boolean canFyi(Document document) {
167         return true;
168     }
169 
170     public boolean canAcknowledge(Document document) {
171         return true;
172     }
173 
174     public boolean canComplete(Document document) {
175         boolean docInInit = document.getDocumentHeader().getWorkflowDocument().isInitiated() || document.getDocumentHeader().getWorkflowDocument().isSaved();
176         boolean completionRequested = document.getDocumentHeader().getWorkflowDocument().isCompletionRequested();
177         if (completionRequested && !docInInit) {
178             return true;
179         }
180         return false;
181     }
182 
183     /**
184      * {@inheritDoc}
185      */
186     @Override
187     public boolean canSuperUserTakeAction(Document document) {
188         return hasActionRequests(document) && canTakeAction(document);
189     }
190 
191     /**
192      * {@inheritDoc}
193      */
194     @Override
195     public boolean canSuperUserApprove(Document document) {
196         return canApproveOrDisapprove(document);
197     }
198 
199     /**
200      * {@inheritDoc}
201      */
202     @Override
203     public boolean canSuperUserDisapprove(Document document) {
204         return canApproveOrDisapprove(document);
205     }
206 
207     /**
208      * Returns whether the {@code document} has any APPROVE or COMPLETE action requests.
209      *
210      * @param document the document to check
211      *
212      * @return true if the {@code document} has any APPROVE or COMPLETE action requests, false otherwise
213      */
214     protected boolean hasActionRequests(Document document) {
215         boolean hasActionRequests = false;
216 
217         for (ActionRequest actionRequest : document.getActionRequests()) {
218             if  (StringUtils.equals(actionRequest.getActionRequested().getCode(), ActionRequestType.APPROVE.getCode())
219                     || StringUtils.equals(actionRequest.getActionRequested().getCode(), ActionRequestType.COMPLETE.getCode())) {
220                 hasActionRequests = true;
221                 break;
222             }
223         }
224 
225         return hasActionRequests;
226     }
227 
228     /**
229      * Returns whether a super user action can be taken on the {@code document}.
230      *
231      * <p>
232      * Typically, actions can only be taken on a document not in INITIATED, FINAL, or CANCELLED status.
233      * </p>
234      *
235      * @param document the document to check
236      *
237      * @return true if a super user action can be taken on the {@code document}, false otherwise
238      */
239     protected boolean canTakeAction(Document document) {
240         String documentNumber = document.getDocumentNumber();
241         DocumentStatus status = KewApiServiceLocator.getWorkflowDocumentService().getDocumentStatus(documentNumber);
242 
243         return !isStateInitiatedFinalCancelled(status);
244     }
245 
246     /**
247      * Returns whether a super user approve or disapprove action can be taken on the {@code document}.
248      *
249      * <p>
250      * Typically, actions can only be taken on a document not in INITIATED, SAVED, PROCESSED, DISAPPROVED, FINAL, or
251      * CANCELLED status.
252      * </p>
253      *
254      * @param document the document to check
255      *
256      * @return true if a super user approve or disapprove action can be taken on the {@code document}, false otherwise
257      */
258     protected boolean canApproveOrDisapprove(Document document) {
259         String documentNumber = document.getDocumentNumber();
260         DocumentStatus status = KewApiServiceLocator.getWorkflowDocumentService().getDocumentStatus(documentNumber);
261 
262         return !isStateInitiatedFinalCancelled(status) && !isStateSaved(status) && !isStateProcessedOrDisapproved(status);
263     }
264 
265     /**
266      * Returns whether the {@code document} is in a INITIATED, FINAL, or CANCELLED state.
267      *
268      * @param status the document status
269      *
270      * @return true if the {@code document} is in a INITIATED, FINAL, or CANCELLED state, false otherwise
271      */
272     protected boolean isStateInitiatedFinalCancelled(DocumentStatus status) {
273         return (StringUtils.equals(status.getCode(), DocumentStatus.INITIATED.getCode()) ||
274                 StringUtils.equals(status.getCode(), DocumentStatus.FINAL.getCode()) ||
275                 StringUtils.equals(status.getCode(), DocumentStatus.CANCELED.getCode()));
276     }
277 
278     /**
279      * Returns whether the {@code document} is in a SAVED state.
280      *
281      * @param status the document status
282      *
283      * @return true if the {@code document} is in a SAVED state, false otherwise
284      */
285     protected boolean isStateSaved(DocumentStatus status) {
286         return (StringUtils.equals(status.getCode(), DocumentStatus.SAVED.getCode()));
287     }
288 
289     /**
290      * Returns whether the {@code document} is in a PROCESSED or DISAPPROVED state.
291      *
292      * @param status the document status
293      *
294      * @return true if the {@code document} is in a PROCESSED or DISAPPROVED state, false otherwise
295      */
296     protected boolean isStateProcessedOrDisapproved(DocumentStatus status) {
297         return (StringUtils.equals(status.getCode(), DocumentStatus.PROCESSED.getCode()) ||
298                 StringUtils.equals(status.getCode(), DocumentStatus.DISAPPROVED.getCode()));
299     }
300 
301     protected ParameterService getParameterService() {
302         if (parameterService == null) {
303             parameterService = CoreFrameworkServiceLocator.getParameterService();
304         }
305         return parameterService;
306     }
307 }