Only allow one case at a time in a process

From pmusers
Jump to: navigation, search

This programming example shows how to only allow a user to have one open case in a process. In this example, a user has to fill out a weekly sales report, but can only fill out one report at a time. If the user tries to start a second case in the sales report process, a trigger will automatically delete the second case and redirect the web browser to the first case, so the user can complete it.


Author: Amos Batto (amos@processmaker.com)
Tested in: 3.2.3 Community with PHP 5.6.20 in Debian 9.5


Create the following trigger:

if (!empty(@@redirected)) {
	@@redirected = null;
}
else {
	$user = @@USER_LOGGED; 
	$process = @@PROCESS;
	$currentCase = @@APPLICATION;
	$query = "SELECT * FROM APP_DELEGATION WHERE PRO_UID='$process' AND 
   		USR_UID='$user' AND DEL_THREAD_STATUS='OPEN' AND APP_UID<>'$currentCase'";
	$res = executeQuery($query);

	if (is_array($res) and count($res) > 0) {
		@@retDelete = PMFDeleteCase(@@APPLICATION);
    		$caseId = $res[1]['APP_UID'];
    		$caseIdx = $res[1]['DEL_INDEX']; 
	
    		//Display message to user to complete the existing case and redirect to it 
    		$g = new \G();
    		$g->SendMessageText("Other case aborted. Please complete or cancel this case before starting a new case.",
							'WARNING');
		PMFSendVariables($caseId, array('redirected' => $currentCase));
		echo "<script> top.location='opencase/$caseId'; </script>";	
		
		//Note: if ProcessMaker is used inside an iframe in another web page, then use this code instead:
		//header("Location: cases_Open?APP_UID=$caseId&DEL_INDEX=$caseIdx");
 
		die(); //abort trigger to prevent any errors
	}
}

Set this trigger to execute before the first step in the first task of the process.

This trigger queries the APP_DELEGATION table in the database to search for other open cases in the current process which are assigned to the logged-in user.

Note: If only wishing to search for other open cases in the current task, then use this query instead:
        $task = @@TASK;
	$query = "SELECT * FROM APP_DELEGATION WHERE PRO_UID='$process' AND 
   		USR_UID='$user' AND DEL_THREAD_STATUS='OPEN' AND TAS_UID='$task' AND APP_UID<>'$currentCase'";

If the query finds a open case, then it will call PMFDeleteCase() to delete the current case. Note that if using this trigger in the second or later task, then PMFCancelCase() should be used instead of PMFDeleteCase().

Then, the trigger will redirect the browser to the open case and use G::SendMessageText() to display a message to the user to complete the case first before starting a second case.

RedirectToFirstCase.png

When redirecting to the other case, it will execute this same trigger again. If this trigger is allowed to execute again, then it will cause an infinite loop. To prevent that, a case variable named "redirected" is set in the first case. If the trigger finds this variable, then it will unset the "redirected" variable and not execute the rest of the trigger.