Loop back from parallel tasks to a prior task

From pmusers
Jump to: navigation, search

This example shows how to route on all the other parallel tasks if a user assigned to one parallel tasks rejects a request. Then, if the request was rejected, then the case will loop back to the first task in the process, so that the user can revise and resubmit the request.



Process: Loop_back_from_parrallel_tasks-1.pmx (right click and select Save Link As)
Author: Amos Batto (amos@processmaker.com)
Version: 1.0 (2018-07-10)
Tested in: ProcessMaker 3.2.1 Community in Debian 8.4 with PHP 5.6.20 and Firefox 51


First, create the following process to request a resource:

LoopBackFromParallelTasksProcessMap.png

In this process, three managers will be assigned to the parallel tasks "Evaluate request1", "Evaluate request2" and "Evaluate request2" in order to evaluate the request. If one of the managers rejects the request, then a trigger will automatically route on the other two parallel tasks, so the other managers don't have to look at the request. The case will then be routed back to the "Request resource" task and assigned to the original user, who can edit the request and resubmit it or cancel the case.

The "Request resource" task will have Value Based Assignment and its variable will be set to: @@firstUser

This will allow the case to be reassigned to the original user if it gets routed back to the "Request resource" task.

Create the following trigger:

@@firstUser = @@USER_LOGGED;

Set this trigger to execute *before assignment* in the "Request resource" task.

Then, create three Dynaforms for the "Evaluate requestX" tasks with fields where the manager can accept or reject the request. To show how this can be done with different types of fields, the "Evaluate request1" task has a checkbox associated with the "approved" variable, the "Evaluate request2" task as a dropdown associated with the "decision" variable, and the "Evaluate request3" task as a radio button associated with the "decision2" variable. The dropdown and radio button have the options "accept" and "reject".

If wishing to force the use to actively select an option, then it is recommended to use a dropdown box which is required and the value of its first option is empty:

requiredDropdown.png

It is important that there be a different variable for the manager's decision in each parallel task. If the same Dynaform is used in all the parallel tasks, then the decision of one manager will overwrite the decision of another manager, since they are using the same variable to store the decision.

Then, create the following trigger:

if (@@approved_label === 'false' or @=decision === 'reject' or @=decision2 === 'reject') {
   $caseId = @@APPLICATION;
   $index = @%INDEX;
   $g = new G();

   //Select all the other parallel tasks for the current case that are still open
   $query = "SELECT * FROM APP_CACHE_VIEW WHERE APP_UID='$caseId' AND ".
      "DEL_THREAD_STATUS='OPEN' AND DEL_INDEX<>$index";
   $aTasks = executeQuery($query);
   
   if (!empty($aTasks) > 0) {
     $g->sessionVarSave();
     $msg = array();
   
      foreach ($aTasks as $aTask) {
         PMFDerivateCase($aTask['APP_UID'], $aTask['DEL_INDEX'], false, $aTask['USR_UID']);
         $msg[] = "Routed on task '{$aTask['APP_TAS_TITLE']}' assigned to {$aTask['APP_CURRENT_USER']}.";
      }   
      $g->sessionVarRestore();
      $g->sendMessageText(implode("\n", $msg), 'INFO'); 
   }
}

This trigger code first checks if one of the managers rejected the request. @@approved_label is the label of the checkbox. If no options are set in the properties of a checkbox, then by default the label will be set to "true" if the checkbox is marked or "false" if not marked.

If the request is rejected, then the APP_CACHE_VIEW table is queried to get the other parallel tasks that are open. Then, the PMFDerivateCase() function is called for each of these parallel tasks to route them on. Because PMFDerivateCase() will change the @@TASK and @@USER_LOGGED system variables when it routes a task assigned to another user, it is important to use G::sessionVarRestore() to reset the session variables back to their original state. Finally, G::SendMessageText() displays a message to the user explaining which tasks were routed on.

Set this trigger to execute before assignment in all three of the parallel tasks.

Next, set the routing rules for the exclusive routing rule so that it will route back to the original task if one of the managers rejected the request:

routingRulesExclusiveGateway.png

With an exclusive gateway, the first condition which evaluates to true will be the route taken, so it is very important that the condition to loop back to the "Request resource" task be the first one in the list, so it will be evaluated first. If it evaluates to false (meaning that none of the managers rejected the request), then the second condition will be evaluated, which is always true, so it will be taken if the first path wasn't taken.

When a case is run and one of the managers rejects the request, a message in grey will be displayed to the user about which users had their tasks automatically routed:

RoutingScreenInfo.png