4 Replies Latest reply on Apr 4, 2014 8:42 AM by Sergey Kornilov

    creating variable number of human tasks in jBPM5.4.0.Final

    Arif Mohammed Novice

      Hi,

       

         I am using jBPM5.4.Final and I would like to know whether the following is possible or not.

       

         As of now I know we can create any number of human tasks say ht1, ht2, ht3 ... and I could define the process in such a way that until and unless all the human tasks are completed the process can't move further. I would like to achieve the same thing but instead of defining the fixed number of human tasks in process definition I would like to create those human tasks at run-time based on some data in DB. Say if you take the refund approval process/leave approval process for an employee where it requires approval by all superiors of that employee in the hierarchy.

       

            I am wondering can we achieve it in jBPM and if so how ?

        • 1. Re: creating variable number of human tasks in jBPM5.4.0.Final
          Arif Mohammed Novice

          Does any one has encountered such a scenario ? I believe this should be the common use case. I am thinking of creating a rule task to create variable number of human tasks, but I am not getting how can I make the rule task to wait until I receive approvals from all the human tasks. Any idea will be appreciated.

          • 3. Re: creating variable number of human tasks in jBPM5.4.0.Final
            Arif Mohammed Novice

            Hi Sergey,

                 Thank you for pointing me to the right direction. Before I recieved your response I have implemented by using signal and rule node(Attachement: Approval-Process) I was programitically creating tasks in tasks server and waiting for them to get completed. However doing it by using "multi instances sub-process" is clean (Attachment: Approval-Process2) but I see one issue here which is explained below.

               1) My goal is to automatically assign each of the created tasks to respective users and each of those users belong to a group. So what I did is, I have assigned GroupId and ActorId to each task by using process variables #{group} and #{reviewerId} respectively (Attachment : Human-Task-Definition). By doing this way tasks are not assigned to respective users and they are in Ready state possibly because of 2 owners, one is group and the other is the user itself. Following are the records created in task server DB

            PEOPLEASSIGNMENTS_POTOOWNERS

            TASK_ID     ENTITY_ID

            1315             APPROVER_GROUP

            1315             ARIF

            1316             APPROVER_GROUP

            1316             GEORGE

            TASK

            TASK_ID     STATUS  ACTUAL_OWNER_ID   CREATED_BY

            1315              Ready     null                                  ARIF

            1316              Ready     null                                  GEORGE

             

               If I remove the GroupId assignment and have just ActorId assignment, task is assigned properly and the DB rows are as follows. I know that if we have multiple owners assigned to the task it will go into Ready state so that any of those assigned users can pick it up. Here that is not the case it is one user and one group it should have directly assigned to that user and should have went to Reserved state.

             

            PEOPLEASSIGNMENTS_POTOOWNERS

            TASK_ID       ENTITY_ID

            1315               ARIF

            1316               GEORGE

            TASK

            TASK_ID      STATUS     ACTUAL_OWNER_ID    CREATED_BY

            1315               Reserved   ARIF                                  null

            1316                Reserved  GEORGE                          null
            Approval-Process.png

            Approval-Process-2.png

            Capture.PNG

            • 4. Re: Re: creating variable number of human tasks in jBPM5.4.0.Final
              Sergey Kornilov Newbie
              /**
              
                   * This method will potentially assign the actual owner of this TaskData and set the status
                   * of the data.
                   * <li>If there is only 1 potential owner, and it is a <code>User</code>, that will become the actual
                   * owner of the TaskData and the status will be set to <code>Status.Reserved</code>.</li>
                   * <li>f there is only 1 potential owner, and it is a <code>Group</code>,  no owner will be assigned
                   * and the status will be set to <code>Status.Ready</code>.</li>
                   * <li>If there are more than 1 potential owners, the status will be set to <code>Status.Ready</code>.</li>
                   * <li>otherwise, the task data will be unchanged</li>
                   *
                   * @param potentialOwners - list of potential owners
                   * @return current status of task data
                   */
                  public Status assignOwnerAndStatus(List<OrganizationalEntity> potentialOwners) {
                      if (getStatus() != Status.Created) {
                          throw new IllegalTaskStateException("Can only assign task owner if status is Created!");
                      }
              
                      Status assignedStatus = null;
              
                      if (potentialOwners.size() == 1) {
                          // if there is a single potential owner, assign and set status to Reserved
                          OrganizationalEntity potentialOwner = potentialOwners.get(0);
                          // if there is a single potential user owner, assign and set status to Reserved
                          if (potentialOwner instanceof User) {
                              setActualOwner((User) potentialOwner);
              
                              assignedStatus = Status.Reserved;
                          }
                          //If there is a group set as potentialOwners, set the status to Ready ??
                          if (potentialOwner instanceof Group) {
              
                              assignedStatus = Status.Ready;
                          }
                      } else if (potentialOwners.size() > 1) {
                          // multiple potential owners, so set to Ready so one can claim.
                          assignedStatus = Status.Ready;
                      } else {
                          //@TODO we have no potential owners
                      }
              
                      if (assignedStatus != null) {
                          setStatus(assignedStatus);
                      } else {
                          // status wasn't assigned, so just return the currrent status
                          assignedStatus = getStatus();
                      }
              
                      return assignedStatus;
                  }
              

              This function assign owner to task. But jBPM not store link between User and Group.(if I'm not mistaken)


              This link determined when you set UserGroupCallback().

               

              UserGroupCallbackManager.getInstance().setCallback(new UserGroupCallback(){...});

               

              public interface UserGroupCallback {
              
                  /**
                   * Resolves existence of user id.
                   * @param userId    the user id assigned to the task
                   * @return true if userId exists, false otherwise.
                   */
                  boolean existsUser(String userId);
              
                  
              
                  /**
                   * Resolves existence of group id.
                   * @param groupId    the group id assigned to the task
                   * @return true if groupId exists, false otherwise.
                   */
              
                  boolean existsGroup(String groupId);
              
                  
              
                  /**
                   * Returns list of group ids for specified user id.
                   * @param userId    the user id assigned to the task
                   * @param groupIds  list of group ids assigned to the task
                   * @param allExistingGroupIds    list of all currently known group ids
                   * @return List of group ids.
                   */
              
                  List<String> getGroupsForUser(String userId, List<String> groupIds, List<String> allExistingGroupIds);
              
              }
              

               

              So, you can try add TaskEventListener and override method taskCreated(). where you can claim task to User