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