1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.actionlist.service.impl;
17
18 import static org.kuali.rice.core.api.criteria.PredicateFactory.between;
19 import static org.kuali.rice.core.api.criteria.PredicateFactory.equal;
20 import static org.kuali.rice.core.api.criteria.PredicateFactory.greaterThanOrEqual;
21 import static org.kuali.rice.core.api.criteria.PredicateFactory.in;
22 import static org.kuali.rice.core.api.criteria.PredicateFactory.isNotNull;
23 import static org.kuali.rice.core.api.criteria.PredicateFactory.isNull;
24 import static org.kuali.rice.core.api.criteria.PredicateFactory.lessThanOrEqual;
25 import static org.kuali.rice.core.api.criteria.PredicateFactory.like;
26 import static org.kuali.rice.core.api.criteria.PredicateFactory.notBetween;
27 import static org.kuali.rice.core.api.criteria.PredicateFactory.notEqual;
28 import static org.kuali.rice.core.api.criteria.PredicateFactory.notLike;
29 import static org.kuali.rice.core.api.criteria.PredicateFactory.or;
30
31 import java.sql.Timestamp;
32 import java.util.ArrayList;
33 import java.util.Calendar;
34 import java.util.Collection;
35 import java.util.Collections;
36 import java.util.Date;
37 import java.util.HashMap;
38 import java.util.List;
39 import java.util.Map;
40
41 import org.apache.commons.collections.CollectionUtils;
42 import org.apache.commons.lang.StringUtils;
43 import org.kuali.rice.core.api.config.property.ConfigContext;
44 import org.kuali.rice.core.api.criteria.Predicate;
45 import org.kuali.rice.core.api.criteria.QueryByCriteria;
46 import org.kuali.rice.core.api.criteria.QueryResults;
47 import org.kuali.rice.core.api.datetime.DateTimeService;
48 import org.kuali.rice.core.api.delegation.DelegationType;
49 import org.kuali.rice.kew.actionitem.ActionItem;
50 import org.kuali.rice.kew.actionitem.ActionItemBase;
51 import org.kuali.rice.kew.actionitem.OutboxItem;
52 import org.kuali.rice.kew.actionlist.ActionListFilter;
53 import org.kuali.rice.kew.actionlist.dao.ActionListDAO;
54 import org.kuali.rice.kew.actionlist.dao.impl.ActionListPriorityComparator;
55 import org.kuali.rice.kew.actionlist.service.ActionListService;
56 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
57 import org.kuali.rice.kew.actionrequest.KimGroupRecipient;
58 import org.kuali.rice.kew.actionrequest.Recipient;
59 import org.kuali.rice.kew.actionrequest.service.ActionRequestService;
60 import org.kuali.rice.kew.actiontaken.ActionTakenValue;
61 import org.kuali.rice.kew.api.KewApiConstants;
62 import org.kuali.rice.kew.doctype.bo.DocumentType;
63 import org.kuali.rice.kew.doctype.service.DocumentTypeService;
64 import org.kuali.rice.kew.notification.service.NotificationService;
65 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
66 import org.kuali.rice.kew.routeheader.service.RouteHeaderService;
67 import org.kuali.rice.kew.useroptions.UserOptions;
68 import org.kuali.rice.kew.useroptions.UserOptionsService;
69 import org.kuali.rice.kew.util.WebFriendlyRecipient;
70 import org.kuali.rice.kim.api.group.GroupService;
71 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
72 import org.kuali.rice.krad.data.DataObjectService;
73
74
75
76
77
78
79 public class ActionListServiceImpl implements ActionListService {
80
81 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ActionListServiceImpl.class);
82
83 protected DataObjectService dataObjectService;
84 protected NotificationService notificationService;
85 protected DateTimeService dateTimeService;
86 protected ActionRequestService actionRequestService;
87 protected DocumentTypeService documentTypeService;
88 protected UserOptionsService userOptionsService;
89 protected RouteHeaderService routeHeaderService;
90
91 protected ActionListDAO actionListDAO;
92
93 @Override
94 public Collection<Recipient> findUserSecondaryDelegators(String principalId) {
95
96 QueryByCriteria query = QueryByCriteria.Builder.fromPredicates(
97 equal("principalId", principalId),
98 equal("delegationType", DelegationType.SECONDARY.getCode()),
99 or(isNotNull("delegatorPrincipalId"), isNotNull("delegatorGroupId")));
100
101 QueryResults<ActionItem> results = dataObjectService.findMatching(ActionItem.class, query);
102
103 Map<Object, Recipient> delegators = new HashMap<Object, Recipient>(results.getResults().size());
104
105 for ( ActionItem actionItem : results.getResults() ) {
106 String delegatorPrincipalId = actionItem.getDelegatorPrincipalId();
107 String delegatorGroupId = actionItem.getDelegatorGroupId();
108
109 if (delegatorPrincipalId != null && !delegators.containsKey(delegatorPrincipalId)) {
110 delegators.put(delegatorPrincipalId,new WebFriendlyRecipient(KimApiServiceLocator.getPersonService().getPerson(delegatorPrincipalId)));
111 } else if (delegatorGroupId != null && !delegators.containsKey(delegatorGroupId)) {
112 delegators.put(delegatorGroupId, new KimGroupRecipient(KimApiServiceLocator.getGroupService().getGroup(delegatorGroupId)));
113 }
114 }
115
116 return delegators.values();
117 }
118
119 @Override
120 public Collection<Recipient> findUserPrimaryDelegations(String principalId) {
121 List<String> workgroupIds = KimApiServiceLocator.getGroupService().getGroupIdsByPrincipalId(principalId);
122
123 Predicate whoPredicate = null;
124 if (CollectionUtils.isNotEmpty(workgroupIds)) {
125 whoPredicate = or( equal("delegatorPrincipalId", principalId), in("delegatorGroupId", workgroupIds ) );
126 } else {
127 whoPredicate = equal("delegatorPrincipalId", principalId);
128 }
129 QueryByCriteria query = QueryByCriteria.Builder.fromPredicates(whoPredicate, equal("delegationType", DelegationType.PRIMARY.getCode() ) );
130
131 QueryResults<ActionItem> results = dataObjectService.findMatching(ActionItem.class, query);
132
133 Map<String, Recipient> delegators = new HashMap<String, Recipient>(results.getResults().size());
134
135 for ( ActionItem actionItem : results.getResults() ) {
136 String recipientPrincipalId = actionItem.getPrincipalId();
137 if (recipientPrincipalId != null && !delegators.containsKey(recipientPrincipalId)) {
138 delegators.put(recipientPrincipalId, new WebFriendlyRecipient(
139 KimApiServiceLocator.getPersonService().getPerson(recipientPrincipalId)));
140 }
141 }
142
143 return delegators.values();
144 }
145
146 @Override
147 public Collection<ActionItem> getActionList(String principalId, ActionListFilter filter) {
148 List<String> filteredByItems = new ArrayList<String>();
149
150 List<Predicate> crit = handleActionItemCriteria(principalId, filter, filteredByItems);
151
152 if ( LOG.isDebugEnabled() ) {
153 LOG.debug("running query to get action list for criteria " + crit);
154 }
155 QueryByCriteria query = QueryByCriteria.Builder.fromPredicates(crit);
156 QueryResults<ActionItem> results = dataObjectService.findMatching(ActionItem.class, query);
157 if ( LOG.isDebugEnabled() ) {
158 LOG.debug("found " + results.getResults().size() + " action items for user " + principalId);
159 }
160
161 if (filter != null) {
162 boolean filterOn = !filteredByItems.isEmpty();
163 filter.setFilterOn(filterOn);
164 filter.setFilterLegend(StringUtils.join(filteredByItems, ", "));
165 }
166
167 return createActionListForUser(results.getResults());
168 }
169
170 protected List<Predicate> handleActionItemCriteria( String principalId, ActionListFilter filter, List<String> filteredByItems ) {
171 LOG.debug("setting up Action List criteria");
172 ArrayList<Predicate> crit = new ArrayList<Predicate>();
173
174 if ( filter != null ) {
175 handleActionRequestedCriteria(filter, crit, filteredByItems);
176 handleDocumentCreateDateCriteria(filter, crit, filteredByItems);
177 handleAssignedDateCriteria(filter, crit, filteredByItems);
178 handleRouteStatusCriteria(filter, crit, filteredByItems);
179 handleDocumentTitleCriteria(filter, crit, filteredByItems);
180 handleDocumentTypeCriteria(filter, crit, filteredByItems);
181 handleWorkgroupCriteria(filter, crit, filteredByItems);
182 handleRecipientCriteria(principalId, filter, crit, filteredByItems);
183 } else {
184 crit.add( equal("principalId", principalId) );
185 }
186 LOG.debug( "Completed setting up Action List criteria");
187 return crit;
188 }
189
190 protected void handleActionRequestedCriteria( ActionListFilter filter, Collection<Predicate> crit, List<String> filteredByItems ) {
191 if ( StringUtils.isNotBlank(filter.getActionRequestCd())
192 && !filter.getActionRequestCd().equals(KewApiConstants.ALL_CODE)) {
193 if (filter.isExcludeActionRequestCd()) {
194 crit.add( notEqual("actionRequestCd", filter.getActionRequestCd()));
195 } else {
196 crit.add( equal("actionRequestCd", filter.getActionRequestCd()));
197 }
198 filteredByItems.add( "Action Requested" );
199 }
200 }
201
202 protected void handleDateCriteria( String propertyPath, String filterLabel, Date fromDate, Date toDate, boolean excludeDates, Collection<Predicate> crit, List<String> filteredByItems ) {
203 if (fromDate != null || toDate != null) {
204 Timestamp fromDateTimestamp = beginningOfDay(fromDate);
205 Timestamp toDateTimestamp = endOfDay(toDate);
206 if (excludeDates) {
207 if (fromDate != null && toDate != null) {
208 crit.add( notBetween(propertyPath, fromDateTimestamp, toDateTimestamp ) );
209 } else if (fromDate != null && toDate == null) {
210 crit.add( lessThanOrEqual(propertyPath, fromDateTimestamp ) );
211 } else if (fromDate == null && toDate != null) {
212 crit.add( greaterThanOrEqual(propertyPath, toDateTimestamp ) );
213 }
214 } else {
215 if (fromDate != null && toDate != null) {
216 crit.add( between(propertyPath, fromDateTimestamp, toDateTimestamp ) );
217 } else if (fromDate != null && toDate == null) {
218 crit.add( greaterThanOrEqual(propertyPath, fromDateTimestamp ) );
219 } else if (fromDate == null && toDate != null) {
220 crit.add( lessThanOrEqual(propertyPath, toDateTimestamp ) );
221 }
222 }
223 filteredByItems.add("Date Created");
224 }
225 }
226
227 protected void handleDocumentCreateDateCriteria( ActionListFilter filter, Collection<Predicate> crit, List<String> filteredByItems ) {
228 handleDateCriteria("routeHeader.createDate", "Date Created", filter.getCreateDateFrom(), filter.getCreateDateTo(), filter.isExcludeCreateDate(), crit, filteredByItems);
229 }
230
231 protected void handleAssignedDateCriteria( ActionListFilter filter, Collection<Predicate> crit, List<String> filteredByItems ) {
232 handleDateCriteria("dateAssigned", "Date Last Assigned", filter.getLastAssignedDateFrom(), filter.getLastAssignedDateTo(), filter.isExcludeLastAssignedDate(), crit, filteredByItems);
233 }
234
235 protected void handleRouteStatusCriteria( ActionListFilter filter, Collection<Predicate> crit, List<String> filteredByItems ) {
236 if ( StringUtils.isNotBlank(filter.getDocRouteStatus())
237 && !filter.getDocRouteStatus().equals(KewApiConstants.ALL_CODE)) {
238 if (filter.isExcludeRouteStatus()) {
239 crit.add( notEqual("routeHeader.docRouteStatus", filter.getDocRouteStatus() ) );
240 } else {
241 crit.add( equal("routeHeader.docRouteStatus", filter.getDocRouteStatus() ) );
242 }
243 filteredByItems.add( "Document Route Status" );
244 }
245 }
246
247 protected void handleDocumentTitleCriteria( ActionListFilter filter, Collection<Predicate> crit, List<String> filteredByItems ) {
248 if ( StringUtils.isNotBlank(filter.getDocumentTitle()) ) {
249 String docTitle = filter.getDocumentTitle().trim();
250 if (docTitle.endsWith("*")) {
251 docTitle = docTitle.substring(0, docTitle.length() - 1);
252 }
253 if (filter.isExcludeDocumentTitle()) {
254 crit.add( notLike("docTitle", "%" + docTitle + "%" ) );
255 } else {
256 crit.add( like("docTitle", "%" + docTitle + "%" ) );
257 }
258 filteredByItems.add( "Document Title" );
259 }
260 }
261
262 protected void handleDocumentTypeCriteria( ActionListFilter filter, Collection<Predicate> crit, List<String> filteredByItems ) {
263 if ( StringUtils.isNotBlank(filter.getDocumentType()) ) {
264 String documentTypeName = filter.getDocumentType();
265 if (filter.isExcludeDocumentType()) {
266 crit.add( notLike( "docName", "%" + documentTypeName + "%" ) );
267 } else {
268 DocumentType documentType = documentTypeService.findByName(documentTypeName);
269
270 if (documentType == null) {
271 crit.add( like( "docName", "%" + documentTypeName + "%" ) );
272 } else {
273
274 Collection<DocumentType> docs = getAllChildDocumentTypes(documentType);
275 Collection<String> docNames = new ArrayList<String>(docs.size()+1);
276 docNames.add(documentType.getName());
277 for ( DocumentType doc : docs ) {
278 docNames.add(doc.getName());
279 }
280 crit.add( in("docName", docNames) );
281 }
282 }
283 filteredByItems.add( "Document Type" );
284 }
285 }
286
287 protected Collection<DocumentType> getAllChildDocumentTypes( DocumentType docType ) {
288 Collection<DocumentType> allChildren = new ArrayList<DocumentType>();
289
290 List<DocumentType> immediateChildren = documentTypeService.getChildDocumentTypes(docType.getId());
291 if ( immediateChildren != null ) {
292 allChildren.addAll(immediateChildren);
293
294 for ( DocumentType childDoc : immediateChildren ) {
295 allChildren.addAll( getAllChildDocumentTypes(childDoc));
296 }
297 }
298
299 return allChildren;
300 }
301
302 protected void handleWorkgroupCriteria( ActionListFilter filter, Collection<Predicate> crit, List<String> filteredByItems ) {
303 filter.setGroupId(null);
304 if ( StringUtils.isNotBlank(filter.getGroupIdString())
305 && !filter.getGroupIdString().trim().equals(KewApiConstants.NO_FILTERING)) {
306
307 filter.setGroupId(filter.getGroupIdString().trim());
308
309 if (filter.isExcludeGroupId()) {
310 crit.add( or(
311 notEqual("groupId", filter.getGroupId()),
312 isNull("groupId") ) );
313 } else {
314 crit.add( equal("groupId", filter.getGroupId()) );
315 }
316 filteredByItems.add( "Action Request Workgroup" );
317 }
318 }
319
320 protected void applyPrimaryDelegationCriteria( String actionListUserPrincipalId, ActionListFilter filter, Collection<Predicate> crit, List<String> filteredByItems ) {
321
322 List<String> delegatorGroupIds = KimApiServiceLocator.getGroupService().getGroupIdsByPrincipalId(actionListUserPrincipalId);
323
324 if (delegatorGroupIds != null && !delegatorGroupIds.isEmpty()) {
325 crit.add( or( equal("delegatorPrincipalId", actionListUserPrincipalId), in("delegatorGroupId", delegatorGroupIds) ) );
326 } else {
327 crit.add( equal("delegatorPrincipalId", actionListUserPrincipalId) );
328 }
329 crit.add( equal("delegationType", DelegationType.PRIMARY.getCode() ) );
330 filter.setDelegationType(DelegationType.PRIMARY.getCode());
331 filter.setExcludeDelegationType(false);
332 filteredByItems.add("Primary Delegator Id");
333 }
334
335
336
337
338
339
340
341
342 protected boolean handlePrimaryDelegation( String actionListUserPrincipalId, ActionListFilter filter, Collection<Predicate> crit, List<String> filteredByItems ) {
343 if ( StringUtils.isBlank(filter.getPrimaryDelegateId())
344 || filter.getPrimaryDelegateId().trim().equals(KewApiConstants.ALL_CODE) ) {
345
346 applyPrimaryDelegationCriteria(actionListUserPrincipalId, filter, crit, filteredByItems);
347
348 return true;
349 } else if (!filter.getPrimaryDelegateId().trim().equals(KewApiConstants.PRIMARY_DELEGATION_DEFAULT)) {
350
351 crit.add( equal("principalId", filter.getPrimaryDelegateId() ) );
352 applyPrimaryDelegationCriteria(actionListUserPrincipalId, filter, crit, filteredByItems);
353
354 return true;
355 }
356
357 return false;
358 }
359
360
361
362
363
364
365
366
367 protected boolean handleSecondaryDelegation( String actionListUserPrincipalId, ActionListFilter filter, Collection<Predicate> crit, List<String> filteredByItems ) {
368 crit.add( equal("principalId", actionListUserPrincipalId) );
369 if (StringUtils.isBlank(filter.getDelegatorId())) {
370 filter.setDelegationType(DelegationType.SECONDARY.getCode());
371
372
373 if (!filter.isExcludeDelegationType()) {
374 crit.add( equal("delegationType", DelegationType.SECONDARY.getCode() ) );
375 filteredByItems.add("Secondary Delegator Id");
376
377 return true;
378 }
379 } else if (filter.getDelegatorId().trim().equals(KewApiConstants.ALL_CODE)) {
380
381 crit.add( equal("delegationType", DelegationType.SECONDARY.getCode() ) );
382 filter.setDelegationType(DelegationType.SECONDARY.getCode());
383 filter.setExcludeDelegationType(false);
384 filteredByItems.add("Secondary Delegator Id");
385
386 return true;
387 } else if (!filter.getDelegatorId().trim().equals(KewApiConstants.DELEGATION_DEFAULT)) {
388
389 filter.setDelegationType(DelegationType.SECONDARY.getCode());
390 filter.setExcludeDelegationType(false);
391
392 if (filter.isExcludeDelegatorId()) {
393 crit.add( or( notEqual("delegatorPrincipalId", filter.getDelegatorId()), isNull("delegatorPrincipalId") ) );
394 crit.add( or( notEqual("delegatorGroupId", filter.getDelegatorId()), isNull("delegatorGroupId") ) );
395 } else {
396 crit.add( or( equal("delegatorPrincipalId", filter.getDelegatorId()), equal("delegatorGroupId", filter.getDelegatorId()) ) );
397 }
398 filteredByItems.add("Secondary Delegator Id");
399
400 return true;
401 }
402
403 return false;
404 }
405
406
407
408
409
410
411
412
413
414 protected void handleRecipientCriteria( String actionListUserPrincipalId, ActionListFilter filter, Collection<Predicate> crit, List<String> filteredByItems ) {
415 if (StringUtils.isBlank(filter.getDelegationType())
416 && StringUtils.isBlank(filter.getPrimaryDelegateId())
417 && StringUtils.isBlank(filter.getDelegatorId())) {
418 crit.add( equal("principalId", actionListUserPrincipalId) );
419 return;
420 }
421 if ( StringUtils.equals(filter.getDelegationType(), DelegationType.PRIMARY.getCode() )
422 || StringUtils.isNotBlank(filter.getPrimaryDelegateId())) {
423
424 if ( handlePrimaryDelegation(actionListUserPrincipalId, filter, crit, filteredByItems)) {
425 return;
426 }
427 }
428
429 if (StringUtils.equals(filter.getDelegationType(), DelegationType.SECONDARY.getCode())
430 || StringUtils.isNotBlank(filter.getDelegatorId()) ) {
431
432 if ( handleSecondaryDelegation(actionListUserPrincipalId, filter, crit, filteredByItems) ) {
433 return;
434 }
435 }
436
437
438 filter.setDelegationType(DelegationType.SECONDARY.getCode());
439 filter.setExcludeDelegationType(true);
440 crit.add( equal("principalId", actionListUserPrincipalId) );
441 crit.add( or( notEqual("delegationType", DelegationType.SECONDARY.getCode()), isNull("delegationType") ) );
442 }
443
444
445
446
447
448
449
450
451 private Collection<ActionItem> createActionListForUser(Collection<ActionItem> actionItems) {
452 Map<String, ActionItem> actionItemMap = new HashMap<String, ActionItem>();
453 ActionListPriorityComparator comparator = new ActionListPriorityComparator();
454 for (ActionItem potentialActionItem: actionItems) {
455 ActionItem existingActionItem = actionItemMap.get(potentialActionItem.getDocumentId());
456 if (existingActionItem == null || comparator.compare(potentialActionItem, existingActionItem) > 0) {
457 actionItemMap.put(potentialActionItem.getDocumentId(), potentialActionItem);
458 }
459 }
460 return actionItemMap.values();
461 }
462
463
464
465
466
467 @Override
468 public Collection<ActionItem> getActionListForSingleDocument(String documentId) {
469 if ( LOG.isDebugEnabled() ) {
470 LOG.debug("getting action list for document id " + documentId);
471 }
472 Collection<ActionItem> collection = findByDocumentId(documentId);
473 if ( LOG.isDebugEnabled() ) {
474 LOG.debug("found " + collection.size() + " action items for document id " + documentId);
475 }
476 return createActionListForRouteHeader(collection);
477 }
478
479
480
481
482
483
484
485
486 protected Collection<ActionItem> createActionListForRouteHeader(Collection<ActionItem> actionItems) {
487 Map<String, ActionItem> actionItemMap = new HashMap<String, ActionItem>();
488 ActionListPriorityComparator comparator = new ActionListPriorityComparator();
489 for (ActionItem potentialActionItem: actionItems) {
490 ActionItem existingActionItem = actionItemMap.get(potentialActionItem.getPrincipalId());
491 if (existingActionItem == null || comparator.compare(potentialActionItem, existingActionItem) > 0) {
492 actionItemMap.put(potentialActionItem.getPrincipalId(), potentialActionItem);
493 }
494 }
495 return actionItemMap.values();
496 }
497
498 public void setActionListDAO(ActionListDAO actionListDAO) {
499 this.actionListDAO = actionListDAO;
500 }
501
502 @Override
503 public void deleteActionItemNoOutbox(ActionItem actionItem) {
504 deleteActionItem(actionItem, false, false);
505 }
506
507 @Override
508 public void deleteActionItem(ActionItem actionItem) {
509 deleteActionItem(actionItem, false);
510 }
511
512 @Override
513 public void deleteActionItem(ActionItem actionItem, boolean forceIntoOutbox) {
514 deleteActionItem(actionItem, forceIntoOutbox, true);
515 }
516
517 protected void deleteActionItem(ActionItem actionItem, boolean forceIntoOutbox, boolean putInOutbox) {
518 dataObjectService.delete(actionItem);
519
520 notificationService.removeNotification(Collections.singletonList(ActionItem.to(actionItem)));
521 if (putInOutbox) {
522 saveOutboxItem(actionItem, forceIntoOutbox);
523 }
524 }
525
526 @Override
527 public void deleteByDocumentId(String documentId) {
528 dataObjectService.deleteMatching(ActionItem.class, QueryByCriteria.Builder.forAttribute("documentId", documentId).build());
529 }
530
531 @Override
532 public Collection<ActionItem> findByDocumentId(String documentId) {
533 QueryResults<ActionItem> results = dataObjectService.findMatching(ActionItem.class,
534 QueryByCriteria.Builder.forAttribute("documentId", documentId).build());
535
536 return results.getResults();
537 }
538
539 @Override
540 public Collection<ActionItem> findByActionRequestId(String actionRequestId) {
541 QueryResults<ActionItem> results = dataObjectService.findMatching(ActionItem.class,
542 QueryByCriteria.Builder.forAttribute("actionRequestId", actionRequestId).build());
543
544 return results.getResults();
545 }
546
547 @Override
548 public Collection<ActionItem> findByWorkflowUserDocumentId(String workflowUserId, String documentId) {
549 Map<String,String> criteria = new HashMap<String, String>(2);
550 criteria.put( "principalId", workflowUserId );
551 criteria.put( "documentId", documentId );
552 QueryResults<ActionItem> results = dataObjectService.findMatching(ActionItem.class,
553 QueryByCriteria.Builder.andAttributes(criteria).build());
554
555 return results.getResults();
556 }
557
558 @Override
559 public Collection<ActionItem> findByDocumentTypeName(String documentTypeName) {
560 QueryResults<ActionItem> results = dataObjectService.findMatching(ActionItem.class,
561 QueryByCriteria.Builder.forAttribute("docName", documentTypeName).build());
562
563 return results.getResults();
564 }
565
566 @Override
567 public ActionItem createActionItemForActionRequest(ActionRequestValue actionRequest) {
568 ActionItem actionItem = new ActionItem();
569
570 DocumentRouteHeaderValue routeHeader = actionRequest.getRouteHeader();
571 DocumentType docType = routeHeader.getDocumentType();
572
573 actionItem.setActionRequestCd(actionRequest.getActionRequested());
574 actionItem.setActionRequestId(actionRequest.getActionRequestId());
575 actionItem.setDocName(docType.getName());
576 actionItem.setRoleName(actionRequest.getQualifiedRoleName());
577 actionItem.setPrincipalId(actionRequest.getPrincipalId());
578 actionItem.setDocumentId(actionRequest.getDocumentId());
579 actionItem.setDateAssigned(new Timestamp(new Date().getTime()));
580 actionItem.setDocHandlerURL(docType.getResolvedDocumentHandlerUrl());
581 actionItem.setDocLabel(docType.getLabel());
582 actionItem.setDocTitle(routeHeader.getDocTitle());
583 actionItem.setGroupId(actionRequest.getGroupId());
584 actionItem.setResponsibilityId(actionRequest.getResponsibilityId());
585 actionItem.setDelegationType(actionRequest.getDelegationType());
586 actionItem.setRequestLabel(actionRequest.getRequestLabel());
587
588 ActionRequestValue delegatorActionRequest = actionRequestService.findDelegatorRequest(actionRequest);
589 if (delegatorActionRequest != null) {
590 actionItem.setDelegatorPrincipalId(delegatorActionRequest.getPrincipalId());
591 actionItem.setDelegatorGroupId(delegatorActionRequest.getGroupId());
592 }
593
594 return actionItem;
595 }
596
597
598 @Override
599 public void updateActionItemsForTitleChange(String documentId, String newTitle) {
600 Collection<ActionItem> items = findByDocumentId(documentId);
601 for ( ActionItem item : items ) {
602 item.setDocTitle(newTitle);
603 saveActionItem(item);
604 }
605 }
606
607 @Override
608 public ActionItem saveActionItem(ActionItem actionItem) {
609 return saveActionItemBase(actionItem);
610 }
611
612 @Override
613 public OutboxItem saveOutboxItem(OutboxItem outboxItem) {
614 return saveActionItemBase(outboxItem);
615 }
616
617 protected <T extends ActionItemBase> T saveActionItemBase(T actionItemBase) {
618 if (actionItemBase.getDateAssigned() == null) {
619 actionItemBase.setDateAssigned(dateTimeService.getCurrentTimestamp());
620 }
621 return dataObjectService.save(actionItemBase);
622 }
623
624 public GroupService getGroupService(){
625 return KimApiServiceLocator.getGroupService();
626 }
627
628 @Override
629 public ActionItem findByActionItemId(String actionItemId) {
630 return dataObjectService.find(ActionItem.class, actionItemId);
631 }
632
633 @Override
634 public int getCount(String principalId) {
635 return actionListDAO.getCount(principalId);
636 }
637
638 @Override
639 public List<Object> getMaxActionItemDateAssignedAndCountForUser(String principalId) {
640 return actionListDAO.getMaxActionItemDateAssignedAndCountForUser(principalId);
641 }
642
643
644
645
646
647
648
649 @Override
650 public Collection<OutboxItem> getOutbox(String principalId, ActionListFilter filter) {
651 boolean filterOn = false;
652 List<String> filteredByItems = new ArrayList<String>();
653
654 List<Predicate> crit = handleActionItemCriteria(principalId, filter, filteredByItems);
655
656 if ( LOG.isDebugEnabled() ) {
657 LOG.debug("running query to get outbox list for criteria " + crit);
658 }
659 QueryByCriteria query = QueryByCriteria.Builder.fromPredicates(crit);
660 QueryResults<OutboxItem> results = dataObjectService.findMatching(OutboxItem.class, query);
661 if ( LOG.isDebugEnabled() ) {
662 LOG.debug("found " + results.getResults().size() + " outbox items for user " + principalId);
663 }
664
665 if ( !filteredByItems.isEmpty() ) {
666 filterOn = true;
667 }
668 filter.setFilterLegend(StringUtils.join(filteredByItems, ", "));
669 filter.setFilterOn(filterOn);
670
671 return results.getResults();
672 }
673
674 @Override
675 public Collection<OutboxItem> getOutboxItemsByDocumentType(String documentTypeName) {
676 QueryResults<OutboxItem> results = dataObjectService.findMatching(OutboxItem.class,
677 QueryByCriteria.Builder.forAttribute("docName", documentTypeName).build());
678
679 return results.getResults();
680 }
681
682
683
684
685
686
687 @Override
688 public void removeOutboxItems(String principalId, List<String> outboxItems) {
689 QueryByCriteria query = QueryByCriteria.Builder.fromPredicates(
690 in("id", outboxItems));
691
692 dataObjectService.deleteMatching(OutboxItem.class, query);
693 }
694
695 @Override
696 public OutboxItem saveOutboxItem(ActionItem actionItem) {
697 return saveOutboxItem(actionItem, false);
698 }
699
700
701
702
703
704
705
706 @Override
707 public OutboxItem saveOutboxItem(ActionItem actionItem, boolean forceIntoOutbox) {
708 Boolean isUsingOutBox = true;
709 List<UserOptions> options = userOptionsService.findByUserQualified(actionItem.getPrincipalId(), KewApiConstants.USE_OUT_BOX);
710 if (options == null || options.isEmpty()){
711 isUsingOutBox = true;
712 } else {
713 for ( UserOptions u : options ) {
714 if ( !StringUtils.equals(u.getOptionVal(), "yes") ) {
715 isUsingOutBox = false;
716 break;
717 }
718 }
719 }
720
721 if (isUsingOutBox
722 && ConfigContext.getCurrentContextConfig().getOutBoxOn()
723 && getOutboxItemByDocumentIdUserId(actionItem.getDocumentId(), actionItem.getPrincipalId()) == null
724 && !routeHeaderService.getRouteHeader(actionItem.getDocumentId()).getDocRouteStatus().equals(
725 KewApiConstants.ROUTE_HEADER_SAVED_CD)) {
726
727
728 ActionRequestValue actionRequest = actionRequestService.findByActionRequestId(
729 actionItem.getActionRequestId());
730 ActionTakenValue actionTaken = actionRequest.getActionTaken();
731
732 if (forceIntoOutbox || (actionTaken != null && actionTaken.getPrincipalId().equals(actionItem.getPrincipalId()))) {
733 return dataObjectService.save(new OutboxItem(actionItem));
734 }
735
736 }
737 return null;
738 }
739
740 protected OutboxItem getOutboxItemByDocumentIdUserId(String documentId, String principalId) {
741 Map<String,String> criteria = new HashMap<String, String>(2);
742 criteria.put( "principalId", principalId );
743 criteria.put( "documentId", documentId );
744 QueryResults<OutboxItem> results = dataObjectService.findMatching(OutboxItem.class,
745 QueryByCriteria.Builder.andAttributes(criteria).build());
746 if ( results.getResults().isEmpty() ) {
747 return null;
748 }
749 return results.getResults().get(0);
750 }
751
752 @Override
753 public Collection<ActionItem> findByPrincipalId(String principalId) {
754 QueryResults<ActionItem> results = dataObjectService.findMatching(ActionItem.class,
755 QueryByCriteria.Builder.forAttribute("principalId", principalId)
756 .setOrderByAscending("documentId").build());
757
758 return results.getResults();
759 }
760
761
762
763
764 @Override
765 public DocumentRouteHeaderValue getMinimalRouteHeader(String documentId) {
766 return actionListDAO.getMinimalRouteHeader(documentId);
767 }
768
769 protected Timestamp beginningOfDay(Date date) {
770 if ( date == null ) {
771 return null;
772 }
773 Calendar cal = Calendar.getInstance();
774 cal.setTime(date);
775 cal.set(Calendar.HOUR_OF_DAY, 0);
776 cal.set(Calendar.MINUTE, 0);
777 cal.set(Calendar.SECOND, 0);
778 return new Timestamp( cal.getTimeInMillis() );
779 }
780
781 protected Timestamp endOfDay(Date date) {
782 if ( date == null ) {
783 return null;
784 }
785 Calendar cal = Calendar.getInstance();
786 cal.setTime(date);
787 cal.set(Calendar.HOUR_OF_DAY, 23);
788 cal.set(Calendar.MINUTE, 59);
789 cal.set(Calendar.SECOND, 59);
790 return new Timestamp( cal.getTimeInMillis() );
791 }
792
793 public void setDataObjectService(DataObjectService dataObjectService) {
794 this.dataObjectService = dataObjectService;
795 }
796
797 public void setNotificationService(NotificationService notificationService) {
798 this.notificationService = notificationService;
799 }
800
801 public void setDateTimeService(DateTimeService dateTimeService) {
802 this.dateTimeService = dateTimeService;
803 }
804
805 public void setActionRequestService(ActionRequestService actionRequestService) {
806 this.actionRequestService = actionRequestService;
807 }
808
809 public void setDocumentTypeService(DocumentTypeService documentTypeService) {
810 this.documentTypeService = documentTypeService;
811 }
812
813 public void setUserOptionsService(UserOptionsService userOptionsService) {
814 this.userOptionsService = userOptionsService;
815 }
816
817 public void setRouteHeaderService(RouteHeaderService routeHeaderService) {
818 this.routeHeaderService = routeHeaderService;
819 }
820 }