Wednesday, 31 July 2013

Conditional Transition in Liferay Workflow using default Kaleo Engine

Conditional Transition in Liferay Workflow using default Kaleo Engine



Loads of material is available on Liferay forums and Liferay WIKI on Workflow in Liferay. I do not intend to play  gimmick by replicating here. I intend to only illustrate how to do conditional transition. Before moving ahead with this blog entry of mine, please go through http://www.liferay.com/documentation/liferay-portal/6.1/user-guide/-/ai/creating-process-definitions first.
Use Case: There is single-approver-definition by default bundled with kaleo workflow engine in Liferay 6.x This default definition worked just fine for my client but with the only difference that if the content is created by a user having Administrator role, then it must NOT be kept pending for approval instead must automatically be considered as approved. And if any user with any role other than Administrator creates the content then it must go through the normal approval process i.e. review and then either reject or approve.
I must mention here that my knowledge of UML (especially statechart & activity diagrams) really helped when I had initially started with BPMN. Well without any further ado, let me illustrate how to achieve the above mentioned requirement.
Create a copy of single-approver-definition called my-workflow and add the following immediately after first state node named as "created"
<condition>
        <name>checkuser</name>
        <description>Checking whether the user is a portal admin</description>
        <script>
            <![CDATA[
           
                import com.liferay.portal.model.User;
                import com.liferay.portal.kernel.workflow.WorkflowConstants;
                import com.liferay.portal.service.UserLocalServiceUtil;
                import com.liferay.portal.model.Role;
                import java.util.List;
               
               
                String userId = (String) workflowContext.get(WorkflowConstants.CONTEXT_USER_ID);
                User user = UserLocalServiceUtil.getUser(Long.valueOf(userId));
                returnValue  = "review";
       
                 List<Role>  roles =  user.getRoles();
                 for (Role r : roles) {
                    println r.getName();
                    if (r.getName().equals("Administrator")) {
                      println "Setting approve for user :  " + user.getFirstName();
                      returnValue = "approve";
                      break;
                    }
                 }
           
                 println user.getFirstName() + " transitioning to : " + returnValue;
                
                 return;
           
            ]]>
        </script>
        <script-language>groovy</script-language>
        <transitions>
            <transition>
                <name>approve</name>
                <target>approved</target>
                <default>true</default>
            </transition>
            <transition>
                <name>review</name>
                <target>review</target>
            </transition>

        </transitions>

    </condition>
Explanation: A condition can have a script which when evaluated must have a value returned back. The name of the variable kaleo looks for is returnValue (normal groovy stuff I suppose). Based on some conditions you set the value in returnValue. Kaleo will do the transition to the value returned by the script. For e.g. if the value of returnValue is "xyz" then it will look for the transition called xyz.
In the script above, I am checking the role of the user logged on to the system. If the user has Administrator role then the value of returnValue is "approve" - this approve is the name of the transition defined withing the condition which is mapped to the target state called "approved". If the user is not Administrator then the transition happens to task called "review". Note that "approved" is the state and "review" is the task. Tasks require user input to proceed and "state" does not.
Res of the entire definition remains as is. I have attached the complete xml to this blog for direct use - my-workflow.xml

No comments:

Post a Comment