Introducción.
Antes de nada, indicar que si este ejemplo/producto sirve para alguien es porque el receptor conoce y disfruta de PHPRunner.
Aunque su ejecución se realiza en PHP y MySQL, no es una solución para cualquiera que desee un workflow para esa plataforma de explotación, ya que el diseño y construcción están fuertemente adaptados a la funcionalidad del citado producto, PHPRunner.
También, para poder entender lo que intento expresar en este texto es necesario conocer la filosofía de funcionamiento del producto, filosofía que no se va a explicar en este artículo y que se puede obtener de la abúndate documentación que dispone el fabricante en su web.
En esta última versión he utilizado PHPRunner 9.8 en donde el fabricante ha incorporado muchas nuevas funcionalidades y sobre todo, el runtime de PHP puede ser la versión 7.1
¿Por qué utilizar PHPRunner como framework de desarrollo de un workflow?
Cada vez que me he enfrentado a la mecanización de un procedimiento, siempre, además del propio Workflow, hay necesidades del tipo:
- Mantenimiento de tablas catálogos.
- Explotación de la información fuera del procedimiento.
- Explotación estadística de los datos.
- Integración con otros sistemas de información.
En todos estos aspectos, PHPRunner es muy bueno, por ello pienso que la solución de utilizar PHPrunner es correcta.
Las soluciones que disponen de una solución de workflow tienen serias dificultades para desarrollar el resto de las funcionalidades que requiere un sistema completo.
Otro aspecto que he tenido en cuenta es la gran capacidad y facilidad que nos da este producto para desarrollar cualquier formulario, tanto en el alta del expediente como en cualquiera de sus trámites, siendo en esta funcionalidad de capacidad casi infinita.
Objetivos del diseño del workflow
El workflow que se utiliza en la presente solución es una solución muy simple, pero potente, que se basa en una diagramación de cambio de estado y la transición de un estado a otro se realiza a través de lo que he llamado “trámite”.
Aunque mi vida profesional, principalmente ha estado unida a una empresa de la administración pública, creo que este tipo de solución es válida para cualquier empresa en la que se describan sus procesos y que se ejecuten en ella a través de flujos de trabajo con los conceptos de expedientes, estados, trámites y usuarios.
La solución tiene estos principios básicos que la condicionan fuertemente:
Es para usuarios del producto PHPRunner.
- Debe gestionar la generación de documentos Word en su formato DOCX, además de otros formatos como PDF.
- Debe poder almacenar y gestionar documento DOCS, PDF y cualquier otro formato que se requiera.
- Debe ser multiflujo o gestionar en el mismo producto varios flujos de trabajo para que los usuarios sólo se tengan que conectar a un único aplicativo.
- Los trámites sólo le deben aparecer y permitir la ejecución si el usuario está autorizado.
- Los usuarios, dispondrán de un sistema de seguridad distinto dependiendo del tipo de expediente.
- El sistema dispondrá de una gestión de “Alertas” para recordar situaciones que requiera acción de los usuarios a una fecha.
- Se debe mantener la filosofía de construcción de PHPRunner para mantener la productividad de este producto.
- Debe ser fácilmente integrable con cualquier otro sistema. Siempre que se pueda se utilizará la tecnología de webservices para estas integraciones.
Solución técnica aplicada.
Más adelante se detallará cómo se han “conseguido” estos objetivos. Ahora voy a explicar algunas de las soluciones técnicas que se han empleado.
Para la generación de documentos DOCX o PDF se va a utilizar Jasper Reports Server principalmente, en su versión free u opensource. También, y se ha añadido en la última versión, se utiliza PHPWord para la confección de documentos y así disponer de un aplicativo 100% PHP.
La integración de Jasperserver se ha hecho utilizando el interface REST que incorpora esta solución para PHP, por lo que los documentos a producir, al igual que los reportes que se deseen, son muy potentes y de alta calidad. Esta integración, en sí misma, puede ser válida para cualquiera que desee incorporar a PHPRunner de una herramienta de reportes muy potente y barata. Normalmente no utilizamos este tipo de producto para hacer reportes, me gusta mucho más la solución de integrar PHPexcel y producir los informes en formato XLSX.
Para utilizar Jasper Reports Server no hay que ser un especialista en J2EE, que es en lo que está construida esta solución. Nada más que hay que seguir las instrucciones de instalación estándar y después instalar la solución de Jasper Studio para definir los informes. Existe muchísima información y ejemplos para poder utilizar de forma básica este producto.
Para la gestión de archivo he utilizado en el ejemplo la solución más sencilla, es decir, almacenar los ficheros en campos BLOB en tablas o en File System (en la DEMO está en File System). Fácilmente podéis pasar la solución para almacenarlos cualquier otro producto de archivo documental.
Para la firma y verificación de documentos firmados digitalmente, no he incorporado ninguna solución. En España se facilita –por la AGE (Administración General del Estado)- @firma que permite a los usuarios firmar y verificar los documentos firmados, ya sean PDF o cualquier otro formato, por lo que dicha complejidad no se incorpora a la aplicación si no que los usuarios la usarán con la solución que más les guste. Lo que si incorpora la solución es que un documento del expediente puede tener uno o más ficheros, pudiendo ser estos diferentes o uno mismo en sus diferentes estados de tramitación.
Todos los tipos de expedientes van a disponer de un conjunto de datos básicos –que se pueden cambiar-, que van a estar todos ellos compartidos en unas tablas básicas. Esto no quita para que por cada tipo de expediente existan formularios específicos para cada uno de ellos, tanto en el alta como en la edición de los mismos.
Las tablas básicas del modelo son:
Para cada tipo de expediente, se puede extender el modelo de datos con tablas específicas de dicho tipo en la forma que se explica en el siguiente dibujo.
Se observa que estás extensiones pueden ser a nivel del Tipo de Expediente o de cada una de las instancias de Expediente.
Uno de los problemas que no he sabido resolver en la gestión de accesos que incorpora PHPRunner son las dependencias de que un usuario pueda o no acceder a un tipo de expediente “ClaveExpedientes” y sí a otros, por lo que he definido una estructura de datos que gestiona estas dependencias y a través de las funcionalidades de PHPRunner se integre estas restricciones a las que ya dispone la solución.
Las tablas para soportar este modelo de gestión de acceso son:
Aquí se pueden observar varios conceptos que conviene explicar.
- Cada tipo de Expedientes tiene un conjunto de grupos de acceso. Un usuario puede pertenecer o no a estos grupos y puede pertenecer a varios grupos.
- En la propia definición de grupo de acceso va a informar si quién disponga de este grupo puede o no dar de alta casos de expedientes o incluso editarlos.
- Los trámites de los Expedientes son las acciones de transitoriedad de un estado a otro de los distintos estados del tipo de expediente.
- El estado fija qué trámites se podrán ejecutar en ese caso de expediente.
- También, el estado fija qué grupos de acceso van a poder realizar esos trámites.
- Para cada Trámite en el sistema se indica a qué otros estados puede transitar.
- Existe el concepto de Utilidad. Una utilidad es una acción sobre el caso de expediente que no depende del estado del mismo .
- Para ejecutar esta “utilidad” la misma debe estar asociada a un grupo de acceso que tenga el usuario.
- Los usuarios siempre van a trabajar con un único tipo de expediente. Lo que siempre van a poder hacer es cambiarse de tipo de expediente de uno a otro que tengan asignado.
- Cuando accedan al aplicativo lo harán con el último tipo de expediente con el que hayan trabajado.
Para explicar algunos aspectos de detalle del modelo pongo el conjunto básico de tramitación y seguridad.
Explicación de algunos atributos del modelo.
- “TituloMenu”.- Tanto en Tramite como en Utilidad, es el literal que va a aparecer en el bloque del menú del aplicativo.
- “ClaveMenu”.- En Tramites será algún valor de TR01 a TR10 y esta clave servirá para fijar en el menú de la aplicación. El número da orden. En el mismo estado no puede haber 2 trámites que tengan el mismo valor. La misma funcionalidad tiene en las utilidades y en este caso los valores son de UT01 a UT10. Se podrían poner más posibles claves.
- “URLTramite”, ”URLUtilidad”.- Son los nombres de los formularios de los trámites y de las Utilidades. Normalmente será el formulario de una vista de PHPRunner en su acción EDIT. En el proyecto hay “plantilla” para los formularios de:
- Alta, Edición y Visualización de cada tipo de Expediente.
- Trámite
- Utilidad
- “ClaveTramitacion”.- Este campo es de la entidad Tramite y servirá para dar funcionalidades distintas al mismo formulario de Trámite. Un mismo código y 2 funcionalidades.
- La entidad de “Informes” se usará cuando se realice el Trámite o Utilidad con el que está relacionado. Resumiendo, cuando se realice el Trámite se obtendrá el documento –informe- que esté definido en PHPWord o JasperServer.
Aspectos de presentación e interfaz.
Hemos utilizado una de las plantillas Bootstrap que trae PHPRunner y se ha personalizado para dejar este aspecto:
Veremos que en cabecera sale el título del tipo de expediente con el que estemos trabajando en ese momento.
El menú de la aplicación se queda en el borde izquierdo y las opciones de menú con contextuales al usuario. Unas opciones de acuerdo a las definiciones de seguridad que se tenga según modelo de PHPRunner y otras de acuerdo al tipo de expediente con el que estemos trabajando, al usuario conectado y al caso de expediente que hayamos seleccionado.
Una de las funcionalidades nuevas que se ha incluido es la posibilidad de representación gráfica del flujo de tramitación del tipo de expediente seleccionado. Se utiliza la representación de UML flujo de secuencia.
Los demás aspectos del interface quedan totalmente abiertos a las posibilidades de PHPRunner y a lo que la instalación / empresa, requiera.
También, indicar que en la consulta de los casos de expediente que puede tratar el usuario se ha utilizado la funcionalidad de solapas para obtener los expedientes que se pueden tramitar según su estado y el usuario conectado y todos los casos de estos expedientes. Esto es personalizable a través de PHPRunner.
En la figura se puede apreciar que el código de expediente está en rojo porque existe una Alerta vencida. Recordar que una alerta es un “mensaje” que vence a una fecha en donde nos avisa que hay que hacer una acción sobre dicho expediente. Por ejemplo, esperar contestación en los 20 días laborables siguientes al requerimiento de dicha documentación.
Seguridad e interfaz
Para facilitar el mantenimiento y reutilización de código se ha creado un conjunto de código externo bajo el directorio /ICM/. Este código se ejecutarán en los distintos eventos en los PHPRunner permite añadir código. Normalmente se ha utilizado variables de sesión para guardar, mantener y utilizar la información facilitada en las funciones
Algunas de las funciones son:
- CargaListaUtilidad(). Guarda en $_SESSION[‘CodigoUtilidades’] las utilidades del tipo de expediente que puede utilizar el usuario.
- CargaListaTramites(). Guarda en $_SESSION[‘CodigoTramites’] los trámites que puede realizar el usuario en este caso de expediente que previamente ha seleccionado.
- InsertLogTramites($values, $oldvalues). Para añadir un nuevo LOG de trámite que sea ejecutado.
- InsertLogUtilidades($values, $oldvalues). Para añadir un nuevo LOG de trámite o utilidad que sea ejecutado.
- EstadosSiguientes($CodigoTramite). Esta función facilita el conjunto de estados a los que este caso de expediente puede ir partiendo de su estado actual. Normalmente se utiliza para que el usuario decida mediante selección de estado, a qué estado desea llevar el expediente que está tramitando.
- MiraListados($idtramite). Actualmente los documentos que genera el sistema se elaboran automáticamente al ejecutar un trámite. Es decir, que dependiendo de la ejecución de un trámite el sistema genera los documentos que estén asociados a dicho trámite. Recordar que los documentos se obtienen a tarvés de PHPWord o ejecutando informes en Jasper Reports Server solicitándolos a través de comandos REST. Los formatos de los documentos son todos los que permite Jasper Reports Server.
- ControlAccesos(). Esta función se utiliza en los códigos de los trámites o utilidades para verificar que quién la está ejecutando tiene autorización a ello. Al igual que hace PHPRunner, si alguien sabe o se queda con una URL y la ejecuta fuera del control del aplicativo, esté no le permite su ejecución.
- DarNumeroExpediente(). Es una función simple, que es personalizable, para asignar un nuevo número de expediente o caso de expediente en el sistema.
- DarNumeroDocumento(). Al igual que la anterior es una función personalizable para asignar un nuevo número de documento al sistema.
- ControlAccesoAlExpte(). Utilizando las variables $_SESSION[‘PuedeDarAltaExpte’], $_SESSION[‘PuedeDarEditaExpte’] y $_SESSION[‘PuedeDarVerExpte’] informará al sistema si el usuario puede ejecutar estas acciones en el tipo de expediente que ha seleccionado.
Insisto que estás funciones son las básicas y que se pueden personalizar para cada instalación o empresa.
También, en el código del proyecto se entregan plantillas –vistas de PHPRunner- que se pueden copiar para facilitar las altas, ediciones y visualizaciones de los tipos de Expedientes y de los Trámites y Utilidades.
Variables de sesión que se utiliza:
- $_SESSION[‘idUsuario’] = Id del Usuario
- $_SESSION[‘idClaveExpediente’] = Id de la Clave del Expediente
- $_SESSION[‘TituloExpediente’] = Título de la Clave del Expediente
- $_SESSION[‘CodigoExpediente’] = Código de la Clave del Expediente
- $_SESSION[‘PuedeDarAltaExpte’] = valor 1/0. Si el usuario puede dar alta
- $_SESSION[‘UrlAlta’] = URL del formulario de Alta
- $_SESSION[‘PuedeDarEditaExpte’] = valor 1/0. Si el usuario puede Editar
- $_SESSION[‘UrlEdita’] = URL del formulario de Edición
- $_SESSION[‘PuedeDarVerExpte’] = valor 1/0. Si el usuario puede Visualizar
- $_SESSION[‘UrlVer’] = URL del formulario de Visualización
- $_SESSION[‘idExpediente’] = Id del caso de expediente seleccionado
- $_SESSION[‘NumeroExpediente’] = Número de expediente seleccionado
- $_SESSION[‘idCataEstado’] = Id del estado del expediente seleccionado
- $_SESSION[‘CodigoTramites’] = Id’s de trámites que se pueden realizar
- $_SESSION[‘CodigoUtilidades’]= Id’s de utilidades que se pueden realizar
- $_SESSION[‘EstadosSiguientes’] = Id’s de estados a transitar según trámite
- $_SESSION[‘clavetramita’] = Clave interna del tramite
- $_SESSION[‘idUtilidad’] = Id de la utilidad que se está ejecutando
- $_SESSION[‘utilidad’] = Titulo de la utilidad que se está ejecutando
- $_SESSION[‘UrlUtilidad’] = URL de la Utilidad
El modelo de datos y datos de ejemplo en Mysql y el proyecto PHPRunner lo podéis descargar desde estos enlaces situados en el apartado de “Adjuntos”.
Cambio hecho en directorio de instalación de PHPRunner
Para hacer una presentación de cabecera, menú vertical, datos y pie que yo entendía necesaria, he modificado uno de los «templates» que trae PHPRunner y es algo que no informé y deje como descargable en el artículo.
Si observáis, en la opción de «Style» está definido el template «bspage_sidebarFHP» que es derivado del «bspage_sidebar».
Para que todo funcione tenéis que descargaros el fichero desde al área de descargas y ponerlo en vuestro directorio de «layouts» en donde hayáis intalado PHPRunner.
Por favor, si tenéis algún problema decídmelo a través de email.