Prevent new cases until current case is completed

From pmusers
Jump to: navigation, search

The following example process forces the logged-in user to complete or cancel any existing cases assigned to the user before opening a new case in the process.


Process: Complete_case_before_opening_a_new_one-2.pmx (right click and select Save Link As)
Author: Amos Batto (amos[at]processmaker[dot]com)
Version: 2.0 (2019-03-11)
Tested in: ProcessMaker 3.3.4 Enterprise


Add the following trigger before the first step in the first task in the process:

if (!empty(@@redirected)) {
	@@redirected = null;
}
else {
	$user = @@USER_LOGGED; 
	$process = @@PROCESS;
	$currentCase = @@APPLICATION;
	$task = @@TASK;
	$currentCaseNo = @%APP_NUMBER;

	$query = "SELECT * FROM APP_CACHE_VIEW WHERE PRO_UID='$process' AND 
   		USR_UID='$user' AND (APP_STATUS='DRAFT' OR APP_STATUS='TO_DO') AND 
                DEL_THREAD_STATUS='OPEN' AND APP_UID<>'$currentCase'";
	$res = executeQuery($query);

	if (is_array($res) and count($res) > 0) {
		$c = new Cases();
		$c->removeCase(@@APPLICATION, true); //will also delete records from APP_DELEGATION
		$caseId = $res[1]['APP_UID'];
		$caseNo = $res[1]['APP_NUMBER']; 
	
    	//Display message to user to complete the existing case and redirect to it 
    	$g = new \G();
    	$g->SendMessageText("Case #$currentCaseNo aborted. Please complete or cancel this case #$caseNo before starting a new case.",
							'WARNING');
		PMFSendVariables($caseId, array('redirected' => $currentCase));

		//roll back case counter:
		$previousCaseNo = $currentCaseNo - 1;
		$sql = "UPDATE APP_SEQUENCE SET  ID=" . $previousCaseNo;
		executeQuery($sql);                
		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
	}
}

This trigger queries the APP_CACHE_VIEW table to check if there is already a case with "To Do" or "Draft" status assigned to the same user in the same process. If it finds an existing case, then it uses Cases::removeCase() to delete the current case from the APPLICATION, APP_DELEGATION and APP_CACHE_VIEW tables in the database.

Then, it writes the case number from the previous case to the APP_SEQUENCE.ID field to roll back the case counter to the previous case.

Finally, it redirects to the existing case so that the user can complete it. The trigger code also displays a message to the user informing him/her that the case was deleted and the other case needs to completed.

If there is an existing case, the user will see the following message when being redirected to the existing cases:

CompleteTheExistingCaseMessage.png

Note: In order to be able to update the APP_SEQUENCE.ID field in the database, edit the file workflow/engine/config/execute-query-blacklist.ini and change the line from:

queries  = "INSERT|UPDATE|REPLACE|DELETE"

To:

queries  = "INSERT|REPLACE|DELETE"

For more information, see Protecting PM Core Tables.