Friday, December 11, 2009

Implementing Parallel Approvals In LiveCycle




Background


I wrote this a few years ago and implemented this on version 7.2, but I figured it still might be of interest (even though ES2 has some parallel routing features)...

I was working on a project which involved creating an orchestration for a procurement process. Like many approval processes, the orchestration involved routing the form to various levels of management and supervisors depending on the dollar amount of the item being approved.


One of the characteristics of their process was that the initiator, and various other people who were involved in the process needed the ability to add as many additional approvers (from their LDAP) as they deemed necessary. They had no limit on the amount of approvers needed at a certain step, and it was solely up to the discretion of the individual at that step. There were mandatory approvals needed (e.g. supervisor), but other approvers could be added dynamically within the process. At a certain step there could be one approver in one instance, and ten approvers when the next form was being filled out.


I needed to come up with a method to allow a dynamic number of approvers. These approvers could be selected in the form by the initiator, or by other approvers in the process.


As is commonly requested, the implementation required that the final document display various qualities of each approval such as:



  • approval comments

  • approval date

  • approval status (i.e. approved or rejected/returned)

  • approver name


Solution Overview


The solution has two components. The first component is an individual approval
orchestration which routes the form to an individual and stores the approval
comments, date, status, and the name of the approver. The second component is for parallel
approval. It makes repeated calls to the individual approval orchestration while recursively calling itself.




Individual Approval Orchestration




The individual approval orchestration takes as input the userid of the individual to whom the form needs to be routed. It outputs the approval characteristics (approver name, date, comments, approval status).

The following diagram depicts the steps utilized in the individual approval orchestration…



Check For Users
If the userid contains a valid user assign the approval task them


ApproveOrReject
When the user opens the task, they are allowed to approve or reject the form. They are also allowed to add approval comments to a field within the form. The approval date is taken from the server and stored.


Approve / Reject
The approval or rejection status is stored


Set Comment
The comments are taken from the form and stored in a temporary variable


Create Output String
This step combines all of the approval characteristics into a single delimited string (e.g. “Wayne Carter~12/12/2008~approved~I approve this request”). In LiveCycle ES this might be better achieved by using a map variable, or some other method.This step basically provides a single item to return to the calling orchestration.



Parallel Approval Orchestration


The parallel approval orchestration takes as input a list of approvers to whom the form needs to be routed. It outputs a list of all of the individual approval characteristics (approver name, date, comments, approval status).

The following diagram depicts the parallel approval orchestration:



Parallel Approval Orchestration



The orchestration first checks for the number of approvers in the list. If there is only one approver (or none) it then takes a route that calls the individual approval orchestration for that approver. If there are multiple approvers in the list the orchestration calls a branch which will do two key things in parallel. The first part of the branch calls the individual approval orchestration on the first approver in the list. The second part of the branch calls the parallel approval orchestration (this same orchestration) passing in the list of the approvers with the first aprover removed.




For example, if parallel approver was called with the following list of users:



wcarter~jcarter~uraymond~mcarey



it would call the individual approval orchestration passing in wcarter, and then call the parallel approval orchestration passing in the following list:




jcarter~uraymond~mcarey



This would repeat until the parallel approval orchestration was called with the list:



mcarey



At this point, it would not go into the branch, but take the bottom route and complete.




Each call to parallel approval will run in parallel. The branch waits for all of the processes to complete before continuing. It then combines the approval characteristics from all of the calls into one list. This can be a delimited string, list of maps, or however you choose to implement.




CheckNumUsers
This step determines if the termination condition of the recurring process has been met. It determines whether to take the route for an individual user or for multiple users.

CheckForUser
This step determines whether there is a single approver or none.



LastApprover
This calls the individual approval orchestration with the single approver. Note that the output variables are set to the output of the individual approver orchestration. The output of the parallel approver orchestration will be the results from the individual approval call.




No More Users
This step does not perform any activity and the orchestration ends here returning null for all parameters.



ApproveInParallel
This branch calls two orchestrations in parallel and waits for them both to finish. It first calls
the individual approver orchestration passing in the first approver in the list. In parallel with that, it calls the parallel approver orchestration with the remaining approvers on the list. The branch will wait for the RemaindingApprovers task to finish and then the outputs will get combined.



CurrentApprover
This step calls the individual approver orchestration passing in the first approver in the list.




RemaindingApprovers
This step makes a call to the parallel approval orchestration passing in the list of approvers minus the first approver.



CombineComments
This step combines all of the approval characteristics and combines them into a single variable (or however you choose to implement) and set them to the output variable.




Calling the Parallel Approval Orchestration



When calling the parallel approval orchestration, you will pass it a list of approvers, and you’ll get back a list of approval characteristics (approver name, comments, date, and approval status).


The following diagram shows an example of where the parallel approval orchestration was called as a sub-process (service). The “Added Approvers” step below is the instantiation of the parallel approval orchestration.





Example of Using the Output of the Parallel Approval




In my implementation, I took the output of parallel approval and put it into a hidden field on the form. When the form was opened, I populated some dynamically created subforms. I had a separate subform for each approval type. The subform would repeat for every set of approval information.




For example, the Development Test Approval section would repeat for every approver that was in that list, and the Approval section would repeat for every approver that was in that list. The comments section would expand to multiple rows if necessary.




No comments:

Post a Comment