Archive for the ‘ProcessMaker’ Category

ProcessMaker Triggers: Timing

First remember:

  1. A process is made up of tasks.
  2. A task is made up of steps (dynaform, input/output document).

You can fire a trigger on 3 levels: process, task and step, in the following order.

  1. Step: before loading a dynaform or after submitting a dynaform.
  2. Task: before assigning the user for the next task. After completing all the steps of a task, you get a confirmation showing the next task and who will be assigned to it. This is the same as after submitting a form if you have only one form in a given task.
  3. Process: before or after derivation of the case to the next task. Perfect if after a task you fire a trigger to insert/update some date on your external Oracle/SQL Server database. Executed after you press the confirmation button to go to the next task. It’s a not return point.

References:

Triggers

Trigger Examples

ProcessMaker: trigger to insert into Oracle

$db = '9324682434f8896adf05bc2078458052';//database connection UID
$idarea = 44;
$depid=@@DEPID;
$monto=@@MONTO;
$fecha=@@FECHA;

$result = executeQuery(“INSERT INTO PM_REEMBOLSO_CAJA_CHICA (ID_AREA,id_pmaker,monto,fecha)
VALUES (‘$idarea’,’$depid’,’$monto’,’$fecha’) “, $db);

Error when insert chinese charactor into oracle in a trigger

Database Connections

 

ProcessMaker: Customizing the Login Screen

For security reasons, I removed the System Information link from login page.

Like this:

1. Edit file: <INSTALL-DIRECTORY>/workflow/engine/skinEngine/skinEngine.php

2. Change line (170-178, 318-322, and 407-416, depending on your version):

if (DB_SYSTEM_INFORMATION == 1) {
$footer = ''; //"<a href=\"#\" onclick=\"openInfoPanel();return false;\" class=\"FooterLink\">| System Information |</a><br />";
}

Works like a charm!!!

 

References

Customizing the Login Screen

Remove System Information from login screen

Exportar formulario maestro/detalle de ProcessMaker

Referencia: http://forum.processmaker.com/viewtopic.php?f=9&t=3637&p=10693#p10693

This is a trigger to export case APP_DATA for a expense report (master/detail form).

 

function cleanData(&$str)
{
$str = preg_replace("/\t/", "\\t", $str);
$str = preg_replace("/\r?\n/", "\\n", $str);
if(strstr($str, '"')) $str = '"' . str_replace('"', '""', $str) . '"';
}

$maestro_col=array('NOMBRE','SUPERVISOR','EMPRESA','LOCAL','MONTOPAGADO','FECHA','GASTOS');//MASTER FORM FIELDS
//FIELD "GASTOS" IS AN ARRAY WHICH CONTAINS SEVERAL DETAIL ROWS
$detalle_col= array('TIPO', 'MOTIVO', 'DETALLE', 'LLEGADA', 'HORAITEM', 'HLLEGADA', 'IMPORTEITEM','NUMCOMPROBANTE');
//DETAIL FORM FIELDS, BELONG TO "GASTOS" ARRAY, WHICH IS A GRID FORM INSERTED ON THE MASTER EXPENSE REPORT FORM
$pro_uid = '6272277834cf7dae12a82d3013862769';//PROCESS ID
$AREA=@@AREA;//DEPARTMENT ID
$DESDE=@@DESDE;//BEGINNING DATE
$HASTA=@@HASTA;//END DATE

$querybasico="SELECT APP_NUMBER, APP_DATA FROM APPLICATION WHERE PRO_UID='$pro_uid' AND (DATE(APP_CREATE_DATE) BETWEEN '$DESDE' AND '$HASTA') AND APP_UID IN (SELECT APP_UID FROM APP_DELEGATION WHERE PRO_UID='$pro_uid' AND DEL_INDEX>=4)";//QUERY
$queryxarea="AND APP_INIT_USER IN (SELECT USR_UID FROM USERS WHERE DEP_UID='$AREA')";//QUERY BY DEPARTMENT
$queryorder="ORDER BY APP_CREATE_DATE DESC";//ORDERED BY DATE
$query="";

if ($AREA=='1')//FOR ALL DEPARTMENTS
{
$query=$querybasico;
}
else{
$query=$querybasico." ".$queryxarea;//FOR SPECIFIC DEPARTMENT
}
$query=$query." ".$queryorder;

$result = executeQuery($query);//GET DATA FROM MYSQL AS AN ASSOCIATIVE ARRAY
@@REFRIGERIOS = array();//FINAL RESULT ARRAY I NEED TO GET

$indicex = 1;
if (is_array($result) && count($result) > 0){
foreach ($result as $row){
$aVars = unserialize($row['APP_DATA']);//UNSERIALIZE CASE DATA, $aVars IS AN ASSOCIATIVE ARRAY
$maestro_arr= array();
$maestro_arr['ID']=$row['APP_NUMBER'];//MASTER ARRAY
foreach($aVars as $key => $value){
if(in_array($key,$maestro_col)){//LOOKUP ARRAY ITEM BY KEY IN MASTER FORM FIELDS ARRAY
$bVars = $value;
if ((is_array($bVars)) && (count($bVars)>0))//IF CASE VARIABLE IS AN ARRAY, IN THIS CASE I'M LOOKING FOR "GASTOS" CASE VARIABLE
{
$detalle_arr=array();//DETAILS ARRAY
foreach($bVars as $key => $value){//"GASTOS" IS AN ARRAY OF ARRAYS, SO ITERATE THROUGH IT
if (is_array($value)){//IF IS ARRAY
foreach ($maestro_arr as $mkey => $mvalue){
$detalle_arr[$mkey] = $mvalue;
}
foreach ($value as $k1 => $v1){//FINAL ITERATION
//TO GET TO DETAIL DATA, I HAVE TO ITERATE 4 TIMES:
//SQL ARRAY, CASE VARIABLES, "GASTOS" CASE VARIABLE WHICH IS AN ARRAY OF ARRAYS
//AND THROUGH EACH ARRAY (EXPENSE REPORT DETAIL ROW)
if(in_array($k1,$detalle_col)){//LOOKUP "GASTOS" ARRAY ITEMS BY KEY
$detalle_arr[$k1]=utf8_decode($v1);
}
}
@@REFRIGERIOS[$indicex] = $detalle_arr;//RESULT ARRAY
$indicex++;
}
}
}
else{
$maestro_arr[$key]=utf8_decode($value);//utf8_decode PHP function for spanish characters
}
}
}
}
}

$nrand=rand(1000,9999);
$filename = "REPORTE_REFRIGERIO_MOVILIDAD_" . $nrand. "_" . date('dmY') . ".xls";
header("Content-Disposition: attachment; filename=\"$filename\"");
header("Content-Type: application/vnd.ms-excel");
$flag = false;
$data = @@REFRIGERIOS;
foreach($data as $row)
{
if(!$flag) {
echo implode("\t", array_keys($row)) . "\n"; //EXPORT HEADER INFORMATION
$flag = true;
}
array_walk($row, 'cleanData');
echo implode("\t", array_values($row)) . "\n"; //EXPORT DATA INFORMATION
}
exit;

Consume PM Web services from ASP.Net

Original article: http://forum.processmaker.com/viewtopic.php?f=9&t=3836

I got working PM web services with ASP.Net.

When I create a employee on our HR system, a PM user will be created automatically so the new employee can access PM to make leave requests, expenses reports, etc.
Also, the newly created PM user is automatically assigned to the “Employees” group.

First, you need to “add a new service reference” to your web application on Visual Studio (version 2008 in my case). Indicate the address(URL) of the web service server of your web server installation (e.g. http://mydomain.com/sysworkflow/en/green/services/wsdl2, you better check this http://wiki.processmaker.com/index.php/ … b_Services).
Give the reference a namespace you can remember(“ProcessMaker”, in my case).

This will modify your web.config file, where you can see diferent settings for your web service.

<system.serviceModel>
<bindings>
<customBinding>
<binding name="ProcessMakerServiceSoap">
<textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16" messageVersion="Soap12" writeEncoding="utf-8">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
<httpTransport manualAddressing="false" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous" realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false" useDefaultWebProxy="true" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://mydomain.com:80/sysworkflow/en/green/services/soap2" binding="customBinding" bindingConfiguration="ProcessMakerServiceSoap" contract="ProcessMaker.ProcessMakerServiceSoap" name="ProcessMakerServiceSoap" />
</client>
</system.serviceModel>

Later, I created a class under App_Code folder. The code is below:

Imports Microsoft.VisualBasic
Imports ProcessMaker//web service namespace, the same you set at "add a new service reference"

Public Class PMakerWSDL

Public Shared Function crearUsuario(ByVal _Empleado As Object) As String

Dim _loginresponse As loginResponse = PMakerWSDL.login()
If _loginresponse.status_code = "0" Then
Dim _password As String
If _Empleado.Idempleado.ToString.Length > 7 Then
_password = _Empleado.Idempleado.Substring(2)
Dim _createuserresponse As createUserResponse = PMakerWSDL.createUser(_loginresponse.message, _Empleado.Idempleado, _Empleado.Nombres + " " + _Empleado.Nombres2, _Empleado.Apellidopaterno + " " + _Empleado.Apellidomaterno, _Empleado.Correo, "PROCESSMAKER_OPERATOR", _
_password)
If _createuserresponse.userUID IsNot Nothing And _createuserresponse.userUID <> "" Then
System.Web.HttpContext.Current.Session("_EsNuevo") = "0"
Dim _groupId As String = "3274407494c983348ca3613003993997" 'EMPLOYEES GROUP ID
Dim _assignusertogroupresponse As assignUserToGroupResponse = PMakerWSDL.assignUserToGroup(_loginresponse.message, _createuserresponse.userUID, _groupId)
If _assignusertogroupresponse.status_code <> 0 Then
Return "3"
Else
Return "4"
End If
Else
Return "2"
End If
Else
Return "1"
End If
Else
Return "0"
End If
End Function

Public Shared Function login() As loginResponse
Dim _pmakersoapclient As New ProcessMakerServiceSoapClient()
Dim _response As New loginResponse
Dim _message As String = ""
Dim _version As String = ""
Dim _timestamp As String = ""
Dim _statuscode As String = ""
Dim _username As String = "administratorusername"
Dim _password As String = "md5:myMD5encryptedpasswordblablabla"
_statuscode = _pmakersoapclient.login(_username, _password, _message, _version, _timestamp)
_response.version = _version
_response.timestamp = _timestamp
_response.message = _message
_response.status_code = _statuscode
Return _response
End Function

Public Shared Function createUser(ByVal _sessionID As String, ByVal _username As String, ByVal _firstname As String, _
ByVal _lastname As String, ByVal _email As String, _
ByVal _role As String, ByVal _password As String) As createUserResponse
Dim _pmakersoapclient As New ProcessMakerServiceSoapClient()
Dim _response As New createUserResponse
Dim _statuscode As String = ""
Dim _message As String = ""
Dim _timestamp As String = ""
Dim _userUID As String = ""
_statuscode = _pmakersoapclient.createUser(_sessionID, _username, _firstname, _lastname, _email, "PROCESSMAKER_OPERATOR", _
_password, _message, _userUID, _timestamp)
_response.message = _message
_response.status_code = _statuscode
_response.timestamp = _timestamp
_response.userUID = _userUID
Return _response
End Function

Public Shared Function createDepartment(ByVal _sessionID As String, ByVal _name As String, _
ByVal _parentUID As String) As createDepartmentResponse
Dim _pmakersoapclient As New ProcessMakerServiceSoapClient()
Dim _response As New createDepartmentResponse
Dim _statuscode As String = ""
Dim _message As String = ""
Dim _timestamp As String = ""
Dim _departmentID As String = ""
_statuscode = _pmakersoapclient.createDepartment(_sessionID, _name, _parentUID, _message, _departmentID, _timestamp)
_response.message = _message
_response.status_code = _statuscode
_response.timestamp = _timestamp
_response.departmentUID = _departmentID
Return _response
End Function

Public Shared Function assignUserToGroup(ByVal _sessionId As String, ByVal _userId As String, ByVal _groupId As String) As assignUserToGroupResponse
Dim _pmakersoapclient As New ProcessMakerServiceSoapClient()
Dim _response As New assignUserToGroupResponse() 'GENERIC PROCESS MAKER RESPONSE <message name="pmResponse">
Dim _message As String = ""
Dim _timestamp As String = ""
Dim _statuscode As String = ""
_statuscode = _pmakersoapclient.assignUserToGroup(_sessionId, _userId, _groupId, _message, _timestamp)
_response.status_code = _statuscode
_response.message = _message
_response.timestamp = _timestamp
Return _response
End Function

Public Shared Function assignUserToDepartment(ByVal _sessionId As String, ByVal _userId As String, ByVal _departmentId As String) As assignUserToGroupResponse
Dim _pmakersoapclient As New ProcessMakerServiceSoapClient()
Dim _response As New assignUserToGroupResponse()
Dim _message As String = ""
Dim _timestamp As String = ""
Dim _statuscode As String = ""
Dim _manager As String = ""
_manager = getDeparmentManager(_departmentId)
_statuscode = _pmakersoapclient.assignUserToDepartment(_sessionId, _userId, _departmentId, _manager, _message, _timestamp)
_response.status_code = _statuscode
_response.message = _message
_response.timestamp = _timestamp
Return _response
End Function

Public Shared Function getDeparmentManager(ByVal _departmentId As String) As String
Dim _manager As String = ""
'TO DO
Return _manager
End Function

Public Shared Function setUserInactive(ByVal _userId As String) As String
'TO DO
Return "1"
End Function
End Class

Then, you can use this from your ASP.Net web forms like this:

_BLEmployee.CreateEmployee(_Entity);//Create employee on HR system
//PROCESS MAKER INTEGRATION
string _respuestaPM="PM";
_respuestaPM = PMakerWSDL.crearUsuario(_Entity);//Create user on ProcessMaker

Other people have had trouble with this, so check:
viewtopic.php?f=9&t=2526&start=0&hilit=visual+studio
http://social.msdn.microsoft.com/Forums … ae9e57b64a

I also had this trouble when I added it as a web reference and not like a service reference.
Adding it as a service reference fixed the problem.

References:
ProcessMaker web services: http://wiki.processmaker.com/index.php/ … b_Services
Add service reference on VS 2008: http://chakkaradeep.wordpress.com/2007/08/13/add-service-reference-in-vs-2008/

http://blog.somecreativity.com/2008/07/22/add-service-reference-option-not-appearing-in-visual-studio-2008/

ProcessMaker: Approval/Rejection directly from the email

Referencia: Approval/Rejection directly from the email

Trabajando con ProcessMaker(PM), en un proceso de solicitud de permisos, encontré el inconveniente que el usuario Jefe de Área que aprueba el pedido tiene que estar pendiente siempre de su computadora y logeado siempre en el sistema, lo cual es una pérdida de tiempo y una limitante, ya que mayormente los jefes de área están en reuniones.

Lo bueno es que todos ellos usan BlackBerry’s 🙂 Así que implementé un proceso para enviarles una notificación automática vía e-mail de la solicitud de permiso, con 2 links: 1 para aprobar y otro para desaprobar la petición.

Basta con hacer click en uno de los links, se conecta con PM vía WSDL web services, se autologea, actualiza el caso (aprueba/rechaza) y deriva el caso al siguiente usuario y tarea.

Vaya que PM es poderoso y sus WSDL web services están bien desarrollados.

ProcessMaker: exportar datos a Excel

Referencia: PROCESS MAKER: Export case data to Excel

Hice un proceso de solicitud de permisos usando ProcessMaker. Luego de un mes de uso, me pidieron unos reportes.

Así que investigué y primero tuve que deserializar los datos grabados en la base de datos. Luego, convertirlo en un array y exportarlo a Excel.

Cada vez me asombra más este software ProcesssMaker. Es muy potente. Le veo buen futuro 🙂