001 /**
002 * Copyright 2005-2013 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 */
016 package org.kuali.rice.kew.actionrequest;
017
018 import org.apache.commons.lang.StringUtils;
019 import org.apache.commons.lang.builder.ToStringBuilder;
020 import org.apache.commons.lang.builder.ToStringStyle;
021 import org.hibernate.annotations.Fetch;
022 import org.hibernate.annotations.FetchMode;
023 import org.hibernate.annotations.GenericGenerator;
024 import org.hibernate.annotations.Parameter;
025 import org.joda.time.DateTime;
026 import org.kuali.rice.core.api.delegation.DelegationType;
027 import org.kuali.rice.core.api.util.RiceConstants;
028 import org.kuali.rice.core.framework.persistence.jpa.OrmUtils;
029 import org.kuali.rice.kew.actionitem.ActionItem;
030 import org.kuali.rice.kew.actiontaken.ActionTakenValue;
031 import org.kuali.rice.kew.api.action.ActionRequest;
032 import org.kuali.rice.kew.api.action.ActionRequestPolicy;
033 import org.kuali.rice.kew.api.action.ActionRequestStatus;
034 import org.kuali.rice.kew.api.action.ActionRequestType;
035 import org.kuali.rice.kew.api.action.ActionTaken;
036 import org.kuali.rice.kew.api.action.RecipientType;
037 import org.kuali.rice.kew.api.util.CodeTranslator;
038 import org.kuali.rice.kew.dto.DTOConverter.RouteNodeInstanceLoader;
039 import org.kuali.rice.kew.engine.CompatUtils;
040 import org.kuali.rice.kew.engine.node.RouteNode;
041 import org.kuali.rice.kew.engine.node.RouteNodeInstance;
042 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
043 import org.kuali.rice.kew.rule.RuleBaseValues;
044 import org.kuali.rice.kew.rule.service.RuleServiceInternal;
045 import org.kuali.rice.kew.service.KEWServiceLocator;
046 import org.kuali.rice.kew.user.RoleRecipient;
047 import org.kuali.rice.kew.api.KewApiConstants;
048 import org.kuali.rice.kim.api.group.Group;
049 import org.kuali.rice.kim.api.identity.Person;
050 import org.kuali.rice.kim.api.identity.principal.Principal;
051 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
052
053 import javax.persistence.CascadeType;
054 import javax.persistence.Column;
055 import javax.persistence.Entity;
056 import javax.persistence.FetchType;
057 import javax.persistence.GeneratedValue;
058 import javax.persistence.Id;
059 import javax.persistence.JoinColumn;
060 import javax.persistence.ManyToOne;
061 import javax.persistence.NamedQueries;
062 import javax.persistence.NamedQuery;
063 import javax.persistence.OneToMany;
064 import javax.persistence.Table;
065 import javax.persistence.Transient;
066 import java.io.Serializable;
067 import java.sql.Timestamp;
068 import java.util.ArrayList;
069 import java.util.Arrays;
070 import java.util.Iterator;
071 import java.util.List;
072 /**
073 * Bean mapped to DB. Represents ActionRequest to a workgroup, user or role. Contains
074 * references to children/parent if a member of a graph
075 *
076 * @author Kuali Rice Team (rice.collab@kuali.org)
077 */
078 @Entity
079 @Table(name="KREW_ACTN_RQST_T")
080 //@Sequence(name="KREW_ACTN_RQST_S", property="actionRequestId")
081 @NamedQueries({
082 @NamedQuery(name="ActionRequestValue.FindByDocumentId", query="select arv from ActionRequestValue arv where arv.documentId = :documentId"),
083 @NamedQuery(name="ActionRequestValue.GetUserRequestCount", query="select count(arv) from ActionRequestValue arv where arv.documentId = :documentId and arv.recipientTypeCd = :recipientTypeCd and arv.principalId = :principalId and arv.currentIndicator = :currentIndicator"),
084 @NamedQuery(name="ActionRequestValue.FindActivatedByGroup", query="select count(arv) from ActionRequestValue arv where arv.groupId = :groupId and arv.currentIndicator = :currentIndicator and arv.status = :status"),
085 @NamedQuery(name="ActionRequestValue.FindAllByDocId", query="select arv from ActionRequestValue arv where arv.documentId = :documentId and arv.currentIndicator = :currentIndicator"),
086 @NamedQuery(name="ActionRequestValue.FindAllPendingByDocId", query="select arv from ActionRequestValue arv where arv.documentId = :documentId and arv.currentIndicator = :currentIndicator and (arv.status = :actionRequestStatus1 or arv.status = :actionRequestStatus2)"),
087 @NamedQuery(name="ActionRequestValue.FindAllRootByDocId", query="select arv from ActionRequestValue arv where arv.documentId = :documentId and arv.currentIndicator = :currentIndicator and arv.parentActionRequest is null"),
088 @NamedQuery(name="ActionRequestValue.FindByStatusAndDocId", query="select arv from ActionRequestValue arv where arv.documentId = :documentId and arv.currentIndicator = :currentIndicator and arv.status = :status"),
089 @NamedQuery(name="ActionRequestValue.FindPendingByActionRequestedAndDocId", query="select arv from ActionRequestValue arv where arv.documentId = :documentId and arv.currentIndicator = :currentIndicator and arv.actionRequested = :actionRequested and (arv.status = :actionRequestStatus1 or arv.status = :actionRequestStatus2)"),
090 @NamedQuery(name="ActionRequestValue.FindPendingByDocIdAtOrBelowRouteLevel", query="select arv from ActionRequestValue arv where arv.documentId = :documentId and arv.currentIndicator = :currentIndicator and arv.status <> :status and arv.routeLevel <= :routeLevel"),
091 @NamedQuery(name="ActionRequestValue.FindPendingRootRequestsByDocIdAtOrBelowRouteLevel", query="select arv from ActionRequestValue arv where arv.documentId = :documentId and arv.currentIndicator = :currentIndicator and arv.parentActionRequest is null and arv.status <> :status and routeLevel <= :routeLevel"),
092 @NamedQuery(name="ActionRequestValue.FindPendingRootRequestsByDocIdAtRouteLevel", query="select arv from ActionRequestValue arv where arv.documentId = :documentId and arv.currentIndicator = :currentIndicator and arv.parentActionRequest is null and arv.status <> :status and routeLevel = :routeLevel"),
093 @NamedQuery(name="ActionRequestValue.FindPendingRootRequestsByDocIdAtRouteNode", query="select arv from ActionRequestValue arv where arv.documentId = :documentId and arv.currentIndicator = :currentIndicator and arv.parentActionRequest is null and arv.nodeInstance.routeNodeInstanceId = :routeNodeInstanceId and (arv.status = :actionRequestStatus1 or arv.status = :actionRequestStatus2)"),
094 @NamedQuery(name="ActionRequestValue.FindPendingRootRequestsByDocumentType", query="select arv from ActionRequestValue arv where arv.documentId in (select drhv.documentId from DocumentRouteHeaderValue drhv where drhv.documentTypeId = :documentTypeId) and arv.currentIndicator = :currentIndicator and arv.parentActionRequest is null and (arv.status = :actionRequestStatus1 or arv.status = :actionRequestStatus2)"),
095 @NamedQuery(name="ActionRequestValue.FindRootRequestsByDocIdAtRouteNode", query="select arv from ActionRequestValue arv where arv.documentId = :documentId and arv.currentIndicator = :currentIndicator and arv.parentActionRequest is null and arv.nodeInstance.routeNodeInstanceId = :routeNodeInstanceId"),
096 @NamedQuery(name="ActionRequestValue.GetRequestGroupIds", query="select arv.groupId from ActionRequestValue arv where arv.documentId = :documentId and arv.currentIndicator = :currentIndicator and arv.recipientTypeCd = :recipientTypeCd"),
097 @NamedQuery(name="ActionRequestValue.FindByStatusAndGroupId", query="select arv from ActionRequestValue arv where arv.groupId = :groupId and arv.currentIndicator = :currentIndicator and arv.status = :status")
098 })
099 public class ActionRequestValue implements Serializable {
100
101 private static final long serialVersionUID = 8781414791855848385L;
102
103 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ActionRequestValue.class);
104
105 private static final String ACTION_CODE_RANK = "FKACB";//B is a hack for allowing blanket approves to count for approve and complete requests in findPreviousAction in ActionTakenService this is a hack and accounts for the -3 on compareActionCode
106 private static final String RECIPIENT_TYPE_RANK = "RWU";
107 private static final List DELEGATION_TYPE_RANK = Arrays.asList(new Object[]{DelegationType.SECONDARY, DelegationType.PRIMARY, null});
108
109 @Id
110 @GeneratedValue(generator="KREW_ACTN_RQST_S")
111 @GenericGenerator(name="KREW_ACTN_RQST_S",strategy="org.hibernate.id.enhanced.SequenceStyleGenerator",parameters={
112 @Parameter(name="sequence_name",value="KREW_ACTN_RQST_S"),
113 @Parameter(name="value_column",value="id")
114 })
115 @Column(name="ACTN_RQST_ID")
116 private String actionRequestId;
117 @Column(name="ACTN_RQST_CD")
118 private String actionRequested;
119 @Column(name="DOC_HDR_ID")
120 private String documentId;
121 @Column(name="STAT_CD")
122 private String status;
123 @Column(name="RSP_ID")
124 private String responsibilityId;
125 @Column(name="GRP_ID")
126 private String groupId;
127 @Column(name="RECIP_TYP_CD")
128 private String recipientTypeCd;
129 @Column(name="PRIO_NBR")
130 private Integer priority;
131 @Column(name="RTE_LVL_NBR")
132 private Integer routeLevel;
133 @Column(name="ACTN_TKN_ID", insertable=false, updatable=false)
134 private String actionTakenId;
135 @Column(name="DOC_VER_NBR")
136 private Integer docVersion = 1;
137 @Column(name="CRTE_DT")
138 private java.sql.Timestamp createDate;
139 @Column(name="RSP_DESC_TXT")
140 private String responsibilityDesc;
141 @Column(name="ACTN_RQST_ANNOTN_TXT")
142 private String annotation;
143 @Column(name="VER_NBR")
144 private Integer jrfVerNbr;
145 @Column(name="PRNCPL_ID")
146 private String principalId;
147 @Column(name="FRC_ACTN")
148 private Boolean forceAction;
149 @Column(name="PARNT_ID", insertable=false, updatable=false)
150 private String parentActionRequestId;
151 @Column(name="QUAL_ROLE_NM")
152 private String qualifiedRoleName;
153 @Column(name="ROLE_NM")
154 private String roleName;
155 @Column(name="QUAL_ROLE_NM_LBL_TXT")
156 private String qualifiedRoleNameLabel;
157 @Transient
158 private String displayStatus;
159 @Column(name="RULE_ID")
160 private String ruleBaseValuesId;
161
162 @Column(name="DLGN_TYP")
163 private String delegationTypeCode;
164 @Column(name="APPR_PLCY")
165 private String approvePolicy;
166
167 @ManyToOne(fetch=FetchType.EAGER)
168 @JoinColumn(name="PARNT_ID")
169 private ActionRequestValue parentActionRequest;
170 @Fetch(value = FetchMode.SELECT)
171 @OneToMany(mappedBy="parentActionRequest",cascade={CascadeType.PERSIST, CascadeType.MERGE},fetch=FetchType.EAGER)
172 private List<ActionRequestValue> childrenRequests = new ArrayList<ActionRequestValue>();
173 @ManyToOne(fetch=FetchType.EAGER)
174 @JoinColumn(name="ACTN_TKN_ID")
175 private ActionTakenValue actionTaken;
176 //@OneToMany(fetch=FetchType.LAZY,mappedBy="actionRequestId")
177 //private List<ActionItem> actionItems = new ArrayList<ActionItem>();
178 @Column(name="CUR_IND")
179 private Boolean currentIndicator = true;
180 @Transient
181 private String createDateString;
182
183 /* New Workflow 2.1 Field */
184 // The node instance at which this request was generated
185 @ManyToOne(fetch=FetchType.EAGER)
186 @JoinColumn(name="RTE_NODE_INSTN_ID")
187 private RouteNodeInstance nodeInstance;
188
189 @Column(name="RQST_LBL")
190 private String requestLabel;
191
192 @Transient
193 private boolean resolveResponsibility = true;
194 @Transient
195 private DocumentRouteHeaderValue routeHeader;
196 @Transient
197 private List<ActionItem> simulatedActionItems;
198
199 public ActionRequestValue() {
200 createDate = new Timestamp(System.currentTimeMillis());
201 }
202
203 //@PrePersist
204 public void beforeInsert(){
205 OrmUtils.populateAutoIncValue(this, KEWServiceLocator.getEntityManagerFactory().createEntityManager());
206 }
207
208 public Group getGroup() {
209 if (getGroupId() == null) {
210 LOG.error("Attempting to get a group with a blank group id");
211 return null;
212 }
213 return KimApiServiceLocator.getGroupService().getGroup(getGroupId());
214 }
215
216 public String getRouteLevelName() {
217 // this is for backward compatibility of requests which have not been converted
218 if (CompatUtils.isRouteLevelRequest(this)) {
219 int routeLevelInt = getRouteLevel();
220 if (routeLevelInt == KewApiConstants.EXCEPTION_ROUTE_LEVEL) {
221 return "Exception";
222 }
223
224 List<RouteNode> routeLevelNodes = CompatUtils.getRouteLevelCompatibleNodeList(KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId).getDocumentType());
225 if (!(routeLevelInt < routeLevelNodes.size())) {
226 return "Not Found";
227 }
228 return ((RouteNode)routeLevelNodes.get(routeLevelInt)).getRouteNodeName();
229 } else {
230 return (nodeInstance == null ? "Exception" : nodeInstance.getName());
231 }
232 }
233
234 public boolean isUserRequest() {
235 return principalId != null;
236 }
237
238 public Principal getPrincipal() {
239 if (getPrincipalId() == null) {
240 return null;
241 }
242 return KEWServiceLocator.getIdentityHelperService().getPrincipal(getPrincipalId());
243 }
244
245 public Person getPerson() {
246 if (getPrincipalId() == null) {
247 return null;
248 }
249 return KimApiServiceLocator.getPersonService().getPerson(getPrincipalId());
250 }
251
252 public String getDisplayName() {
253 if (isUserRequest()) {
254 Person person = getPerson();
255 if ( person != null ) {
256 return person.getName();
257 }
258 } else if (isGroupRequest()) {
259 Group group = getGroup();
260 if ( group != null ) {
261 return group.getName();
262 } else {
263 return getGroupId();
264 }
265 } else if (isRoleRequest()) {
266 return getRoleName();
267 }
268 return "";
269 }
270
271 public Recipient getRecipient() {
272 if (getPrincipalId() != null) {
273 return new KimPrincipalRecipient(getPrincipal());
274 } else if (getGroupId() != null){
275 return new KimGroupRecipient(getGroup());
276 } else {
277 return new RoleRecipient(this.getRoleName());
278 }
279 }
280
281 public boolean isPending() {
282 return ActionRequestStatus.INITIALIZED.getCode().equals(getStatus()) || ActionRequestStatus.ACTIVATED.getCode().equals(getStatus());
283 }
284
285 public String getStatusLabel() {
286 return CodeTranslator.getActionRequestStatusLabel(getStatus());
287 }
288
289 public String getActionRequestedLabel() {
290 if (StringUtils.isNotBlank(getRequestLabel())) {
291 return getRequestLabel();
292 }
293 return CodeTranslator.getActionRequestLabel(getActionRequested());
294 }
295
296 /**
297 * @return Returns the actionTaken.
298 */
299 public ActionTakenValue getActionTaken() {
300 return actionTaken;
301 }
302
303 /**
304 * @param actionTaken
305 * The actionTaken to set.
306 */
307 public void setActionTaken(ActionTakenValue actionTaken) {
308 this.actionTaken = actionTaken;
309 }
310
311 /**
312 * @return Returns the actionRequested.
313 */
314 public String getActionRequested() {
315 return actionRequested;
316 }
317
318 /**
319 * @param actionRequested
320 * The actionRequested to set.
321 */
322 public void setActionRequested(String actionRequested) {
323 this.actionRequested = actionRequested;
324 }
325
326 /**
327 * @return Returns the actionRequestId.
328 */
329 public String getActionRequestId() {
330 return actionRequestId;
331 }
332
333 /**
334 * @param actionRequestId
335 * The actionRequestId to set.
336 */
337 public void setActionRequestId(String actionRequestId) {
338 this.actionRequestId = actionRequestId;
339 }
340
341 /**
342 * @return Returns the actionTakenId.
343 */
344 public String getActionTakenId() {
345 return actionTakenId;
346 }
347
348 /**
349 * @param actionTakenId
350 * The actionTakenId to set.
351 */
352 public void setActionTakenId(String actionTakenId) {
353 this.actionTakenId = actionTakenId;
354 }
355
356 /**
357 * @return Returns the annotation.
358 */
359 public String getAnnotation() {
360 return annotation;
361 }
362
363 /**
364 * @param annotation
365 * The annotation to set.
366 */
367 public void setAnnotation(String annotation) {
368 this.annotation = annotation;
369 }
370
371 /**
372 * @return Returns the createDate.
373 */
374 public java.sql.Timestamp getCreateDate() {
375 return createDate;
376 }
377
378 /**
379 * @param createDate
380 * The createDate to set.
381 */
382 public void setCreateDate(java.sql.Timestamp createDate) {
383 this.createDate = createDate;
384 }
385
386 /**
387 * @return Returns the docVersion.
388 */
389 public Integer getDocVersion() {
390 return docVersion;
391 }
392
393 /**
394 * @param docVersion
395 * The docVersion to set.
396 */
397 public void setDocVersion(Integer docVersion) {
398 this.docVersion = docVersion;
399 }
400
401 public String getPrincipalId() {
402 return principalId;
403 }
404
405 public void setPrincipalId(String principalId) {
406 this.principalId = principalId;
407 }
408
409 /**
410 * @return Returns the forceAction.
411 */
412 public Boolean getForceAction() {
413 return forceAction;
414 }
415
416 /**
417 * @param forceAction
418 * The forceAction to set.
419 */
420 public void setForceAction(Boolean forceAction) {
421 this.forceAction = forceAction;
422 }
423
424 /**
425 * @return Returns the jrfVerNbr.
426 */
427 public Integer getJrfVerNbr() {
428 return jrfVerNbr;
429 }
430
431 /**
432 * @param jrfVerNbr
433 * The jrfVerNbr to set.
434 */
435 public void setJrfVerNbr(Integer jrfVerNbr) {
436 this.jrfVerNbr = jrfVerNbr;
437 }
438
439 /**
440 * @return Returns the priority.
441 */
442 public Integer getPriority() {
443 return priority;
444 }
445
446 /**
447 * @param priority
448 * The priority to set.
449 */
450 public void setPriority(Integer priority) {
451 this.priority = priority;
452 }
453
454 /**
455 * @return Returns the recipientTypeCd.
456 */
457 public String getRecipientTypeCd() {
458 return recipientTypeCd;
459 }
460
461 /**
462 * @param recipientTypeCd
463 * The recipientTypeCd to set.
464 */
465 public void setRecipientTypeCd(String recipientTypeCd) {
466 this.recipientTypeCd = recipientTypeCd;
467 }
468
469 /**
470 * @return Returns the responsibilityDesc.
471 */
472 public String getResponsibilityDesc() {
473 return responsibilityDesc;
474 }
475
476 /**
477 * @param responsibilityDesc
478 * The responsibilityDesc to set.
479 */
480 public void setResponsibilityDesc(String responsibilityDesc) {
481 this.responsibilityDesc = responsibilityDesc;
482 }
483
484 /**
485 * @return Returns the responsibilityId.
486 */
487 public String getResponsibilityId() {
488 return responsibilityId;
489 }
490
491 /**
492 * @param responsibilityId
493 * The responsibilityId to set.
494 */
495 public void setResponsibilityId(String responsibilityId) {
496 this.responsibilityId = responsibilityId;
497 }
498
499 /**
500 * @return Returns the documentId.
501 */
502 public String getDocumentId() {
503 return documentId;
504 }
505
506 public void setDocumentId(String documentId) {
507 this.documentId = documentId;
508 }
509
510 public Integer getRouteLevel() {
511 return routeLevel;
512 }
513
514 public void setRouteLevel(Integer routeLevel) {
515 this.routeLevel = routeLevel;
516 }
517
518 public String getStatus() {
519 return status;
520 }
521
522 public void setStatus(String status) {
523 this.status = status;
524 }
525
526 public String getGroupId() {
527 return groupId;
528 }
529
530 public void setGroupId(String groupId) {
531 this.groupId = groupId;
532 }
533
534 public boolean isInitialized() {
535 return ActionRequestStatus.INITIALIZED.getCode().equals(getStatus());
536 }
537
538 public boolean isActive() {
539 return ActionRequestStatus.ACTIVATED.getCode().equals(getStatus());
540 }
541
542 public boolean isApproveOrCompleteRequest() {
543 return KewApiConstants.ACTION_REQUEST_APPROVE_REQ.equals(getActionRequested()) || KewApiConstants.ACTION_REQUEST_COMPLETE_REQ.equals(getActionRequested());
544 }
545
546 public boolean isDone() {
547 return ActionRequestStatus.DONE.getCode().equals(getStatus());
548 }
549
550 public boolean isReviewerUser() {
551 return RecipientType.PRINCIPAL.getCode().equals(getRecipientTypeCd());
552 }
553
554 /**
555 * Determines whether the specified principalId is in the recipient graph of this action request
556 * @param principalId the principal id to check
557 * @return whether the specified principalId is in the recipient graph of this action request
558 */
559 public boolean isRecipientRoutedRequest(String principalId) {
560 //before altering this method it is used in checkRouteLogAuthentication
561 //don't break that method
562 if (principalId == null || "".equals(principalId)) {
563 return false;
564 }
565
566 boolean isRecipientInGraph = false;
567 if (isReviewerUser()) {
568 isRecipientInGraph = getPrincipalId().equals(principalId);
569 } else if (isGroupRequest()) {
570 Group group = getGroup();
571 if (group == null){
572 LOG.error("Was unable to retrieve workgroup " + getGroupId());
573 }
574 isRecipientInGraph = KimApiServiceLocator.getGroupService().isMemberOfGroup(principalId, group.getId());
575 }
576
577
578 for (ActionRequestValue childRequest : getChildrenRequests())
579 {
580 isRecipientInGraph = isRecipientInGraph || childRequest.isRecipientRoutedRequest(principalId);
581 }
582
583 return isRecipientInGraph;
584 }
585
586 public boolean isRecipientRoutedRequest(Recipient recipient) {
587 //before altering this method it is used in checkRouteLogAuthentication
588 //don't break that method
589 if (recipient == null) {
590 return false;
591 }
592
593 boolean isRecipientInGraph = false;
594 if (isReviewerUser()) {
595 if (recipient instanceof KimPrincipalRecipient) {
596 isRecipientInGraph = getPrincipalId().equals(((KimPrincipalRecipient) recipient).getPrincipalId());
597 } else if (recipient instanceof KimGroupRecipient){
598 isRecipientInGraph = KimApiServiceLocator.getGroupService().isMemberOfGroup(getPrincipalId(), ((KimGroupRecipient)recipient).getGroup().getId());
599 }
600
601 } else if (isGroupRequest()) {
602 Group group = getGroup();
603 if (group == null){
604 LOG.error("Was unable to retrieve workgroup " + getGroupId());
605 }
606 if (recipient instanceof KimPrincipalRecipient) {
607 KimPrincipalRecipient principalRecipient = (KimPrincipalRecipient)recipient;
608 isRecipientInGraph = KimApiServiceLocator.getGroupService().isMemberOfGroup(principalRecipient.getPrincipalId(), group.getId());
609 } else if (recipient instanceof KimGroupRecipient) {
610 isRecipientInGraph = ((KimGroupRecipient) recipient).getGroup().getId().equals(group.getId());
611 }
612 }
613
614
615 for (ActionRequestValue childRequest : getChildrenRequests())
616 {
617 isRecipientInGraph = isRecipientInGraph || childRequest.isRecipientRoutedRequest(recipient);
618 }
619
620 return isRecipientInGraph;
621 }
622
623 public boolean isGroupRequest(){
624 return RecipientType.GROUP.getCode().equals(getRecipientTypeCd());
625 }
626
627 public boolean isRoleRequest() {
628 return RecipientType.ROLE.getCode().equals(getRecipientTypeCd());
629 }
630
631 public boolean isAcknowledgeRequest() {
632 return KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ.equals(getActionRequested());
633 }
634
635 public boolean isApproveRequest() {
636 return KewApiConstants.ACTION_REQUEST_APPROVE_REQ.equals(getActionRequested());
637 }
638
639 public boolean isCompleteRequst() {
640 return KewApiConstants.ACTION_REQUEST_COMPLETE_REQ.equals(getActionRequested());
641 }
642
643 public boolean isFYIRequest() {
644 return KewApiConstants.ACTION_REQUEST_FYI_REQ.equals(getActionRequested());
645 }
646
647 /**
648 * Allows comparison of action requests to see which is greater responsibility. -1 : indicates code 1 is lesser responsibility than code 2 0 : indicates the same responsibility 1 : indicates code1 is greater responsibility than code 2 The priority of action requests is as follows: fyi < acknowledge < (approve == complete)
649 *
650 * @param code1
651 * @param code2
652 * @param completeAndApproveTheSame
653 * @return -1 if less than, 0 if equal, 1 if greater than
654 */
655 public static int compareActionCode(String code1, String code2, boolean completeAndApproveTheSame) {
656 int cutoff = Integer.MAX_VALUE;
657 if (completeAndApproveTheSame) {
658 // hacked so that APPROVE and COMPLETE are equal
659 cutoff = ACTION_CODE_RANK.length() - 3;
660 }
661 Integer code1Index = Math.min(ACTION_CODE_RANK.indexOf(code1), cutoff);
662 Integer code2Index = Math.min(ACTION_CODE_RANK.indexOf(code2), cutoff);
663 return code1Index.compareTo(code2Index);
664 }
665
666 /**
667 * Allows comparison of action requests to see which is greater responsibility. -1 : indicates type 1 is lesser responsibility than type 2 0 : indicates the same responsibility 1 : indicates type1 is greater responsibility than type 2
668 *
669 * @param type1
670 * @param type2
671 * @return -1 if less than, 0 if equal, 1 if greater than
672 */
673 public static int compareRecipientType(String type1, String type2) {
674 Integer type1Index = RECIPIENT_TYPE_RANK.indexOf(type1);
675 Integer type2Index = RECIPIENT_TYPE_RANK.indexOf(type2);
676 return type1Index.compareTo(type2Index);
677 }
678
679 public static int compareDelegationType(DelegationType type1, DelegationType type2) {
680 Integer type1Index = DELEGATION_TYPE_RANK.indexOf(type1);
681 Integer type2Index = DELEGATION_TYPE_RANK.indexOf(type2);
682 return type1Index.compareTo(type2Index);
683 }
684
685 public List<ActionItem> getActionItems() {
686 if (this.simulatedActionItems == null || this.simulatedActionItems.isEmpty()) {
687 return (List<ActionItem>) KEWServiceLocator.getActionListService().findByActionRequestId(actionRequestId);
688 } else {
689 return this.simulatedActionItems;
690 }
691 }
692
693 public List<ActionItem> getSimulatedActionItems() {
694 if (this.simulatedActionItems == null) {
695 this.simulatedActionItems = new ArrayList<ActionItem>();
696 }
697 return this.simulatedActionItems;
698 }
699
700 public void setSimulatedActionItems(List<ActionItem> simulatedActionItems) {
701 this.simulatedActionItems = simulatedActionItems;
702 }
703
704 public Boolean getCurrentIndicator() {
705 return currentIndicator;
706 }
707
708 public void setCurrentIndicator(Boolean currentIndicator) {
709 this.currentIndicator = currentIndicator;
710 }
711
712 public String getParentActionRequestId() {
713 return parentActionRequestId;
714 }
715
716 public void setParentActionRequestId(String parentActionRequestId) {
717 this.parentActionRequestId = parentActionRequestId;
718 }
719
720 public ActionRequestValue getParentActionRequest() {
721 return parentActionRequest;
722 }
723
724 public void setParentActionRequest(ActionRequestValue parentActionRequest) {
725 this.parentActionRequest = parentActionRequest;
726 }
727
728 public List<ActionRequestValue> getChildrenRequests() {
729 return childrenRequests;
730 }
731
732 public void setChildrenRequests(List<ActionRequestValue> childrenRequests) {
733 this.childrenRequests = childrenRequests;
734 }
735
736 public String getQualifiedRoleName() {
737 return qualifiedRoleName;
738 }
739
740 public void setQualifiedRoleName(String roleName) {
741 this.qualifiedRoleName = roleName;
742 }
743
744 public DelegationType getDelegationType() {
745 return DelegationType.fromCode(delegationTypeCode);
746 }
747
748 public void setDelegationType(DelegationType delegationPolicy) {
749 this.delegationTypeCode = delegationPolicy == null ? null : delegationPolicy.getCode();
750 }
751
752
753 public String getDelegationTypeCode() {
754 return delegationTypeCode;
755 }
756
757 public void setDelegationTypeCode(String delegationTypeCode) {
758 this.delegationTypeCode = delegationTypeCode;
759 }
760
761 public String getRoleName() {
762 return roleName;
763 }
764
765 public void setRoleName(String roleName) {
766 this.roleName = roleName;
767 }
768
769 public String getApprovePolicy() {
770 return approvePolicy;
771 }
772
773 public void setApprovePolicy(String requestType) {
774 this.approvePolicy = requestType;
775 }
776
777 public boolean getHasApprovePolicy() {
778 return getApprovePolicy() != null;
779 }
780
781 public boolean isDeactivated() {
782 return ActionRequestStatus.DONE.getCode().equals(getStatus());
783 }
784
785 public boolean hasParent() {
786 return getParentActionRequest() != null;
787 }
788
789 public boolean hasChild(ActionRequestValue actionRequest) {
790 if (actionRequest == null)
791 return false;
792 String actionRequestId = actionRequest.getActionRequestId();
793 for (Iterator<ActionRequestValue> iter = getChildrenRequests().iterator(); iter.hasNext();) {
794 ActionRequestValue childRequest = iter.next();
795 if (childRequest.equals(actionRequest) || (actionRequestId != null && actionRequestId.equals(childRequest.getActionRequestId()))) {
796 return true;
797 }
798 }
799 return false;
800 }
801
802 public String getDisplayStatus() {
803 return displayStatus;
804 }
805
806 public void setDisplayStatus(String displayStatus) {
807 this.displayStatus = displayStatus;
808 }
809
810 public String getQualifiedRoleNameLabel() {
811 return qualifiedRoleNameLabel;
812 }
813
814 public void setQualifiedRoleNameLabel(String qualifiedRoleNameLabel) {
815 this.qualifiedRoleNameLabel = qualifiedRoleNameLabel;
816 }
817
818 public String getCreateDateString() {
819 if (createDateString == null || createDateString.trim().equals("")) {
820 return RiceConstants.getDefaultDateFormat().format(getCreateDate());
821 } else {
822 return createDateString;
823 }
824 }
825
826 public void setCreateDateString(String createDateString) {
827 this.createDateString = createDateString;
828 }
829
830 public RouteNodeInstance getNodeInstance() {
831 return nodeInstance;
832 }
833
834 public String getPotentialNodeName() {
835 return (getNodeInstance() == null ? "" : getNodeInstance().getName());
836 }
837
838 public void setNodeInstance(RouteNodeInstance nodeInstance) {
839 this.nodeInstance = nodeInstance;
840 }
841
842 public String getRecipientTypeLabel() {
843 return RecipientType.fromCode(getRecipientTypeCd()).getLabel();
844 }
845
846 public RuleBaseValues getRuleBaseValues(){
847 if(ruleBaseValuesId != null){
848 return getRuleService().findRuleBaseValuesById(ruleBaseValuesId);
849 }
850 return null;
851 }
852 public String getRuleBaseValuesId() {
853 return ruleBaseValuesId;
854 }
855
856 public void setRuleBaseValuesId(String ruleBaseValuesId) {
857 this.ruleBaseValuesId = ruleBaseValuesId;
858 }
859
860 private RuleServiceInternal getRuleService() {
861 return (RuleServiceInternal) KEWServiceLocator.getService(KEWServiceLocator.RULE_SERVICE);
862 }
863
864 public boolean isPrimaryDelegator() {
865 boolean primaryDelegator = false;
866 for (Iterator<ActionRequestValue> iter = childrenRequests.iterator(); iter.hasNext();) {
867 ActionRequestValue childRequest = iter.next();
868 primaryDelegator = DelegationType.PRIMARY.equals(childRequest.getDelegationType()) || primaryDelegator;
869 }
870 return primaryDelegator;
871 }
872
873 /**
874 * Used to get primary delegate names on route log in the 'Requested Of' section so primary delegate requests
875 * list the delegate and not the delegator as having the request 'IN ACTION LIST'. This method doesn't recurse
876 * and therefore assume an AR structure.
877 *
878 * @return primary delgate requests
879 */
880 public List<ActionRequestValue> getPrimaryDelegateRequests() {
881 List<ActionRequestValue> primaryDelegateRequests = new ArrayList<ActionRequestValue>();
882 for (ActionRequestValue childRequest : childrenRequests)
883 {
884 if (DelegationType.PRIMARY.equals(childRequest.getDelegationType()))
885 {
886 if (childRequest.isRoleRequest())
887 {
888 for (ActionRequestValue actionRequestValue : childRequest.getChildrenRequests())
889 {
890 primaryDelegateRequests.add(actionRequestValue);
891 }
892 } else
893 {
894 primaryDelegateRequests.add(childRequest);
895 }
896 }
897 }
898 return primaryDelegateRequests;
899 }
900
901 public boolean isAdHocRequest() {
902 return KewApiConstants.ADHOC_REQUEST_RESPONSIBILITY_ID.equals(getResponsibilityId());
903 }
904
905 public boolean isGeneratedRequest() {
906 return KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID.equals(getResponsibilityId());
907 }
908
909 public boolean isExceptionRequest() {
910 return KewApiConstants.EXCEPTION_REQUEST_RESPONSIBILITY_ID.equals(getResponsibilityId());
911 }
912
913 public boolean isRouteModuleRequest() {
914 // FIXME: KULRICE-5201 switched rsp_id to a varchar, so the comparison below is no longer valid
915 // return getResponsibilityId() > 0;
916 // TODO: KULRICE-5329 Verify that this code below makes sense
917 return getResponsibilityId() != null && !KewApiConstants.SPECIAL_RESPONSIBILITY_ID_SET.contains(getResponsibilityId());
918 }
919
920 public String toString() {
921 return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
922 .append("actionRequestId", actionRequestId)
923 .append("actionRequested", actionRequested)
924 .append("documentId", documentId)
925 .append("status", status)
926 .append("responsibilityId", responsibilityId)
927 .append("groupId", groupId)
928 .append("recipientTypeCd", recipientTypeCd)
929 .append("priority", priority)
930 .append("routeLevel", routeLevel)
931 .append("actionTakenId", actionTakenId)
932 .append("docVersion", docVersion)
933 .append("createDate", createDate)
934 .append("responsibilityDesc", responsibilityDesc)
935 .append("annotation", annotation)
936 .append("jrfVerNbr", jrfVerNbr)
937 .append("principalId", principalId)
938 .append("forceAction", forceAction)
939 .append("parentActionRequestId", parentActionRequestId)
940 .append("qualifiedRoleName", qualifiedRoleName)
941 .append("roleName", roleName)
942 .append("qualifiedRoleNameLabel", qualifiedRoleNameLabel)
943 .append("displayStatus", displayStatus)
944 .append("ruleBaseValuesId", ruleBaseValuesId)
945 .append("delegationType", delegationTypeCode)
946 .append("approvePolicy", approvePolicy)
947 .append("actionTaken", actionTaken)
948 .append("currentIndicator", currentIndicator)
949 .append("createDateString", createDateString)
950 .append("nodeInstance", nodeInstance).toString();
951 }
952
953 public String getRequestLabel() {
954 return this.requestLabel;
955 }
956
957 public void setRequestLabel(String requestLabel) {
958 this.requestLabel = requestLabel;
959 }
960
961 public String getGroupName() {
962 return KimApiServiceLocator.getGroupService().getGroup(this.groupId).getName();
963 }
964
965 /**
966 * @return the resolveResponsibility
967 */
968 public boolean getResolveResponsibility() {
969 return this.resolveResponsibility;
970 }
971
972 /**
973 * @param resolveResponsibility the resolveResponsibility to set
974 */
975 public void setResolveResponsibility(boolean resolveResponsibility) {
976 this.resolveResponsibility = resolveResponsibility;
977 }
978
979 public DocumentRouteHeaderValue getRouteHeader() {
980 if (this.routeHeader == null && this.documentId != null) {
981 this.routeHeader = KEWServiceLocator.getRouteHeaderService().getRouteHeader(this.documentId);
982 }
983 return this.routeHeader;
984 }
985
986 public void setRouteHeader(DocumentRouteHeaderValue routeHeader) {
987 this.routeHeader = routeHeader;
988 }
989
990 public static ActionRequest to(ActionRequestValue actionRequestBo) {
991 if (actionRequestBo == null) {
992 return null;
993 }
994 return createActionRequestBuilder(actionRequestBo).build();
995 }
996
997 private static ActionRequest.Builder createActionRequestBuilder(ActionRequestValue actionRequestBo) {
998 ActionRequest.Builder builder = ActionRequest.Builder.create(actionRequestBo.getActionRequestId(),
999 ActionRequestType.fromCode(actionRequestBo.getActionRequested()),
1000 ActionRequestStatus.fromCode(actionRequestBo.getStatus()),
1001 actionRequestBo.getResponsibilityId(),
1002 actionRequestBo.getDocumentId(),
1003 RecipientType.fromCode(actionRequestBo.getRecipientTypeCd()));
1004 if (actionRequestBo.getActionTaken() != null) {
1005 builder.setActionTaken(ActionTaken.Builder.create(ActionTakenValue.to(actionRequestBo.getActionTaken())));
1006 }
1007 builder.setAnnotation(actionRequestBo.getAnnotation());
1008 builder.setCurrent(actionRequestBo.getCurrentIndicator().booleanValue());
1009 builder.setDateCreated(new DateTime(actionRequestBo.getCreateDate().getTime()));
1010 if (actionRequestBo.getDelegationType() != null) {
1011 builder.setDelegationType(actionRequestBo.getDelegationType());
1012 }
1013 builder.setForceAction(actionRequestBo.getForceAction().booleanValue());
1014 builder.setGroupId(actionRequestBo.getGroupId());
1015 builder.setNodeName(actionRequestBo.getPotentialNodeName());
1016 if (actionRequestBo.getParentActionRequestId() != null) {
1017 builder.setParentActionRequestId(actionRequestBo.getParentActionRequestId());
1018 }
1019 builder.setPrincipalId(actionRequestBo.getPrincipalId());
1020 if (actionRequestBo.getPriority() == null) {
1021 builder.setPriority(KewApiConstants.ACTION_REQUEST_DEFAULT_PRIORITY);
1022 } else {
1023 builder.setPriority(actionRequestBo.getPriority().intValue());
1024 }
1025 if (actionRequestBo.getRouteLevel() == null ) {
1026 builder.setRouteLevel(0);
1027 } else {
1028 builder.setRouteLevel(actionRequestBo.getRouteLevel().intValue());
1029 }
1030 builder.setQualifiedRoleName(actionRequestBo.getQualifiedRoleName());
1031 builder.setQualifiedRoleNameLabel(actionRequestBo.getQualifiedRoleNameLabel());
1032 builder.setRequestLabel(actionRequestBo.getRequestLabel());
1033 if (!StringUtils.isBlank(actionRequestBo.getApprovePolicy())) {
1034 builder.setRequestPolicy(ActionRequestPolicy.fromCode(actionRequestBo.getApprovePolicy()));
1035 }
1036 builder.setResponsibilityDescription(actionRequestBo.getResponsibilityDesc());
1037 builder.setRoleName(actionRequestBo.getRoleName());
1038 if (actionRequestBo.getNodeInstance() != null) {
1039 builder.setRouteNodeInstanceId(actionRequestBo.getNodeInstance().getRouteNodeInstanceId());
1040 }
1041
1042 List<ActionRequest.Builder> childRequests = new ArrayList<ActionRequest.Builder>();
1043 if (actionRequestBo.getChildrenRequests() != null) {
1044 for (ActionRequestValue childActionRequestBo : actionRequestBo.getChildrenRequests()) {
1045 childRequests.add(createActionRequestBuilder(childActionRequestBo));
1046 }
1047 }
1048 builder.setChildRequests(childRequests);
1049 return builder;
1050 }
1051
1052 /**
1053 * TODO - this javadoc copied from DTOConverter, needs to be updated!
1054 *
1055 * Converts an ActionRequestVO to an ActionRequest. The ActionRequestDTO passed in must be the root action request in the
1056 * graph, otherwise an IllegalArgumentException is thrown. This is to avoid potentially sticky issues with circular
1057 * references in the conversion. NOTE: This method's primary purpose is to convert ActionRequestVOs returned from a
1058 * RouteModule. Incidentally, the DTO's returned from the route module will be lacking some information (like the node
1059 * instance) so no attempts are made to convert this data since further initialization is handled by a higher level
1060 * component (namely ActionRequestService.initializeActionRequestGraph).
1061 */
1062 public static ActionRequestValue from(ActionRequest actionRequest) {
1063 return ActionRequestValue.from(actionRequest, null);
1064 }
1065
1066 /**
1067 * Converts an ActionRequestVO to an ActionRequest. The ActionRequestDTO passed in must be the root action request in the
1068 * graph, otherwise an IllegalArgumentException is thrown. This is to avoid potentially sticky issues with circular
1069 * references in the conversion.
1070 * @param routeNodeInstanceLoader a service that will provide routeNodeInstanceS based on their IDs.
1071 */
1072 public static ActionRequestValue from(ActionRequest actionRequest,
1073 RouteNodeInstanceLoader routeNodeInstanceLoader) {
1074 return convertActionRequest(actionRequest, null, routeNodeInstanceLoader);
1075 }
1076
1077 private static ActionRequestValue convertActionRequest(ActionRequest actionRequest, ActionRequestValue parentActionRequestBo,
1078 RouteNodeInstanceLoader routeNodeInstanceLoader) {
1079 if (actionRequest == null) {
1080 return null;
1081 }
1082 ActionRequestValue actionRequestBo = new ActionRequestFactory().createBlankActionRequest();
1083 populateActionRequest(actionRequestBo, actionRequest, routeNodeInstanceLoader);
1084 if (parentActionRequestBo != null) {
1085 actionRequestBo.setParentActionRequest(parentActionRequestBo);
1086 actionRequestBo.setParentActionRequestId(parentActionRequestBo.getActionRequestId());
1087 }
1088 if (actionRequest.getChildRequests() != null) {
1089 for (ActionRequest childRequest : actionRequest.getChildRequests()) {
1090 actionRequestBo.getChildrenRequests().add(ActionRequestValue.convertActionRequest(childRequest, actionRequestBo, routeNodeInstanceLoader));
1091 }
1092 }
1093 return actionRequestBo;
1094 }
1095
1096 /**
1097 * This method converts everything except for the parent and child requests
1098 */
1099 private static void populateActionRequest(ActionRequestValue actionRequestBo, ActionRequest actionRequest,
1100 RouteNodeInstanceLoader routeNodeInstanceLoader) {
1101
1102 actionRequestBo.setActionRequested(actionRequest.getActionRequested().getCode());
1103 if (!StringUtils.isBlank(actionRequest.getId())) {
1104 actionRequestBo.setActionRequestId(actionRequest.getId());
1105 }
1106
1107 if (actionRequest.getActionTaken() != null) {
1108 // actionRequestBo.setActionTaken(ActionTakenValue.from(actionRequest.getActionTaken()));
1109 if (!StringUtils.isBlank(actionRequest.getActionTaken().getId())) {
1110 actionRequestBo.setActionTakenId(actionRequest.getActionTaken().getId());
1111 }
1112 }
1113 actionRequestBo.setAnnotation(actionRequest.getAnnotation());
1114 if (actionRequest.getRequestPolicy() != null) {
1115 actionRequestBo.setApprovePolicy(actionRequest.getRequestPolicy().getCode());
1116 }
1117 actionRequestBo.setCreateDate(new Timestamp(actionRequest.getDateCreated().getMillis()));
1118 actionRequestBo.setCurrentIndicator(actionRequest.isCurrent());
1119 if (actionRequest.getDelegationType() != null) {
1120 actionRequestBo.setDelegationType(actionRequest.getDelegationType());
1121 }
1122 //actionRequestBo.setDocVersion(actionRequest.?);
1123 actionRequestBo.setForceAction(actionRequest.isForceAction());
1124 actionRequestBo.setPriority(actionRequest.getPriority());
1125 actionRequestBo.setRouteLevel(actionRequest.getRouteLevel());
1126 actionRequestBo.setQualifiedRoleName(actionRequest.getQualifiedRoleName());
1127 actionRequestBo.setQualifiedRoleNameLabel(actionRequest.getQualifiedRoleNameLabel());
1128 actionRequestBo.setRecipientTypeCd(actionRequest.getRecipientType().getCode());
1129 actionRequestBo.setResponsibilityDesc(actionRequest.getResponsibilityDescription());
1130 if (!StringUtils.isBlank(actionRequest.getResponsibilityId())) {
1131 actionRequestBo.setResponsibilityId(actionRequest.getResponsibilityId());
1132 }
1133 actionRequestBo.setRoleName(actionRequest.getRoleName());
1134 String documentId = actionRequest.getDocumentId();
1135 if (documentId != null) {
1136 actionRequestBo.setDocumentId(documentId);
1137 actionRequestBo.setRouteHeader(KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId));
1138 }
1139
1140 actionRequestBo.setStatus(actionRequest.getStatus().getCode());
1141 actionRequestBo.setPrincipalId(actionRequest.getPrincipalId());
1142 actionRequestBo.setGroupId(actionRequest.getGroupId());
1143
1144 if (routeNodeInstanceLoader != null && !StringUtils.isBlank(actionRequest.getRouteNodeInstanceId())) {
1145 actionRequestBo.setNodeInstance(routeNodeInstanceLoader.load(actionRequest.getRouteNodeInstanceId()));
1146 }
1147 }
1148
1149 }