Page 1 of 2

Approve/Reject by email

Posted: Thu May 18, 2017 6:27 am
by avi123
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, 'avi123@gmail.com', $to, '', '', 
      $subject, 'Notification.html', array(), $aAttached);
}
Thanks & Regards

Re: Approve/Reject by email

Posted: Thu May 18, 2017 10:47 pm
by amosbatto
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 22880 times
The exclusive gateway has the following routing rules:
approvalByEmailRoutingRules.png
approvalByEmailRoutingRules.png (34.44 KiB) Viewed 22880 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, 'admin@example.com', 
  'manager@example.com', '', '', 'Approve Purchase Request #'.@@APP_NUMBER,
  'approvalForm.html');
//where admin@example.com 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 22880 times
Here is the sample process that you can download:
approvalByEmailProcess.png
approvalByEmailProcess.png (18.13 KiB) Viewed 22880 times

Re: Approve/Reject by email

Posted: Thu May 18, 2017 10:53 pm
by amosbatto
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, 'avi123@gmail.com', $to, '', '',
      $subject, 'Notification.html', array(), $aAttached);

Re: Approve/Reject by email

Posted: Fri May 19, 2017 8:02 am
by avi123
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, 'avi123@gmail.com', $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

Re: Approve/Reject by email

Posted: Fri May 19, 2017 6:17 pm
by amosbatto
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.

Re: Approve/Reject by email

Posted: Mon May 22, 2017 8:14 am
by avi123
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 22842 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 22842 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 448 times
Thanks & Reagrds

Re: Approve/Reject by email

Posted: Mon May 22, 2017 11:39 pm
by amosbatto
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.

Re: Approve/Reject by email

Posted: Tue May 23, 2017 8:08 am
by marcosfpa
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?

Re: Approve/Reject by email

Posted: Tue May 23, 2017 8:41 am
by avi123
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 432 times
Thanks & Regards

Re: Approve/Reject by email

Posted: Tue May 23, 2017 9:18 pm
by amosbatto
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.

Re: Approve/Reject by email

Posted: Tue May 23, 2017 10:19 pm
by amosbatto
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.

Re: Approve/Reject by email

Posted: Wed May 24, 2017 8:27 am
by avi123
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

Re: Approve/Reject by email

Posted: Thu May 25, 2017 12:32 am
by amosbatto
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 465 times
(1.42 KiB) Downloaded 429 times

Re: Approve/Reject by email

Posted: Fri May 26, 2017 3:03 pm
by marcosfpa
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);

Re: Approve/Reject by email

Posted: Fri May 26, 2017 5:34 pm
by amosbatto
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.

Re: Approve/Reject by email

Posted: Mon May 29, 2017 8:23 am
by marcosfpa
Did not work either...

Re: Approve/Reject by email

Posted: Mon May 29, 2017 10:44 pm
by amosbatto
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);

Re: Approve/Reject by email

Posted: Tue May 30, 2017 8:16 am
by marcosfpa
string(32) "00000000000000000000000000000001" string(5) "admin" resource(2) of type (mysql link) bool(true) array(1) { ["USR_PASSWORD"]=> string(32) "8636bdeb6302589eef8880016870a62e" }

Re: Approve/Reject by email

Posted: Tue May 30, 2017 1:48 pm
by marcosfpa
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!

Re: Approve/Reject by email

Posted: Tue May 30, 2017 7:45 pm
by amosbatto
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?

Re: Approve/Reject by email

Posted: Thu Jun 01, 2017 8:44 pm
by marcosfpa
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?

Re: Approve/Reject by email

Posted: Fri Jun 02, 2017 9:40 pm
by amosbatto
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.

Re: Approve/Reject by email

Posted: Mon Jun 05, 2017 1:01 pm
by avi123
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?

Re: Approve/Reject by email

Posted: Mon Jun 05, 2017 11:12 pm
by amosbatto
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.

Re: Approve/Reject by email

Posted: Mon Jun 05, 2017 11:44 pm
by amosbatto
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.

Re: Approve/Reject by email

Posted: Tue Jun 06, 2017 7:32 am
by avi123
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 376 times
Thanks & Regards

Re: Approve/Reject by email

Posted: Tue Jun 06, 2017 11:24 pm
by amosbatto
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.

Re: Approve/Reject by email

Posted: Wed Jun 07, 2017 8:20 am
by avi123
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.

Re: Approve/Reject by email

Posted: Wed Jun 07, 2017 10:37 pm
by amosbatto
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");

Re: Approve/Reject by email

Posted: Thu Jun 08, 2017 5:56 am
by avi123
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 395 times
Thanks & Regards