Questions and discussion about using ProcessMaker: user interface, running cases & functionality

Moderator: amosbatto

By avi123
#790879
Hello,

I am using processmaker enterprise edition free trial version.
I want to approve/reject case by email. So when user clicked on approve link then it will open new email which contain is shown below:
Code: Select all
 Status: 'Approved'
Remark:'whatever user typed here'
When user submit this mail it will redirect to next assign user.
It is same for rejection and this data will update in database(I mean status, comment and comment's time)
How will I achieve this? Is it possible in community edition 3.1.2 as well?
And In my process, I used multiple uploader in grid. Now I want to attach that uploaded document in email. Uploaded document may be 1 or more than 1. I tried below trigger but didn't work
Code: Select all
$caseId    = @@APPLICATION;
$gridVar   = 'fileuploadgrid';
$fileField = 'multipleFile1';
$subject = @@Title;
//$aFiles    = array();
$query = "SELECT C.CON_VALUE AS FILENAME, AD.* FROM CONTENT C, APP_DOCUMENT AD 
   WHERE AD.APP_UID='$caseId' AND APP_DOC_FIELDNAME LIKE '{$gridVar}_%_{$fileField}' AND 
   AD.APP_DOC_STATUS = 'ACTIVE' AND AD.APP_DOC_UID = C.CON_ID AND 
   C.CON_CATEGORY = 'APP_DOC_FILENAME' ORDER BY AD.APP_DOC_FIELDNAME";
$aFiles = executeQuery($query);

if (is_array($aFiles) and count($aFiles) > 0) {
   $aAttached = array();
   foreach ($aFiles as $aFile) {
      $d = new AppDocument();
      $aDoc = $d->Load($aFile['APP_DOC_UID'], $aFile['DOC_VERSION']);
      $filename = $aDoc['APP_DOC_FILENAME'];
      $ext = pathinfo($filename, PATHINFO_EXTENSION);
      $filePath = PATH_DOCUMENT . G::getPathFromUID($caseId) . PATH_SEP .
         $aFile['APP_DOC_UID'] .'_'. $aFile['DOC_VERSION'] .'.'. $ext;
      $aAttached = PMFAddAttachmentToArray($aAttached, $filename, $filePath);
   }
   //get users who have participated in case:
   $c = new Cases();
   $aUsers = $c->getUsersParticipatedInCase(@@APPLICATION);
   $to = '';
   foreach ($aUsers['array'] as $userUID => $userInfo) {
      $to = (empty($to) ? '' : ', ') . $userInfo['USR_EMAIL'];
   }
   PMFSendMessage($caseId, '[email protected]', $to, '', '', 
      $subject, 'Notification.html', array(), $aAttached);
}
Thanks & Regards
User avatar
By amosbatto
#790901
First of all, read this example of approval via email using web services.
Instead of using a link in the form, use a form whose method="get", which has a textarea where the user can enter remarks.

First, create a process like the following:
approvalByEmailProcess.png
approvalByEmailProcess.png (18.13 KiB) Viewed 6784 times
The exclusive gateway has the following routing rules:
approvalByEmailRoutingRules.png
approvalByEmailRoutingRules.png (34.44 KiB) Viewed 6784 times
Then, create a form inside your email template like this:
Code: Select all
<form method="get" id="decisionForm" name="decisionForm"  action="http://localhost:320/decision.php">
<p><label>Purchase Decision</label><br /><select name="purchaseDecision">
<option value="">-Select-</option>
<option value="yes">Accept</option>
<option value="no">Reject</option>
</select></p>
<p><label>Comments</label><br /> 
<textarea name="decisionComments"></textarea></p>
<p><submit name="submit">	
<input type="hidden" name="caseId" value="@#APPLICATION">
<input type="hidden" name="userId" value="@#USER_LOGGED">	
<p><button type="submit" form="decisionForm" value="Submit">Submit</button></p>
</form>
Then, add a plain text file in your PM server at the path install-directory/processmaker/workflow/public_html/decision.php, with the following content:
Code: Select all
<?php
ini_set("soap.wsdl_cache_enabled", "0");
//ini_set('error_reporting', E_ALL); //uncomment to debug
//ini_set('display_errors', True);  //uncomment to debug
 
if (!isset($_GET['purchaseDecision'])) {
  die("The GET variable purchaseDecision is not set!");
}
//set to the IP address or domain name of your ProcessMaker server: 
$client = new SoapClient('http://localhost:320/sysworkflow/en/neoclassic/services/wsdl2');
$pass = 'md5:' . md5('admin');
$pass = 'admin';
$params = array(array('userid'=>'admin', 'password'=>$pass));
$result = $client->__SoapCall('login', $params);

if ($result->status_code == 0) {
   $sessionId = $result->message;
} 
else {
   die("<html><body><p></p>Unable to connect to ProcessMaker.<br>\n" .
      "Error Message: <pre>$result->message</pre></p></body></html>");
} 
class variableStruct {
    public $name;
    public $value;
}
 
$decision        = new variableStruct();
$decision->name  = 'purchaseDecision';
$decision->value = $_GET['purchaseDecision'];

$comments        = new variableStruct();
$comments->name  = 'decisionComments';
$comments->value = $_GET['decisionComments'];
 
$variables = array($decision, $comments);
$params = array(array('sessionId'=>$sessionId, 'caseId'=>$_GET['caseId'], 'variables'=>$variables));
$result = $client->__SoapCall('sendVariables', $params);
if ($result->status_code != 0) {
   die("<html><body><pre>Error: $result->message </pre></body></html>");
} 
else {
   print "Form submitted.";
}
?>
In the first task add the following trigger to fire before assignment:
Code: Select all
@@mailResult = PMFSendMessage(@@APPLICATION, '[email protected]', 
  '[email protected]', '', '', 'Approve Purchase Request #'[email protected]@APP_NUMBER,
  'approvalForm.html');
//where [email protected] is the email account configured at Admin > Email Servers
When a case is run, the user should receive the following email:
EmailApprovalByEmail.png
EmailApprovalByEmail.png (23.5 KiB) Viewed 6784 times
Here is the sample process that you can download:
approvalByEmailProcess.png
approvalByEmailProcess.png (18.13 KiB) Viewed 6784 times
Attachments
(71.4 KiB) Downloaded 170 times
User avatar
By amosbatto
#790905
avi123 wrote:And In my process, I used multiple uploader in grid. Now I want to attach that uploaded document in email. Uploaded document may be 1 or more than 1. I tried below trigger but didn't work
I don't see any obvious errors in your code. Add the following lines for debug:
Code: Select all
@=Files = $aFiles;
@=Attached = $aAttached;
@@emailResult = PMFSendMessage($caseId, '[email protected]', $to, '', '',
      $subject, 'Notification.html', array(), $aAttached);
By avi123
#790913
amosbatto wrote:
avi123 wrote:And In my process, I used multiple uploader in grid. Now I want to attach that uploaded document in email. Uploaded document may be 1 or more than 1. I tried below trigger but didn't work
I don't see any obvious errors in your code. Add the following lines for debug:
Code: Select all
@=Files = $aFiles;
@=Attached = $aAttached;
@@emailResult = PMFSendMessage($caseId, '[email protected]', $to, '', '',
      $subject, 'Notification.html', array(), $aAttached);
Thanks for reply, uploaded document attached in email is worked.
In Approve/Reject by email, I want when user clicked on Approve link it will open new email whose contents as followed:
Status: 'Approved'
Remark:'whatever user typed here'
And this email will send to admin. Then case will redirect to next assign user and Remark & Status will save in database.
When user clicked on Approve link it will open new email whose contents as same as above.
This email is also send to admin and initiator of case.

Is it possible by using community edition and how to achieve it?
Thanks & Regards
User avatar
By amosbatto
#790917
The Actions By Email feature in the Enterprise Edition isn't designed for what you want. You have to program this yourself in either the Community Edition or the Enterprise Edition.

Here are the basic steps:
1. Create a trigger which uses PMFSendMessage to will send the first email. It should contain an HTML form similar to the one I gave you in my previous post. There the user can enter remarks and select to approve or reject. The action of the form will be to execute your custom script (that can be located in the public_html directory).
2. Create a second trigger which has the PMFSendMessage() to send the second email.
3. Create a script in publicly accessible place (such as the processmaker/workflow/public_html to handle the submission from the first email. This script is executed when the user submits the form in the first email. This script uses the sendVariables() web service to send the information entered in form as variables to the case. Then the script uses the executeTrigger() web service to execute the second trigger which sends out the second email.
4. In your process, you need a looparound with an intermediate timer event and an exclusive gateway to keep checking until a variable is set, before it will advance to the rest of the process. Make sure that to set up your server to periodically execute the timereventcron.php file. See the looparound example I gave you in my previous post.
By avi123
#791448
amosbatto wrote:The Actions By Email feature in the Enterprise Edition isn't designed for what you want. You have to program this yourself in either the Community Edition or the Enterprise Edition.

Here are the basic steps:
1. Create a trigger which uses PMFSendMessage to will send the first email. It should contain an HTML form similar to the one I gave you in my previous post. There the user can enter remarks and select to approve or reject. The action of the form will be to execute your custom script (that can be located in the public_html directory).
2. Create a second trigger which has the PMFSendMessage() to send the second email.
3. Create a script in publicly accessible place (such as the processmaker/workflow/public_html to handle the submission from the first email. This script is executed when the user submits the form in the first email. This script uses the sendVariables() web service to send the information entered in form as variables to the case. Then the script uses the executeTrigger() web service to execute the second trigger which sends out the second email.
4. In your process, you need a looparound with an intermediate timer event and an exclusive gateway to keep checking until a variable is set, before it will advance to the rest of the process. Make sure that to set up your server to periodically execute the timereventcron.php file. See the looparound example I gave you in my previous post.
Thank you for your reply, But it's not working. I am using bitnami community edition 3.1.2
I want to know will it work on this process?
5.png
5.png (14.8 KiB) Viewed 6746 times
I tried to execute your process as well. I got email but when I fill data and submit it. It shows this errors:
7.png
7.png (45.96 KiB) Viewed 6746 times
When I only run localhost:81/decision.php it shows above error.
In error.log
[Fri May 19 15:47:00.021586 2017] [access_compat:error] [pid 9036:tid 1076] [client ::1:57250] AH01797: client denied by server configuration: C:/Bitnami/processmakerenterprise-3.1-0/apps/processmaker/htdocs/workflow/public_html/decision.php

I tried solution(changed in httpd.conf file) of this problem as well but it didn't work.
How to solve this problem?
And I also want to know that Can I route the case by calling web service? So user can approve/reject case by using email.
Here is my process:
(86.04 KiB) Downloaded 125 times
Thanks & Reagrds
User avatar
By amosbatto
#791473
Is http://localhost:81 the URL to access your installation of ProcessMaker? I don't have a windows machine to test why you can't access the decision.php file. On a Linux server, it generally is a file permissions problem that blocks access if it isn't an Apache configuration problem. Maybe Bitnami is blocking access for some reason. You can place your decision.php file anywhere which is accessible via a web browser, including on another web server.

If you want to route to the next task in the case, you can use the routeCase() web service in your code.
By marcosfpa
#791480
I found this email feature very interesting in the community version. It will help me a lot in some approval and purchasing processes.
One question: could I use this email approval feature to perform a task rather than using a gateway with a timer event?

I think of using this feature in a procurement process to ask suppliers for their price quotes, what do you think?
By avi123
#791481
amosbatto wrote:Is http://localhost:81 the URL to access your installation of ProcessMaker? I don't have a windows machine to test why you can't access the decision.php file. On a Linux server, it generally is a file permissions problem that blocks access if it isn't an Apache configuration problem. Maybe Bitnami is blocking access for some reason. You can place your decision.php file anywhere which is accessible via a web browser, including on another web server.

If you want to route to the next task in the case, you can use the routeCase() web service in your code.
Thanks for reply. It is working now. I changed in htaccess.conf file.
For routing case to next assign user, I changed in decision.php file.
Code: Select all
<?php
ini_set("soap.wsdl_cache_enabled", "0");
//ini_set('error_reporting', E_ALL); //uncomment to debug
//ini_set('display_errors', True);  //uncomment to debug
 
if (!isset($_GET['purchaseDecision'])) {
  die("The GET variable purchaseDecision is not set!");
}
//set to the IP address or domain name of your ProcessMaker server: 
$client = new SoapClient('http://localhost:81/sysworkflow/en/neoclassic/services/wsdl2');
$user = "admin";
$pass = "avi1234";
//$pass = 'md5:' . md5('nuc1234');     
$params = array(array('userid'=>$user, 'password'=>$pass));
$result = $client->__SoapCall('login', $params);

if ($result->status_code == 0) {
   $sessionId = $result->message;
   
} 
else {
   die("<html><body><pre>Unable to connect to ProcessMaker.<br>\n" .
     "Error Message: $result->message</pre></body></html>");
	} 
	
	
 
class variableStruct {
    public $name;
    public $value;
}

if ($_GET['index']) 
     $index = $_GET['index']; 
   else
     $index = "";
 
$decision        = new variableStruct();
$decision->name  = 'purchaseDecision';
$decision->value = $_GET['purchaseDecision'];

$comments        = new variableStruct();
$comments->name  = 'decisionComments';
$comments->value = $_GET['decisionComments'];
 
$variables = array($decision, $comments);
//$params = array(array('sessionId'=>$sessionId, 'caseId'=>$_GET['caseId'], 'variables'=>$variables));
$params = array(array('sessionId'=>$sessionId, 'caseId'=>$_GET['caseId'], 'delIndex'=>$index));

//$result = $client->__SoapCall('sendVariables', $params);
$result = $client->__SoapCall('routeCase', $params);
if ($result->status_code != 0) {
   die("<html><body><pre>Error: $result->message </pre></body></html>");
} 
else {
   print "Form submitted.";
}
?>
When I tried for routing case to next assign user. It gives following error:
Error: This case is assigned to another user
I want to approve or reject case by email as well as route case to next assign user, fired trigger like Save first approver comment,track record first approver, first approver grid and save the data in database. I also add one more seek information alongwith approve/ reject and select user for seek information.
Is this possible by using sendVariables, routeCase and executeTrigger all together in decision.php file?
And can I use mysql query in decision.php file as shown in link?
http://wiki.processmaker.com/3.0/Trigge ... _in_a_Case


I have attached my process.
(104.58 KiB) Downloaded 102 times
Thanks & Regards
User avatar
By amosbatto
#791489
marcosfpa wrote:I found this email feature very interesting in the community version. It will help me a lot in some approval and purchasing processes.
One question: could I use this email approval feature to perform a task rather than using a gateway with a timer event?

I think of using this feature in a procurement process to ask suppliers for their price quotes, what do you think?
If you want the user to complete a task via email, then add this trigger before the first step in the task:
Code: Select all
PMFSendMessage(...);
G::header("Location: ../cases/casesListExtJs");
die;
See: http://wiki.processmaker.com/3.0/Intern ... ader.28.29

You will need to add a hidden field to the email's form to hold the case's delegation index number (which is the @%INDEX system variable).

Then, in your decision.php file you can call the sendVariables() web service to send the variables from the email's form to the case and then call the routeCase() web service to route the case to the next task in the process.
User avatar
By amosbatto
#791490
avi123 wrote:When I tried for routing case to next assign user. It gives following error:
Error: This case is assigned to another user
Your problem is that you can only call routeCase() if the logged-in user is assigned to the current task in the case. For example, if "johndoe" is assigned to Task 2 and you logged in with "admin" in web services and then try to call routeCase() on delegation index 2, then you will get that error.

There are two possible solutions. One solution is to lookup the password hash for johndoe in the database and use that password hash when logging in via web services. See: http://wiki.processmaker.com/3.0/Proces ... eb_Service

The other solution is to create a trigger in your process with the following code:
Code: Select all
$g = new G();
$g->sessionVarSave();
PMFDerivateCase(@@task2UserId, @%task2Index);  
$g->sessionVarRestore();
Then, in your decision.php script, you can call the sendVariables() web service to set the value of the "task2UserId" variable to the ID of user johndoe and the "task2Index" to 2. Then call the executeTrigger() web service.
avi123 wrote:I want to approve or reject case by email as well as route case to next assign user, fired trigger like Save first approver comment,track record first approver, first approver grid and save the data in database. I also add one more seek information along with approve/ reject and select user for seek information.
Is this possible by using sendVariables, routeCase and executeTrigger all together in decision.php file?
Yes, you can use all those web services together in the same script.
avi123 wrote:And can I use mysql query in decision.php file as shown in link?
http://wiki.processmaker.com/3.0/Trigge ... _in_a_Case
Yes, you can do the same thing in your decision.php script. See this code for how to lookup the password hash for a user:
http://wiki.processmaker.com/3.0/Proces ... d_Password

Looking at your process, you probably want to add the following trigger before assignment in the previous task.
Code: Select all
PMFSendMessage(...);
G::header("Location: ../cases/casesListExtJs");
die;
Then use the routeCase() web service to route to the next task in your process.
By avi123
#791502
amosbatto wrote:
Looking at your process, you probably want to add the following trigger before assignment in the previous task.
Code: Select all
PMFSendMessage(...);
G::header("Location: ../cases/casesListExtJs");
die;
Then use the routeCase() web service to route to the next task in your process.
Thanks for reply. But this solution didn't work
Here is my decision.php file.
Code: Select all
<?php

ini_set("soap.wsdl_cache_enabled", "0");
//ini_set('error_reporting', E_ALL); //uncomment to debug
//ini_set('display_errors', True);  //uncomment to debug
 
/*$conn = mysql_connect('localhost:3307', 'root', 'nuc1234') or 
   die("Error connecting to MySQL database.\n");
mysql_select_db('wf_workflow');
*/
if (!isset($_GET['purchaseDecision'])) {
  die("The GET variable purchaseDecision is not set!");
}
//set to the IP address or domain name of your ProcessMaker server: 
$client = new SoapClient('http://192.168.11.55:81/sysworkflow/en/neoclassic/services/wsdl2');
$user = "fa1";
/*$user = $_SESSION['USER_LOGGED'];
$result = mysql_query("SELECT USR_PASSWORD FROM USERS WHERE USR_UID='$user'") or 
   die("Error: Unable to query the USER table.\n");
$record = mysql_fetch_array($result, MYSQL_ASSOC);
if (!$record) {
   die("Error: Unable to find password for '$user' in the USER table.\n");
}   

$pass = $record['USR_PASSWORD'];
*/
$pass = "avi1234";
//$pass = 'md5:' . md5('nuc1234');     
$params = array(array('userid'=>$user, 'password'=>$pass));
$result = $client->__SoapCall('login', $params);

if ($result->status_code == 0) {
   $sessionId = $result->message;
   
} 
else {
   die("<html><body><pre>Unable to connect to ProcessMaker.<br>\n" .
     "Error Message: $result->message</pre></body></html>");
	} 
	
	
 
class variableStruct {
    public $name;
    public $value;
}

/*if ($_GET['index']) 
    $index = $_GET['index']; 
   else
     $index = "";*/
 
$decision        = new variableStruct();
$decision->name  = 'purchaseDecision';
$decision->value = $_GET['purchaseDecision'];

$comments        = new variableStruct();
$comments->name  = 'decisionComments';
$comments->value = $_GET['decisionComments'];

/*$task2UserId        = new variableStruct();
$task2UserId->name  = 'task2UserId';
$task2UserId->value = $_SESSION['USER_LOGGED'];

$index        = new variableStruct();
$index->name  = 'task2Index';
$index->value = $_GET['INDEX'];;
*/

$variables = array($decision, $comments);
$params = array(array('sessionId'=>$sessionId, 'caseId'=>$_GET['caseId'], 'variables'=>$variables));
//$params = array(array('sessionId'=>$sessionId, 'caseId'=>$_GET['caseId'], 'delIndex'=>$index));

$result = $client->__SoapCall('sendVariables', $params);
//$result = $client->__SoapCall('routeCase', $params);
if ($result->status_code != 0) {
   die("<html><body><pre>Error: $result->message </pre></body></html>");
} 
else {
   print "Form submitted.";
}
/*
$params = array(array('sessionId'=>$sessionId, 'caseId'=>$_GET['caseId'], 'delIndex'=>$index));
$result = $client->__SoapCall('routeCase', $params);
if ($result->status_code != 0) {
   die("<html><body><pre>Error: $result->message </pre></body></html>");
} 
else {
   print "Case derived: $result->message \n";
}

$params = array(array('sessionId'=>$sessionId, 'caseId'=>$_GET['caseId'],
   'triggerIndex'=>'25299072258995b9f73ebd1063722338','delIndex'=>'1'));
$result = $client->__SoapCall('executeTrigger', $params);
if ($result->status_code != 0)
   print "Error: $result->message \n";
*/
?>
When I used above code with this trigger it doesn't route case to task2. It remains in task1.
Code: Select all
PMFSendMessage(...);
G::header("Location: ../cases/casesListExtJs");
die();

Suppose user(task1) is raised case. fa1(task2) is first approver and sa1(task3) is second approver. fa1 got email and if fa1 approve/reject it then in task2 it shows Status->Completed. It didn't go to task3. For this I changed in code which is given below:
Code: Select all
<?php

ini_set("soap.wsdl_cache_enabled", "0");
//ini_set('error_reporting', E_ALL); //uncomment to debug
//ini_set('display_errors', True);  //uncomment to debug
 
if (!isset($_GET['purchaseDecision'])) {
  die("The GET variable purchaseDecision is not set!");
}
//set to the IP address or domain name of your ProcessMaker server: 
$client = new SoapClient('http://192.168.11.55:81/sysworkflow/en/neoclassic/services/wsdl2');
$user = "fa1";

$pass = "nuc1234";
//$pass = 'md5:' . md5('nuc1234');     
$params = array(array('userid'=>$user, 'password'=>$pass));
$result = $client->__SoapCall('login', $params);

if ($result->status_code == 0) {
   $sessionId = $result->message;
   
} 
else {
   die("<html><body><pre>Unable to connect to ProcessMaker.<br>\n" .
     "Error Message: $result->message</pre></body></html>");
	} 
	
	
 
class variableStruct {
    public $name;
    public $value;
}

/*if ($_GET['index']) 
    $index = $_GET['index']; 
   else
     $index = "";*/
 
$decision        = new variableStruct();
$decision->name  = 'purchaseDecision';
$decision->value = $_GET['purchaseDecision'];

$comments        = new variableStruct();
$comments->name  = 'decisionComments';
$comments->value = $_GET['decisionComments'];

/*$task2UserId        = new variableStruct();
$task2UserId->name  = 'task2UserId';
$task2UserId->value = $_SESSION['USER_LOGGED'];

$index        = new variableStruct();
$index->name  = 'task2Index';
$index->value = $_GET['INDEX'];;
*/

//$variables = array($decision, $comments);
//$params = array(array('sessionId'=>$sessionId, 'caseId'=>$_GET['caseId'], 'variables'=>$variables));
$params = array(array('sessionId'=>$sessionId, 'caseId'=>$_GET['caseId'], 'delIndex'=>'2'));

//$result = $client->__SoapCall('sendVariables', $params);
$result = $client->__SoapCall('routeCase', $params);
if ($result->status_code != 0) {
   die("<html><body><pre>Error: $result->message </pre></body></html>");
} 
else {
   print "Form submitted.";
}
?>
Is it anything wrong in this code? And that executeTrigger() is also not working.
Do you have any example of this?

Thanks & Regards
User avatar
By amosbatto
#791514
You can only use $_SESSION['USER_LOGGED'] in a trigger. It won't work in decision.php, because it is outside PM. You can pass the user's ID in a hidden field in the email's form.
avi123 wrote:When I used above code with this trigger it doesn't route case to task2. It remains in task1.
Code: Select all
PMFSendMessage(...);
G::header("Location: ../cases/casesListExtJs");
die();
This trigger code stops the case in task1. When the user fills out the form in the email and submits it, then decision2.php will execute routeCase() to route the case from Task1 to Task2. I have attached a process and the code files that shows how to do this.
(59.25 KiB) Downloaded 136 times
(1.42 KiB) Downloaded 105 times
By marcosfpa
#791595
I managed to make it work and found it very good. However I can not send the user password with the code below, I can only manually set the user's password in the decision2.php file, however this is not useful since it may be different users to route the case via email ...

$pass = 'md5:' . $record['USR_PASSWORD'];
$client = new SoapClient('http://localhost:8080/syssample/en/neoc ... ices/wsdl2');
$params = array(array('userid'=>$userId, 'password'=>$pass));
$result = $client->__SoapCall('login', $params);
User avatar
By amosbatto
#791596
Try using this:
Code: Select all
$pass = 'sha256:' . $record['USR_PASSWORD'];
If that doesn't work, then verify that the Username is correct and the password hash matches what is found in the database.
User avatar
By amosbatto
#791644
Then, do the standard things to debug, like this:
Code: Select all
var_dump($userId);
var_dump($username);
//lookup the password hash for the user assigned to the "Request Items" task in the database
$conn = mysql_connect($dbDomain, $dbUser, $dbPassword) or
   die("Error connecting to MySQL database.\n");
var_dump($conn);
$ret = mysql_select_db($dbWorkspace);
var_dump($ret);
$result = mysql_query("SELECT USR_PASSWORD FROM USERS WHERE USR_UID='$userId'") or
   die("Error: Unable to query the USER table.\n");
$record = mysql_fetch_array($result, MYSQL_ASSOC);
var_dump($record);
By marcosfpa
#791652
string(32) "00000000000000000000000000000001" string(5) "admin" resource(2) of type (mysql link) bool(true) array(1) { ["USR_PASSWORD"]=> string(32) "8636bdeb6302589eef8880016870a62e" }
By marcosfpa
#791657
I have set up another process so that an ordinary user can approve directly in the email and route the case. However, it gives the error below even if for test I put the user login data directly in the decision.php ... In order for the function of routeCase () to work, does it have to be user ADMIN always?

User not registered!
User avatar
By amosbatto
#791664
Your database query is correct. Now debug the login() and the routeCase() and figure out exactly where it fails.

The logged-in user needs to be same as the user assigned to the open task when called routeCase(). Are you sure that the task is still open when routeCase() is called. You can only route the case if the task is still open in the case.

By the way, the name of the file that should be called is decision2.php in the last example I gave you. Are you mixing the two examples?
By marcosfpa
#791758
I did not mix the examples, I changed the same file name ...

Regarding the user of the task, yes it is the same user and the task is open when I try to execute by email ...

And about debugging the login error in routeCase, will you do this?
User avatar
By amosbatto
#791838
The login() web service is working, but the routeCase() is not working? Then, you probably aren't using the user who is assigned to the task in the case or the task has already been closed in the case.
By avi123
#793018
amosbatto wrote:The login() web service is working, but the routeCase() is not working? Then, you probably aren't using the user who is assigned to the task in the case or the task has already been closed in the case.
Is this feature capatible with 2 task process only?

Because in my process, when first approver approves or rejects case by email. That case status is completed in participated case and doesn't route to next assign user.

I tried to debug process. I fired trigger after routing.
If purchaseDecision ==0 then update REJECT status in application table. Then I checked process again.
When first approver approved case in email. It doesn't route to next assign user and application table status column update REJECT status. Why is it so?
User avatar
By amosbatto
#793100
avi123 wrote:Is this feature capatible with 2 task process only?

Because in my process, when first approver approves or rejects case by email. That case status is completed in participated case and doesn't route to next assign user.

I tried to debug process. I fired trigger after routing.
If purchaseDecision ==0 then update REJECT status in application table. Then I checked process again.
When first approver approved case in email. It doesn't route to next assign user and application table status column update REJECT status. Why is it so?
The process can have any number of tasks. The important thing is that you call routeCase() for the open task in the case. For example, if the second task in the process is currently the open task in the case, then the delegation index in routeCase() has to be 2.

I'm not sure how routeCase() handle's triggers in the routing. PMFDerivateCase() has a parameter to determine whether triggers should be fired or not when routing a case to the next task.
User avatar
By amosbatto
#793103
Marcos and Avi, if you post your process and your external code file and tell me in which task the email is sent out and which task should be routed, then I will see if I can figure out what is the problem.
By avi123
#793112
amosbatto wrote:Marcos and Avi, if you post your process and your external code file and tell me in which task the email is sent out and which task should be routed, then I will see if I can figure out what is the problem.
I tested this code. It worked if I passed hard code value of username and password. If I didn't pass hard value then it shows error message(Unable to connect processmaker). This is with process. When I tried with my process. It's not working.

I have sent my process to you in same post Downloads.zip. In this file you will get my process and table schema.
I have attached my process.
Downloads (2).zip
(104.58 KiB) Downloaded 11 times
Here I have attached external code file.
(1.53 KiB) Downloaded 82 times
Thanks & Regards
User avatar
By amosbatto
#793127
Avi, there is nothing wrong with your code. You need to debug your code the same way I showed Marcos in a previous post to determine if you are getting the password from the database. If all the informatition is correct, then post your process so I can check it against the code.
By avi123
#793130
amosbatto wrote:Avi, there is nothing wrong with your code. You need to debug your code the same way I showed Marcos in a previous post to determine if you are getting the password from the database. If all the informatition is correct, then post your process so I can check it against the code.
I got this.

string(32) "87298583958f06b9ddc9059027934610" NULL resource(3) of type (mysql link) bool(true) array(1) { ["USR_PASSWORD"]=> string(32) "00000000000000000000000000000000" }
Unable to connect to ProcessMaker.
Error Message:
User not registered!

87298583958f06b9ddc9059027934610 this is userid of user who raised a case not first approver. And username is showing NULL.
User avatar
By amosbatto
#793144
Oh I see the problem. You have to query the RBAC_USERS.USR_PASSWORD field, not the USERS.USR_PASSWORD field. It will work if the case is assigned to the admin, but it won't work for any other user, because USERS.USR_PASSWORD is always set to '000000000000000000000000000' for any other users. I bet this is also the reason why it didn't work for Marcos.

To fix it, change your code from:
Code: Select all
$result = mysql_query("SELECT USR_PASSWORD FROM USERS WHERE USR_UID='$userId'") or
   die("Error: Unable to query the USER table.\n");
To:
Code: Select all
$result = mysql_query("SELECT USR_PASSWORD FROM RBAC_USERS WHERE USR_UID='$userId'") or
   die("Error: Unable to query the USER table.\n");
By avi123
#793150
amosbatto wrote:Oh I see the problem. You have to query the RBAC_USERS.USR_PASSWORD field, not the USERS.USR_PASSWORD field. It will work if the case is assigned to the admin, but it won't work for any other user, because USERS.USR_PASSWORD is always set to '000000000000000000000000000' for any other users. I bet this is also the reason why it didn't work for Marcos.

To fix it, change your code from:
Code: Select all
$result = mysql_query("SELECT USR_PASSWORD FROM USERS WHERE USR_UID='$userId'") or
   die("Error: Unable to query the USER table.\n");
To:
Code: Select all
$result = mysql_query("SELECT USR_PASSWORD FROM RBAC_USERS WHERE USR_UID='$userId'") or
   die("Error: Unable to query the USER table.\n");
Thanks for reply. Your code solved half problem only.
In my process, there are 3 tasks. Task1-> user Raised a case, Task2 and Task3-> approvers approve that case.
I assign emp to task1, fa1 to task2 and sa1 to task3.
username(userid)
emp(87298583958f06b9ddc9059027934610)
fa1(59838867158f06bc02e69e1010252930)
sa1(31344604458f06c30df06a3037022897)

When emp submit case. It assign to fa1, when fa1 approves case then it assigns to sa1.
When emp submit case. fa1 got email and when he put values in email fields and submit it shows this
string(32) "87298583958f06b9ddc9059027934610" NULL resource(3) of type (mysql link) bool(true) array(1) { ["USR_PASSWORD"]=> string(64) "086d4bb4448fd5bab1cc29408bfd00a8408b229a5e4ef80dae02403fc14dfb44" }

87298583958f06b9ddc9059027934610-> emp's userid and instead of username it shows null.
Now problem is that I didn't userid and username of fa1. So I hard code it and pass then it worked. See the code:
Code: Select all
<?php
require_once "dbCredentials.php";
ini_set("soap.wsdl_cache_enabled", "0");
//ini_set('error_reporting', E_ALL); //uncomment to debug
//ini_set('display_errors', True);  //uncomment to debug
 
if (!isset($_GET['purchaseDecision'])) {
  die("The GET variable purchaseDecision is not set!");
}

$userId   = $_GET['userId'];
$username = $_GET['username'];
var_dump($userId);
var_dump($username);
//lookup the password hash for the user assigned to the "Request Items" task in the database
$conn = mysql_connect($dbDomain, $dbUser, $dbPassword) or
   die("Error connecting to MySQL database.\n");
   var_dump($conn);
$ret = mysql_select_db($dbWorkspace);
var_dump($ret);
$result = mysql_query("SELECT USR_PASSWORD FROM RBAC_USERS WHERE USR_UID='59838867158f06bc02e69e1010252930'") or
   die("Error: Unable to query the USER table.\n");
$record = mysql_fetch_array($result, MYSQL_ASSOC);
var_dump($record);
if (!$record) {
   die("Error: Unable to find password for '$username' in the USER table.\n");
}

$client = new SoapClient('http://192.168.11.55:81/sysworkflow/en/neoclassic/services/wsdl2');
$pass = 'md5:' . $record['USR_PASSWORD'];
$params = array(array('userid'=>'fa1', 'password'=>$pass));
$result = $client->__SoapCall('login', $params);

if ($result->status_code == 0) {
   $sessionId = $result->message;
} 
else {
   die("<html><body><p></p>Unable to connect to ProcessMaker.<br>\n" .
      "Error Message: <pre>$result->message</pre></p></body></html>");
} 

class variableStruct {
    public $name;
    public $value;
}
 
$decision        = new variableStruct();
$decision->name  = 'purchaseDecision';
$decision->value = $_GET['purchaseDecision'];

$comments        = new variableStruct();
$comments->name  = 'decisionComments';
$comments->value = $_GET['decisionComments'];
 
$variables = array($decision, $comments);
$params = array(array('sessionId'=>$sessionId, 'caseId'=>$_GET['caseId'], 'variables'=>$variables));
$result = $client->__SoapCall('sendVariables', $params);

if ($result->status_code != 0) {
   die("<html><body><pre>Error: $result->message </pre></body></html>");
}

$params = array(array('sessionId'=>$sessionId, 'caseId'=>$_GET['caseId'], 'delIndex'=>$_GET['index']));
$result = $client->__SoapCall('routeCase', $params);

if ($result->status_code != 0) {
   die("<html><body><pre>Error: $result->message </pre></body></html>");
}

print "<html><body><p>Form submitted and case routed:<br>\n".$result->message."</p></body</html>";

?>
If I used hard code value for userid and username then works fine. Case is routing.

$userId = $_GET['userId'];
$username = $_GET['username'];
I didn't get userid of fa1. Instead of fa1's userid I get emp's userid.
And I didn't get username of assign user(fa1). So it doesn't login.
In short, it didn't get appropriate userid and username.
Will this solution work for value based assignment.


I have attached my process here.
(88.06 KiB) Downloaded 99 times
Thanks & Regards

Hi, Is there any way to show my custom column only[…]

Send for clarification

Hi, I know this is an old post but i could not fin[…]

add dropdown to search process

Please replay if there is any solution!!!!

Amosbatto, PMUsers.com is down.

Hi Amos, I appreciate you setting up a tips and t[…]