Saltar a contenido

Programmer's Manual

Examples of solutions to everyday implementation problems

How to print messages during the execution of a post-process in preview but not in production, to validate the operation of a post-process

When the preview is run the variable $ef_test is true.

Important, there are two previews

  • During the creation of the electronic folio. In this preview only you can check the javascript validations and see the general form layout but can't run an update to validate personal pages or post-processes.

  • During assignment, visible or editable fields per station. In this case, the following information data is not available (which they do have at runtime): $in{'folio'} and the values of the folio fields, unless in the preview they are editable and populated before running the update.

sub main1 {
    if ($ef_test) {
        print "*Estoy en vista previa ejecutando main1*";
        print "*Inicializo folio a 1 para tener un valor válido*";
        $in{'folio'} = *1*;
    }
    # El código siguiente se ejecuta en vista previa y en producción
}

sub main2 {
    if ($ef_test) {
        print "*Estoy en vista previa ejecutando main2*";
    }
}

1;

Email notifications to personnel outside the company

Problem I want to make special notifications by email to users not involved in the process or users additional to those parameterized, my clients, suppliers, advisors, etc.

use Eflow::Libs;

sub main1 {
}

sub main2 {
    my $lib = Libs->new();
    my $rsx = Pg_VB->new();
    my $mensaje;
    my %datos;
    my $destino;

    # Leo los datos de mi folio
    $rsx->connectdb("dbname=workflow");
    $rsx->execute("select * from obj$in{'obj_id'} where folio=$in{'folio'}");
    %datos = $rs->getHash;
    $rsx->connectdb("dbname=workflow");
    $rsx->execute("select name from station where process=$in{'process'} and id=$in{'opt_station'}");
    $destino = $rs->itemvalue('name');
    # Construyo mi mensaje de correo
    # Sustituir cada ??? por el número correcto del campo asignado en el diseñador al dato que quiere
    # Recuperar del folio que se está procesando.
    $mensaje = qq¡
    Estimado $datos{'ff???'},
    Le notificamos que su folio número $in{'process'}-$in{'folio'}
    Referente a su Garantía, a pasado a la etapa $destino.
    Datos de su tramite
    Nombre del cliente : $datos{'ff???'}
    Telefonos : $datos{'ff???'}
    Tipo tramite : $datos{'ff???'}

    Atentamente
    Nuestra empresa.
    ¡;

    # The recipient's email must be obtained from some source,
     # in this case it is assumed that somehow they are in the variable $para.
    $lib->email_user($para,'Título de notificación',$mensaje);
}

1;

If your email message is encoded with HTML, to be able to send images and a more user-friendly format, replace the last line with:

$lib->email_user_html($para,'Título de notificación',$ruta_archivo);

In this case the file_path variable contains the path on the hard drive of a document in HTML format, the images are links to the portal from which they will be downloaded at the moment the client opens the message in their email client.

Validate that the fields captured in the electronic document form are valid according to my parameters

  1. To carry out validations as quickly as possible, it is recommended that the values are editable in the form to receive them at the time of process the form. If the field is read-only, enable that the field is sent as hidden to have the data available.
use Eflow::Libs;

sub main1 {
    my $lib = Libs->new();
    if ($in{'ff???'} ne '*mi valor*') {
        $lib->Alert("El campo fulano debe tener el valor <b>mi valor</b> para ser válido.",1);
    } elsif (($in{'ff???'} == *8*) && ($in{'ff???'} eq '*UNI*')) {
        $lib->Alert("La combinación de campos no es válida");
    }
}

sub main2 {
}

1;

If you consider that your users may be aggressive or your work environment unreliable. You will have to load the data with a query instead of sending it in the form to prevent hidden values from being altered by the user.

Example :

$rs->execute("Select * from obj## where folio = $in{'folio'}");
%data = $rs->getHash;

Send the folio to a different stage from the one parameterized in the designer when a condition is met

sub main1 {
    if (!$in{'opt_station'}) {
        # Actualizando comentarios no hacer nada
        return 0;
    } elsif ($in{'opt_station'} == -1) {
        # Se está terminando el folio, hacer algo?
        return 0;
    } elsif ($in{'ff???'} == *valor*) {
        # Cambiar destino seleccionado por el este.
        $in{'opt_station'} = 6;
        return 0;
    }
}

sub main2 {
}

1;

Decide who to assign the folio to without using eFlow algorithms

sub main1 {
    if (!$in{'opt_station'}) {
        # Actualizando comentarios no hacer nada
        return 0;
    } elsif ($in{'opt_station'} == -1) {
        # Se está terminando el folio, hacer algo?
        return 0;
    } elsif ($in{'ff???'} == *valor*) {
        # Asignar el usuario que debe recibir el folio.
        $ef_user = *6*;
        return 0;
        #IMPORTANTE, el número es el de la plaza del usuario, no el número del usuario.
    }
}

sub main2 {
}

1;

Save data captured in the process in a table in my company's systems

use Eflow::Libs;

sub main1 {
    my $lib = Libs->new();
    my $dbh;
    my $sth;
    my $rsx;
    # Validaciones requeridas para garantizar que datos son correctos.
    # Antes de mover el folio a la siguiente etapa.
    ...
    if (!$in{'opt_station'}) {
        # Actualizando comentarios no hacer nada
        return 0;
    }
    $dbh = DBI->connect("string de conexion a su base de datos") or
    $lib->Error($DBI::errstr);
    # Prepare sus datos para la transacción que corresponda.
    $dbh->do("*insert into TABLA () values ()*") or
    $lib->Error($DBI::errstr);
    $dbh->do("*update TABLA set ... where ...*") or
    $lib->Error($DBI::errstr);
}

sub main2 {
}

1;

I want to return the folio to the user who updates a particular stage

OPTION 1:

This requires two steps:

  1. Save the user who updates at the correct stage.
  2. Recover the saved user when you want to return the folio to this person.

Post Process at the stage where I want to save the updating user.

Using a field of the electronic folio, designated for this operation. No additional database connections are required.

sub main1 {
    $in{'ff???'} = "$user,$ruser";
}

sub main 2{
}

1;

Post Process in the recovery stage of the saved user.

Using a field of the electronic folio, designated for this operation. The field is supposed to appear as a hidden field on the form being updated.

sub main1 {
    ($ef_user,$ef_ruser) = split/,/,$in{'ff???'};
}

sub main2 {
}

1;

OPTION 2

getNextUser() function

Generic for any process. In the stage that I want to return the folio, I create assignment type getNextUser(); Additional connections to databases are required.

sub getNextUser {
    my $rs = Pg_VB->new();
    my $station = '???';
    $rs->connectdb("dbname=workflow");
    $rs->execute("select u.id,u.ruser_id from log_update$in{'process'} l, users u where l.station=$station and l.folio$in{'folio'} and l.user_id=u.id");
    return ($rs->itemvalue('id'),$rs->itemvalue('ruser_id'));
}

I want to deploy 2 combos on a station, but the selection of the first combo determines the values of the second combo

  • First option. Web Solution 1. The stations will only be accessed from a PC browser.

In the electronic folio we create 5 fields with the following configurations (the two combos that we want to create are not created).

  • Unlimited text field, to store the description of the value of the first combo. (ff1)
  • Unlimited text field, to store the value of the first combo. (ff2)
  • Unlimited text field, to store the description of the value of the second combo. (ff3)
  • Unlimited text field, to store the value of the second combo. (ff4)

Text link field to an application

In the stage where the selection of these values is going to be carried out, it must be configured as follows:

  • ff1 : See
  • ff2 : View -- Hidden
  • ff3 : See
  • ff4 : View -- Hidden

Finally, in the league application a script will be executed that the programmer can develop with complete freedom to display and select the two combos as he sees fit to develop this part.

The important thing is that at the end of the selection of the two combos, the application must execute the following code at the end. Suppose that once both combos have been selected and the page is updated, the "save" subroutine is executed:

sub salva {
    my $rs = Pg_VB->new();
    $rs->connectdb("dbname=workflow");
    $rs->execute("update obj?? set *ff1*='$in{'*combo1*'},*ff2*={'*valor1*'},*ff3*='$in{'*combo2*'},*ff4*={'*valor2*'} where folio=$in{'folio'}");
    print qq|
    <html>
    <body>
    <script languaje="JavaScript">
    top.opener.location.reload();
    self.close();
    </script>
    </body>
    </html>
    |;
}

In conclusion, the problem is solved by selecting the values of the combos through a pop-up window and subsequently transferring the values to the fields of the folio and reloading the form so that the stage form shows the values selected in the combos of the window emergent.

  • Second option. Using Web 2.0. JavaScript and use of the DOM. JQuery.

Create a custom page

  • In main_page3: Load the JavaScript libraries you require and interact with the DOM to create the desired effect on the desired elements.
  • Use the HTML source code generated in the browser so that you know the ids and names of the variables of the combos or other elements with which you want to interact.
our $combo1;

sub main_page {
}

sub main_page2 {
}

sub main_page3 {
    print qq¡
    <script>
    // JavaScript con instrucciones para manipular los elementos.
    </script>
    ¡;
}

sub main_value {
    return 0;
}

Season. I want to pull data from my ERP to eFlow right at the moment the folio is displayed, since this value changes frequently in my ERP (examples: exchange rate, production lot number, etc.)

Add a .pl program to the "Personal Page" parameter and create the following code:

use DBI;
use Eflow::Libs;

sub main_page {
    if ($ef_test) {
        print "Ejecutando MAIN PAGE<br>";
    }
}

sub main_page2 {
    if ($ef_test) {
        print "Ejecutando MAIN PAGE2<br>";
    }
}

sub main_page3 {
    if ($ef_test) {
        print "Ejecutando MAIN PAGE3<br>";
    }
}

sub main_value {
    my $lib = Libs->new();
    my $dbh;
    my $sth;
    my $rsx;

    if ($data{'id'} == ??) {
        if ($ef_test) {
            print "Traer valor actual del ERP <br>";
        }
        $dbh = DBI->connect("*string de conexion a su base de datos*") or
        $lib->Error(DBI::errstr);
        $dbh->prepare("*select válido para traer el valor de su base de datos*") or $lib->Error(DBI::errstr);
        $dbh->execute or $lib->Error(DBI::errstr);
        $rsx = $sth->fetchrow_hashref;
        $val{'ff???'} = $$rsx*{'nombre del campo'};*
    }
    return 0;
}

Season. I have several user editable fields on a station

One of them is a key with several associated data in an external database (example: customer number, which has associates, name, telephone address, RFC, etc.). I want the user to capture the key and if the data exists in the external database, the fields related to the existing data are filled in and these cannot be edited by the user. If the number does not exist, the new record is registered with the fields that the user captures, in this case the related data can be edited.

When you see problems like the previous one and have programmed in Windows for a long time, the first thing that occurs to you is how to enable or disable the fields in case one of the two events occurs: found or not found. Below we are going to present two solutions to the problem, the first in Web style and the second in Windows style.

1) The simple, simple and direct method in the Web 1.0 style

Make the fields not editable but only viewable (fields that require processing in a post-process are also activated as hidden). When you start the folio they will all be empty. There is a Link type field that opens a pop-up window to search for the key field, the search query is made to the external database and the results can be:

a) The key is found. All related data is then pulled and updated with an update in the corresponding objNN table.

$rs->execute("update objNN set ffNN='value',ffNN='value',... where folio=$in{'folio'}");

Subsequently, the following HTML page ends up printing:

<html>
<body>
<script>
top.opener.location.reload();
self.close();
</script>
</body>
</html>

This causes the eFlow window to reload and since the data was already entered with the previous update, the data is available in the WorkFlow. When the window reloads, the empty data now appears full and the window automatically closes.

b) You can't find the key. It then displays a capture form with all the related data. When the user finishes capturing, submit the form. The data is inserted into the external table. The data in the folio table is updated as in the previous step and the same HTML page from the previous step is printed again.

2) Using Web 2.0 techniques

All fields are editable on the station form.

  • A program.pl is added to the station in the "Personal Page" line, as if it were a post-process, read the station.cgi section to understand the concept.
  • In main_page3: Load the JavaScript libraries you require and interact with the DOM to create the desired effect on the desired elements.
  • Use the HTML source code generated in the browser so that you know the ids and names of the variables of the combos or other elements with which you want to interact.
sub main_page {
}

sub main_page2 {
}

sub main_page3 {

print qq|
    <script>
    document.MyForm.ffnnn.readOnly=true;
    document.MyForm.ffnnn.readOnly=true;
    ...
    </script>
    |;
}

sub main_value {
}

1;

This will cause this code to print right after the fields are printed and will disable all of them. is one line per field you want to disable. The actual ff of your page should be written. A League type field is created again to open a pop-up window. And the key is located in the external base. Possible results

a) The key is located. With javascript all the data is copied to the eFlow form fields that are readonly. And the window closes itself.

<html>
<body>
<script>
top.opener.document.MyForm.ffpredial.value='valor predial';
top.opener.document.MyForm.ffnnn.value='valor';
top.opener.document.MyForm.ffnnn.value='valor';
...
self.close();
</script>
</body>
</html>

b) The key is not found. The key is passed with javascript to the read-only field of the eFlow form. And the locked fields are enabled for writing:

<html>
<body>
<script>
top.opener.document.MyForm.ffLLAVEl.value='valor predial';
top.opener.document.MyForm.ffnnn.readOnly=false;
top.opener.document.MyForm.ffnnn.readOnly=false;
...
top.opener.document.MyForm.ffnnn.focus();
self.close();
</script>
</body>
</html>

Enable all fields so they can be written. The only one that is not the one with the key so that they don't look for one and write another.

A post-process has to be added to insert the new values into the external database.

I want to display a field in a special way in the "station" form, depending on whether the view is on a mobile device or on a PC. The field contains a string of characters that I want to appear arranged in a table

Suppose we have extracted a group of data from our ERP, and we have concatenated the values with "pipes", for the example it is the detail of the lines of a purchase. The detail data was stored in a text field of the folio with the following format:

description|quantity|unit|unit price|total|purchase warehouse|work|cost center
description|quantity|unit|unit price|total|purchase warehouse|work|cost center
description|quantity|unit|unit price|total|purchase warehouse|work|cost center
description|quantity|unit|unit price|total|purchase warehouse|work|cost center

The lines are located in the variable ff35 (for this example). When entering the folio in eFlow we want to present the values in a large table if access is from a PC, but in a different format if it is from a BlackBerry, with a narrow display and limited HTML.

sub main_page {
}

sub main_page2 {
}

sub main_page3 {
}

sub main_value {
    my $det;
    if ($data{'id'} == 35) {
        if ($BB) {
            my @lines;
            my $line;
            my $desc; my $cant; my $unid; my $precio; my $alm; my $obra; my $const; my $total;
            my $bgcolor;
            my $i=0;
            @lines = split /n/,$val{'ff447'};
            print qq|
            <tr>
            <td class='label' width=20% valign='top'>Detalle</td></tr>
            <tr>
            <td class='value' valign='top'>
            <table border=0 cellspacing=0 style='font-size: 6pt' width="100%">
            |;
            foreach $line (@lines) {
                ($desc,$cant,$unid,$precio,$total,$alm,$obra,$const) = split /|/,$line;
                $i++;
                print qq|
                <tr class='title'><td colspan="2" width="100%">Partida $i</td></tr>
                <tr bgcolor="white"><td width="35%" valign="top"><b>Descr</b> </td><td width="65%" valign="top">$desc</td></tr>
                <tr bgcolor="white"><td width="35%" valign="top"><b>Cant</b> </td><td width="65%">$cant $unid <b>P.U.</b>$$precio</td></tr>
                <tr bgcolor="white"><td width="35%" valign="top"><b>Total</b> </td><td width="65%">$$total</td></tr>
                <tr bgcolor="white"><td width="35%" valign="top"><b>Almac</b> </td><td width="65%">$alm</td></tr>
                <tr bgcolor="white"><td width="35%" valign="top"><b>Obra</b> </td><td width="65%">$obra</td></tr>
                <tr bgcolor="white"><td width="35%" valign="top"><b>CECOS</b> </td><td width="65%">$const</td></tr>
                |;
            }
            print qq|
            </table>
            </td></tr>
            |;
        } else {
            $det = $val{'ff447'};
            $det =~ s/|/</td><td bgcolor='white'>/g;
            $det =~ s/n/</td></tr>n<tr><td bgcolor='white'>/g;
            print qq|
            <tr><td class='label' width=20% valign='top'>Detalle</td>
            <td class='value' valign='top'>
            <table border=0 cellspacing=1 style='font-size: 8pt' bgcolor="#888888">
            <tr class='title'>
            <td>Descripción</td>
            <td>Cantidad</td>
            <td>Unidad</td>
            <td>Precio</td>
            <td>Monto</td>
            <td>Almacén</td>
            <td>Obra</td>
            <td>Centro Costos</td>
            </tr>
            <tr><td bgcolor='white'>$det</td></tr>
            </table>
            </td>
            <td valign='top' width='20%'></td>
            |;
        }
        return 1;
    }
    return 0;
}

1;

The result would look like the two images below:

Image on PC

Mobile device

I want to create a folio when an event is created in my ERP, CRM or other system

These types of problems are solved using a cron service. In the following example, we are going to create a folio when a new purchase is created in the ERP (In this case Navision). The folio will be sent to an authorizer, the authorization is escalated to a director and subsequently sent to purchases when this is authorized. To create the folio, create a program that runs with cron every 2 minutes. The program that validates that there is a new purchase in Navision and inserts the folio into eFlow is the following. For this example in Navision, a new entry was created in the purchases table for the user to indicate when the purchase is ready to be authorized.

Cron line:

*/2 * * * * /home/eflow/cron/compras_nav/carga_compras.pl

carga_compras.pl

#!/usr/bin/perl

carga_nuevas_compras();

# Rutina para cargar las compras

sub carga_nuevas_compras {
    my $qry;
    my $sth; my $rs;
    my $sth2; my $rs2;
    my %ph;
    my %fd;
    my $st;
    my $ok;

    conectaNavision($SERVIDOR,2);
    # Buscar todas las compras que tienen una version 1 creada
    $qry = qq|select * FROM [dbo].[VISE$Purchase Header] where Status=1 and "Status Flow"=0 and "Document Type"=1|;
    $sth = $dbN->prepare($qry) or sqlError("$qrynn$DBI::errstr");
    $sth->execute() or sqlError("$qrynn$DBI::errstr");
    while ($rs = $sth->fetchrow_hashref) {
         %ph = %$rs;
         %fd = ();
        $st = carga_informacion(%ph,%fd);
        if ($st) {
            $ok = alta_folio(%fd);
            if ($ok) {
                marca_tomado($$rs{'No_'},$$rs{'Posting Description'});
            }
        }
    }
}

# Esta rutina inserta el nuevo folio en eFlow

sub alta_folio {
    my $fd = shift;
    my $folio;
    my $label;
    my $key;

    $rsw->execute("begin");
    $rsw->execute("LOCK TABLE process IN SHARE ROW EXCLUSIVE MODE");
    $rsw->execute("update process set folio=folio+1 where id=$PROCESS");
    $rsw->execute("select folio from process where id=$PROCESS");
    $folio = $rsw->itemvalue('folio');
    $rsw->execute('commit');
    if (($OBJ > 0) && ($folio)) {
        $$fd{'folio'} = $folio;
        $rsf->insert("obj$OBJ",$fd);
    } else {
        return 0;
    }
    $label = "$$fd{'ff440'}";
    $rsw->execute("insert into folio$PROCESS (id,label,status,user_folio,user_new,date_created,time_created,acc_cost,date_finished,obj_folio) values ...");
    $rsw->execute("insert into folio_station$PROCESS (folio,station,user_id,date_station,time_station) values ...");
    return 1;
}

    # Esta rutina extrae los datos de Navision y los pasa al folio en eFlow

sub carga_informacion {
    my $ph = shift;
    my $fd = shift;
    $$fd{'ff440'} = $$ph{'No_'};
    $$fd{'ff491'} = $$ph{'Tipo pago'};
    $$fd{'ff442'} = $$ph{'Pay-to Name'};
    $$fd{'ff441'} = $Sdate;
    $$fd{'ff455'} = $$ph{'Purchaser Code'};
    $$fd{'ff457'} = "$$ph{'Id Solicitante'},$super,$gerente,$esol,$esup";
    ($$fd{'ff445'},$$fd{'ff450'}) = getUsuario($$ph{'Id Solicitante'});
    ...
    if ($errores) {
        return 0;
    }
    ...
    return 1;
}

### Esta rutina marca compra como tomada por eFlow

sub marca_tomado {
    my $no_doc = shift;
    my $qry;
    $qry = qq|update [dbo].[VISE$Purchase Header] set "Status Flow" = 1 where "no_"='$no_doc'|;
    $dbN2->do($qry) or sqlError("$qrynn$DBI::errstr");
}

I want to configure eFlow to authenticate users using digital certificates

Configure eflow.conf of the apache server.

<Directory "/home/eflowweb/cgi-bin">
AllowOverride None
Options None
Order allow,deny
Allow from all
SSLOptions +StdEnvVars +OptRenegotiate
SSLVerifyClient require
SSLVerifyDepth 1
</Directory>

<Directory "/home/eflowweb/html">
AllowOverride None
Options None
Order allow,deny
Allow from all
SSLVerifyClient require
SSLVerifyDepth 1
</Directory>

<VirtualHost *:8043>
DirectoryIndex index.htm
AddCharset utf-8 htm html
ServerAdmin ...
ServerName mi.eflow.com.mx
DocumentRoot /home/eflowweb/html
ErrorLog /home/eflowweb/log/error_log
ScriptAlias /cgi-bin/ "/home/eflowweb/cgi-bin/"
SSLCACertificateFile ...../ca_CA.crt
SSLCertificateFile ..../myserver.cer
SSLCertificateKeyFile ..../myserver.key
SSLEngine on
</VirtualHost>

I want to make a document queue

At one stage I receive hundreds of documents. These documents can remain indefinitely at this point waiting for the client to show up to continue the process or for the final documentation to be delivered. Customers are presented with a receipt containing the eFlow folio number. I want any of the users in this stage to be able to process the document.

The best solution in this case is to create a user called "queue", for example. With your waiting queue user and a password that no one is going to use.

The documents are assigned to this fictitious user at the stage where the documents are accumulated.

At the same stage, support permission is given to the group of users who will be serving the clients as they arrive.

The user, takes the customer's receipt, selects to search for folio through the folio search page. He writes the folio number, and if the document is in the queue stage, it will appear for him to carry out the process in eFlow.

The advantages of solving the problem in this way are:

  • If users intervene in several stages, they do not have to be seeing this large list of documents that is processed very indefinite. They remain "hidden" so to speak.
  • The stage, being assigned to a fictitious user, does not accumulate time to any real user, since the process in this case depends for a client to show up when they have time.
  • The procedure to locate the document is much faster.
  • Any other assignment algorithm will designate the job to staff who will not necessarily attend to you when the time comes for the client to show up, for this reason it is not advisable to assign the process to no one in particular.

I want to create some stages with escalation between users if one cannot resolve within a certain time

We create the stage that performs the main activity. And we configure it as "Manual / Automatic". And we give the destination stage "2 -- Escalation Level 1", for this example.

We configure stage 2 as "Manual / Automatic". And again we configure so that the folio is moved to "Level 3".

If the user updates personally, he or she will advance the document to stage "4". But if the station time expires, the document goes up to the next escalation level.

Even if we configure stage "3" as "Manual / Automatic" and create stage "1" as a predefined destination, we are going to create the effect that the document will be jumping between the possible members who can give it a solution, until someone takes the sheet and processes it.

ALTERNATIVE OPTION (with programming)

We create a single stage as "Manual / Automatic" (the first stage of the activity). And we add the following post-process to the stage, with the logic described in the example.

sub main1 {
    if ($AUTOMATIC) {
        $in{'opt_station'} = $in{'station'};
        $ef_user = *nextUser()*;
        $in{'alarm'} = *{ minutos para siguiente escalamiento }*;
        $in{'ef_time'} = *60*;
        return 0;
    }
}

sub main2 {
}

sub nextUser {
    *{ función que regresa siguiente usuario en el escalamiento }*
}

1;

I want clients or external citizens to register procedures from the Internet

When one considers this service for clients, suppliers or citizens, the first question is whether one should assign them an eFlow account and password to enter the system.

The short answer is "It depends."

  • If we have few users and we want to integrate them into our processes. It can be done.
  • When the users are going to be thousands or hundreds of thousands. and what What we want is to offer the possibility of starting the procedures from your offices or in their homes. It is best to create a portal that collects and control the information required for the procedure and when Once it has been correctly requested, internally open a folio tracking in eFlow and only give the reference to the client external. With another portal you can make a monitoring report that is as explicit and detailed with the information we want can consult. Benefits of this approach.
  • If the access portal is made on a different server, internally the volume will not affect internal operations of the users. Probably the service is attention to citizens and thousands of procedures are received daily, but there is a small team for eFlow because internally the process is served by 20 users. Which better distributes the load of accesses to the server.
  • The processing server is isolated from reception and access open, which increases security because users External servers do not have direct access to the process server.
  • It allows me, through personalized reports, to define what information I want you to see in the follow-up, since Internally, the information that is parameterized in eFlow contains sensitive data that should not be seen in the history by the external applicant. Likewise, we do not wish to give information about contact of the person who has the procedure at that moment to not to disturb him or try to pressure him to release a Procedure.
  • Access control can be implemented for more users suitable for users. Accounts and passwords, certificates digital, free access, etc. Without compromising the internal system of eFlow for this.

I want a folio located in an automatic station to move considering other events not only the expiration of the folio in the station

Create a post-process like the following and evaluate your expression, if this is true the document advances otherwise it remains without advancing.

sub main1 {
    if ($AUTOMATIC) {
        $flg = __*calcular evento;__*
        if ($flg) {
            # has más cosas
        } else {
            $in{'opt_station'} = '';
            return 0;
        }
    }
    # Esto se ejecuta tanto en automático como manual
}

sub main2 {
}

1;

Quiero incrementar la seguridad de acceso a la base de datos de PostgreSQL

No deseo que otros programas locales tengan acceso sin cuenta y contraseña a la base de datos de eFlow.

  1. Edite pg_hba.conf para que solicite autenticación md5 en conexiones locales.
  2. Edite Pg_VB.pm, y fieje $user y password al usuario de eflow. Puede dejar los valores fijos o que se den por omisión si no se especifica alguno. Ejemplo :

pg_hba.conf

local all all md5

Pg_VB.pm

sub connectdb {
    my $user = @_ ? shift : 'eflow';
    my $passwd = @_ ? shift : '*passwd*';
}

PostgreSQL will run on a different server than where eFlow is installed

  1. Configure remote access permissions in pg_hba.conf on the server from postgresql
  2. Same as the previous example, but we add the connection to the server remote in Pg_VB.pm

pg_hba.conf

local all all md5

Pg_VB.pm

sub connectdb {
    my $user = @_ ? shift : 'eflow';
    my $passwd = @_ ? shift : 'passwd';
    $self->{'dbh'} = DBI->connect("dbi:Pg:$db;__*host=$host;port=$port__*",$user,$passwd);
}

Use of print_doc.pl or print_doc.cgi library

print_doc.pl is used when you want to print a form after updating a folio. In this case calling it from post-process2.

When configured in a post-process, parameters must be added to the line: document_path, valid_station, [0 if a capture is to be performed and then printed, 1 if it is to be printed without capture something before]. Example :

/home/eflowweb/cgi-bin/formats/my_format.htm,1,0

/home/eflowweb/cgi-bin/formats/my_format.htm,1,1

print_doc.cgi is used when you want to print a form in a pop-up window, calling the routine from a link in the station form. The path to the document must be configured in the designer in the doc variable. Example:

/cgi-bin/eflow/lib/print_doc.cgi?doc=/home/eflowweb/cgi-bin/docs/my_form.htm&cmd=[0 or 1]

The format of the document must be HTML, and within the format tags must be inserted that will perform different functions when the document is displayed.

The general format of the labels is: Instructions:options:parameters

The possible instructions and their result are explained in the following table.

Instruction Options Action Example
SYS PERL global variable name Print the value [[SYS:Sdate]
IN Form field name Print value $in{'field'} [[IN:folio]
FOLIO folio_fields+:format Displays one or more concatenated data [[FOLIO:ff45 ff46 ff77]]
dateL (date) Presented in date format [[FOLIO:ff88:dateL]]
DBSEL Query to DB Display field [[DBSEL:table:id:name]]
SEL Fixed list Display combo [[SEL:Primary|Secondary|High School]]
EXEC Load a program and execute routine [[EXEC:mi_prog.pl:rutinax]
TEXTAREA Displays text area [[TEXTAREA:Initial legend:45]]
Any name text field Displays a text field [[my_text:Legend:20]]