1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.ole.module.purap.document.service.impl;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocument;
20 import org.kuali.ole.module.purap.document.service.PurApWorkflowIntegrationService;
21 import org.kuali.ole.sys.context.SpringContext;
22 import org.kuali.rice.kew.api.KewApiConstants;
23 import org.kuali.rice.kew.api.KewApiServiceLocator;
24 import org.kuali.rice.kew.api.WorkflowDocument;
25 import org.kuali.rice.kew.api.action.ActionRequest;
26 import org.kuali.rice.kew.api.action.RoutingReportCriteria;
27 import org.kuali.rice.kew.api.action.WorkflowDocumentActionsService;
28 import org.kuali.rice.kew.api.document.node.RouteNodeInstance;
29 import org.kuali.rice.kew.api.exception.WorkflowException;
30 import org.kuali.rice.kim.api.identity.Person;
31 import org.kuali.rice.kim.api.identity.PersonService;
32 import org.kuali.rice.krad.document.Document;
33 import org.kuali.rice.krad.util.GlobalVariables;
34 import org.kuali.rice.krad.util.ObjectUtils;
35 import org.kuali.rice.krad.workflow.service.WorkflowDocumentService;
36 import org.springframework.transaction.annotation.Transactional;
37
38 import java.security.InvalidParameterException;
39 import java.util.ArrayList;
40 import java.util.Arrays;
41 import java.util.List;
42
43
44
45
46 @Transactional
47 public class PurApWorkflowIntegrationServiceImpl implements PurApWorkflowIntegrationService {
48 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PurApWorkflowIntegrationServiceImpl.class);
49
50
51 private WorkflowDocumentService workflowDocumentService;
52 private PersonService personService;
53
54
55 public void setWorkflowDocumentService(WorkflowDocumentService workflowDocumentService) {
56 this.workflowDocumentService = workflowDocumentService;
57 }
58
59
60
61
62
63
64
65
66
67
68
69 protected void superUserApproveAllActionRequests(Person superUser, String documentNumber, String nodeName, Person user, String annotation) throws WorkflowException {
70 WorkflowDocument workflowDoc = workflowDocumentService.loadWorkflowDocument(documentNumber, superUser);
71 List<ActionRequest> actionRequests = getActiveActionRequestsForCriteria(documentNumber, nodeName, user);
72 for (ActionRequest actionRequestDTO : actionRequests) {
73 if (LOG.isDebugEnabled()) {
74 LOG.debug("Active Action Request list size to process is " + actionRequests.size());
75 LOG.debug("Attempting to super user approve action request with id " + actionRequestDTO.getId());
76 }
77 SpringContext.getBean(org.kuali.rice.kew.routeheader.service.WorkflowDocumentService.class).superUserActionRequestApproveAction(superUser.getPrincipalId(), documentNumber, actionRequestDTO.getId(), annotation, true);
78 break;
79 }
80 }
81
82
83
84
85
86 @Override
87 public boolean takeAllActionsForGivenCriteria(Document document, String potentialAnnotation, String nodeName, Person userToCheck, String superUserNetworkId) {
88 try {
89 String documentNumber = document.getDocumentNumber();
90 String networkIdString = (ObjectUtils.isNotNull(userToCheck)) ? userToCheck.getPrincipalName() : "none";
91 List<ActionRequest> activeActionRequests = getActiveActionRequestsForCriteria(documentNumber, nodeName, userToCheck);
92
93
94 if (activeActionRequests.isEmpty()) {
95 if (LOG.isDebugEnabled()) {
96 LOG.debug("No action requests found on document id " + documentNumber + " for given criteria: principalName - " + networkIdString + "; nodeName - " + nodeName);
97 }
98 return false;
99 }
100
101
102 if (StringUtils.isNotBlank(superUserNetworkId)) {
103
104 Person superUser = getPersonService().getPersonByPrincipalName(superUserNetworkId);
105 if (LOG.isDebugEnabled()) {
106 LOG.debug("Attempting to super user approve all action requests found on document id " + documentNumber + " for given criteria: principalName - " + networkIdString + "; nodeName - " + nodeName);
107 }
108 superUserApproveAllActionRequests(superUser, documentNumber, nodeName, userToCheck, potentialAnnotation);
109 return true;
110 } else {
111
112 if (ObjectUtils.isNotNull(userToCheck)) {
113 WorkflowDocument workflowDocument = workflowDocumentService.loadWorkflowDocument(documentNumber, userToCheck);
114 boolean containsFyiRequest = false;
115 boolean containsAckRequest = false;
116 boolean containsApproveRequest = false;
117 boolean containsCompleteRequest = false;
118 if (StringUtils.isBlank(nodeName)) {
119
120 containsCompleteRequest = workflowDocument.isCompletionRequested();
121 containsApproveRequest = workflowDocument.isApprovalRequested();
122 containsAckRequest = workflowDocument.isAcknowledgeRequested();
123 containsFyiRequest = workflowDocument.isFYIRequested();
124 } else {
125 for (ActionRequest actionRequestDTO : activeActionRequests) {
126 containsFyiRequest |= (KewApiConstants.ACTION_REQUEST_FYI_REQ.equals(actionRequestDTO.getActionRequested().getCode()));
127 containsAckRequest |= (KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ.equals(actionRequestDTO.getActionRequested().getCode()));
128 containsApproveRequest |= (KewApiConstants.ACTION_REQUEST_APPROVE_REQ.equals(actionRequestDTO.getActionRequested().getCode()));
129 containsCompleteRequest |= (KewApiConstants.ACTION_REQUEST_COMPLETE_REQ.equals(actionRequestDTO.getActionRequested().getCode()));
130 }
131 }
132 if (containsCompleteRequest || containsApproveRequest) {
133 workflowDocumentService.approve(workflowDocument, potentialAnnotation, new ArrayList());
134 return true;
135 } else if (containsAckRequest) {
136 workflowDocumentService.acknowledge(workflowDocument, potentialAnnotation, new ArrayList());
137 return true;
138 } else if (containsFyiRequest) {
139 workflowDocumentService.clearFyi(workflowDocument, new ArrayList());
140 return true;
141 }
142 } else {
143
144 String errorMessage = "No super user network id and no user to check given. Need at least one or both";
145 LOG.error(errorMessage);
146 throw new RuntimeException(errorMessage);
147 }
148 }
149 return false;
150 } catch (WorkflowException e) {
151 String errorMessage = "Error trying to get action requests of document id '" + document.getDocumentNumber() + "'";
152 LOG.error("takeAllActionsForGivenCriteria() " + errorMessage, e);
153 throw new RuntimeException(errorMessage, e);
154 } catch (Exception e) {
155 String errorMessage = "Error trying to get user for network id '" + superUserNetworkId + "'";
156 LOG.error("takeAllActionsForGivenCriteria() " + errorMessage, e);
157 throw new RuntimeException(errorMessage, e);
158 }
159 }
160
161
162
163
164
165
166
167
168
169
170 protected List<ActionRequest> getActiveActionRequestsForCriteria(String documentNumber, String nodeName, Person user) throws WorkflowException {
171 if (StringUtils.isBlank(documentNumber)) {
172
173 }
174 org.kuali.rice.kew.api.document.WorkflowDocumentService workflowDocService = KewApiServiceLocator.getWorkflowDocumentService();
175 List<ActionRequest> actionRequests = workflowDocService.getActionRequestsForPrincipalAtNode(documentNumber, nodeName, user.getPrincipalId());
176 List<ActionRequest> activeRequests = new ArrayList<ActionRequest>();
177 for (ActionRequest actionRequest : actionRequests) {
178
179 if (actionRequest.isActivated()) {
180 activeRequests.add(actionRequest);
181 }
182 }
183 return activeRequests;
184 }
185
186
187
188
189
190
191
192 @Override
193 public boolean willDocumentStopAtGivenFutureRouteNode(PurchasingAccountsPayableDocument document, String givenNodeName) {
194 if (givenNodeName == null) {
195 throw new InvalidParameterException("Given Node Detail object was null");
196 }
197 try {
198 String activeNode = null;
199 String[] nodeNames = document.getDocumentHeader().getWorkflowDocument().getCurrentNodeNames().toArray(new String[0]);
200
201 if (nodeNames.length == 1) {
202 activeNode = nodeNames[0];
203 }
204
205 if (isGivenNodeAfterCurrentNode(document, activeNode, givenNodeName)) {
206 if (document.getDocumentHeader().getWorkflowDocument().isInitiated()) {
207
208 RoutingReportCriteria.Builder builder = RoutingReportCriteria.Builder.createByDocumentTypeName(document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName());
209 builder.setXmlContent(document.getXmlForRouteReport());
210 builder.setRoutingPrincipalId(GlobalVariables.getUserSession().getPerson().getPrincipalId());
211 builder.setTargetNodeName(givenNodeName);
212 RoutingReportCriteria reportCriteria = builder.build();
213 boolean value = SpringContext.getBean(WorkflowDocumentActionsService.class).documentWillHaveAtLeastOneActionRequest(reportCriteria, Arrays.asList(KewApiConstants.ACTION_REQUEST_APPROVE_REQ, KewApiConstants.ACTION_REQUEST_COMPLETE_REQ), false);
214 return value;
215 } else {
216
217
218
219
220 RoutingReportCriteria.Builder builder = RoutingReportCriteria.Builder.createByDocumentId(document.getDocumentNumber());
221 builder.setXmlContent(document.getXmlForRouteReport());
222 builder.setTargetNodeName(givenNodeName);
223 RoutingReportCriteria reportCriteria = builder.build();
224 boolean value = SpringContext.getBean(WorkflowDocumentActionsService.class).documentWillHaveAtLeastOneActionRequest(reportCriteria, Arrays.asList(KewApiConstants.ACTION_REQUEST_APPROVE_REQ, KewApiConstants.ACTION_REQUEST_COMPLETE_REQ), false);
225 return value;
226 }
227 }
228 return false;
229 } catch (Exception e) {
230 String errorMessage = "Error trying to test document id '" + document.getDocumentNumber() + "' for action requests at node name '" + givenNodeName + "'";
231 LOG.error("isDocumentStoppingAtRouteLevel() " + errorMessage, e);
232 throw new RuntimeException(errorMessage, e);
233 }
234 }
235
236
237
238
239
240
241
242
243 protected boolean isGivenNodeAfterCurrentNode(Document document, String currentNodeName, String givenNodeName) {
244 if (ObjectUtils.isNull(givenNodeName)) {
245
246 return false;
247 }
248 if (ObjectUtils.isNull(currentNodeName)) {
249
250 return true;
251 }
252
253 List<RouteNodeInstance> routeNodes = KewApiServiceLocator.getWorkflowDocumentService().getRouteNodeInstances(document.getDocumentNumber());
254
255 int currentNodeIndex = 0;
256 int givenNodeIndex = 0;
257 RouteNodeInstance node = null;
258
259
260 for (int i = 0; i < routeNodes.size(); i++) {
261 node = routeNodes.get(i);
262
263 if (node.getName().equals(currentNodeName)) {
264 currentNodeIndex = i;
265 }
266 if (node.getName().equals(givenNodeName)) {
267 givenNodeIndex = i;
268 }
269 }
270
271
272 return givenNodeIndex > currentNodeIndex;
273
274 }
275
276
277
278
279
280 protected PersonService getPersonService() {
281 if (personService == null) {
282 personService = SpringContext.getBean(PersonService.class);
283 }
284 return personService;
285 }
286
287 }