Diferencia entre revisiones de «Tarea I: Creando una oficina sin papeles»

De Egeasy
Saltar a: navegación, buscar
(Evolucionando el ''workflow'')
(Evolucionando el ''workflow'')
Línea 231: Línea 231:
 
  {{PR|fin}}
 
  {{PR|fin}}
  
<p>Vemos que en la definición de ''Entrada'' hemos incluído los campos que comentamos para comprobar la documentación.</p>También podemos observar que hay una serie de variables declaradas en la definición de nuestro método, que nos permitirán almacenar un recurso del tipo de la variable. La variable lógica '''documentacion_incompleta''', que inicializamos a "verdadero", la utilizaremos para controlar la salida del bucle. Dicha salida se producirá cuando el campo [Documentacion completa?] de la Entrada actual tenga valor "Sí", asignándole el valor "falso" a '''documentacion_incompleta'''.<p>¿Y cómo consultamos dicho campo?</p>Al lanzar la tarea ''Registrar entrada'', ésta la almacenamos en la variable de tipo {{RE|tarea}} '''TareaRegistroEntrada'''. Esto nos va a permitir acceder al ''target'' de la tarea mediante la propiedad [&Destino], que en este caso, es un objeto de tipo ''Entrada'', por lo que podremos acceder al campo [Documentacion completa?] y realizar la consulta. En caso de tener la documentación completa, saldremos del bucle. En caso contrario, lanzaremos la tarea encargada de elaborar un requerimiento, que a su vez tendrá que ser firmada, lanzando también su respectiva tarea.<p>Respecto a la ejecución de las tareas '''Elaborar requerimiento''' y '''Firmar requerimiento''' es necesario hacer un inciso. Al igual que en el lanzamiento de las demás tareas, la tarea '''Elaborar requerimiento''' es asignada a una variable de tipo tarea. Y al igual que en las anteriores, esto lo hacemos para poder acceder al objeto con el que trabaja la tarea, mediante la propiedad [&Destino]. A continuación, se lanza la tarea ''Firmar requerimiento'', pero esta vez con un nuevo parámetro.
+
<p>Vemos que en la definición de ''Entrada'' hemos incluído los campos que comentamos para comprobar la documentación.</p>También podemos observar que hay una serie de variables declaradas en la definición de nuestro método, que nos permitirán almacenar un recurso del tipo de la variable. La variable lógica '''documentacion_incompleta''', que inicializamos a "verdadero", la utilizaremos para controlar la salida del bucle. Dicha salida se producirá cuando el campo [Documentacion completa?] de la Entrada actual tenga valor "Sí", asignándole el valor "falso" a '''documentacion_incompleta'''.<p>¿Y cómo consultamos dicho campo?</p>Al lanzar la tarea ''Registrar entrada'', ésta la almacenamos en la variable de tipo {{RE|tarea}} '''TareaRegistroEntrada'''. Esto nos va a permitir acceder al ''target'' de la tarea mediante la propiedad [&Destino], que en este caso, es un objeto de tipo ''Entrada'', por lo que podremos acceder al campo [Documentacion completa?] y realizar la consulta. En caso de tener la documentación completa, saldremos del bucle. En caso contrario, lanzaremos la tarea encargada de elaborar un requerimiento, que a su vez tendrá que ser firmada, lanzando también su respectiva tarea.<p>Respecto a la ejecución de las tareas '''Elaborar requerimiento''' y '''Firmar requerimiento''' es necesario hacer un inciso. Al igual que en el lanzamiento de las demás tareas, la tarea ''Elaborar requerimiento'' es asignada a una variable de tipo tarea. Y al igual que en las anteriores, esto lo hacemos para poder acceder al objeto con el que trabaja la tarea, mediante la propiedad [&Destino]. A continuación, se lanza la tarea ''Firmar requerimiento'', pero esta vez con un nuevo parámetro.
  
 
==Siguiente tarea==
 
==Siguiente tarea==

Revisión del 12:58 10 mar 2009

Construir una aplicación paso a paso

Hasta ahora, los usuarios del Registro utilizan el software sólo para introducir o consultar datos, sin realizar ningún trámite ni llevar a cabo un procedimiento administrativo.

Supongamos que la organización ofrece becas para la realización de estudios en el extranjero. Estas becas las gestiona el Servicio de Ayudas y Subvenciones. Los interesados deben presentar las solicitudes en el Registro de Entrada y Salida. Un auxiliar del Registro revisa la documentación y, en caso de faltar algo, elabora un requerimiento para el interesado. Este requerimiento debe firmarlo el jefe de servicio del Registro.

Una vez la documentación esté completa, se remite al Servicio de Ayudas y Subvenciones quien resuelve la beca por el procedimiento de concurrencia sin concurso; es decir, que todos aquellos interesados que cumplan con los requisitos recibirán la beca.

Al recibir la documentación, un técnico del Servicio de Ayudas y Subvenciones comprueba la documentación para ver si el interesado cumple con los requisitos. A continuación, procede a elaborar resolución positiva (o negativa). La resolución la deben firmar el jefe del Servicio de Ayudas y Subvenciones y el director de la organización.

Una vez firmada, la resolución se remite al Registro, donde un auxiliar se encarga de darle salida. El procedimiento se puede resumir en el siguiente diagrama.

Procedimiento de concesión de becas

¿Qué nos hace falta?

Para implementar este workflow, primero debemos identificar los ítems de información y, a continuación, definirlos en el sistema. Analizando, vemos que necesitamos cuatro objetos diferentes:

  • Entrada, para las tareas de Registrar entrada de documentación y Comprobar documentación. Este tipo ya lo tenemos definido.
  • Requerimiento, para las tareas de Elaborar requerimiento y Firmar requerimiento.
  • Resolución positiva y Resolución negativa, para las tareas de Elaborar resolución positiva/negativa, Firmar propuesta de resolución, Firmar resolución y Registrar salida de documentación.

Además, todos los documentos relacionados con una solicitud deben almacenarse en alguna parte. Para ello, definiremos también el tipo Expediente de beca.

Por último, debemos definir dos nuevas habitaciones, donde se enviarán sus tareas específicas: la Oficina de Ayudas y Subvenciones y la Oficina de dirección.

Definir los escritos

Definimos el requerimiento de documentación con dos componentes: una componente escrito, para la plantilla del documento, y una componente formulario, para los campos firma.

tipo [Requerimiento de documentación] es contenedor
    [Escrito] es documento
        -plantilla_documento = "Req 001.rtf";
    fin

    [Datos generales] es formulario
        [Firma del escrito] es firma
    fin
fin

Hacemos lo mismo para las resoluciones. En este caso, como las resoluciones la firman dos personas, debemos incluir dos campos firma, uno para la propuesta y otro para la resolución.

tipo [Resolución positiva] es contenedor
    [Escrito] es documento
        -plantilla_documento = "Res 001.rtf";
    fin

    [Datos generales] es formulario
        [Firma de la propuesta] es firma
        [Firma de la resolución] es firma
    fin
fin
tipo [Resolución negativa] es contenedor
    [Escrito] es documento
        -plantilla_documento = "Res 002.rtf";
    fin

    [Datos generales] es formulario
        [Firma de la propuesta] es firma
        [Firma de la resolución] es firma
    fin
fin

Definir el Expediente de beca

Cada vez que se inicie un trámite de beca, abriremos un expediente en el que se recogerá toda la documentación relacionada con el trámite. Este expediente tendrá un número (asignado automáticamente) que identificará el trámite y una fecha de alta que indicará la fecha en la que se inició el trámite. Asimismo, tendrá un vínculo a la Entrada que dio lugar al trámite.

Crearemos el expediente con dos componentes: una componente para el formulario de datos y otra para la colección en la que se almacerán todos los documentos.

tipo [Expediente de beca] es contenedor
    [Datos generales] es formulario
        [Nº de expediente] es timbre
            -certificado.valor = [&Valor_secuencia];
            -certificado.secuencia.nombre = "STR$EXPEDIENTE"; 
            -certificado.secuencia.longitud = 5; 
        [Fecha de alta] es fecha
        [Solicitud] es vinculo
            -vinculo.definicion = [Entrada];
            -vinculo.etiqueta = [Datos generales].[Número] + " (" 
                                       + [Datos generales].[Remitente]->[Datos generales].[Nombre/Razón social] 
                                       + " " +  [Datos generales].[Remitente]->[Datos generales].[Apellidos] 
                                       + ")";
            -vinculo.valores = $matriz([Libro de entrada].[Contenido]);
    fin

    [Documentos] es coleccion
        -nombre_tabla = "TC$EXPEDIENTE_BECA";

        contiene [Requerimiento de documentación]
        contiene [Resolución positiva]
        contiene [Resolución negativa]

        columna [Nombre]
            -columna_bd.nombre = "DOCUMENTO";
            -origen = [&Nombre];
    fin
fin

Por último, necesitamos almacenar los expedientes en alguna parte. Para ello, crearemos un objeto del sistema en los que almacenarlo.

[Expedientes de beca] es contenedor
    [Contenido] es coleccion
        -nombre_tabla = "TC$EXPEDIENTES";

        contiene [Expediente de beca]

        columna [Nº de expediente]
            -columna_bd.nombre = "NUMERO";
            -origen = [Datos generales].[Nº de expediente];
        columna [Fecha de alta]
            -columna_bd.nombre = "FECHA_ALTA";
            -origen = [Datos generales].[Fecha de alta];
    fin
fin

Definir las oficinas

Tan sólo nos queda definir la oficinas y ubicar los recursos necesarios en cada una. En nuestro caso, se reduce sólo al estante de expedientes, ya que es el único recurso común a las tres oficinas.

[Oficina de Ayudas y Becas] es habitacion
    -publico = falso;

    ubicado [Expedientes de beca] 
        -lugar = "Estantes";
fin

[Oficina de la dirección] es habitacion
    -publico = falso;

    ubicado [Expedientes de beca] 
        -lugar = "Estantes";
fin

¿Cómo funciona el motor de workflow?

Hasta ahora nos hemos centrado en definir los ítems de información que nos iban a hacer falta para llevar a cabo el procedimiento de concesión de beca. En los próximos apartados veremos cómo implementar el flujo de trabajo, pero primero explicaremos cómo funciona el motor de workflow de la plataforma.

En egeasy, los procedimientos administrativos se definen en dos pasos. En primer lugar, debe definirse el flujo de tareas. Esta definición se hace en un fichero con extensión nmt. Los ficheros nmt son ficheros de texto plano que se crean en la carpeta Data del proyecto. Una vez definido el flujo de tareas, procederemos a definir los atributos de cada tarea: ítem de trabajo, código que se ejecuta al terminar la tareas, ... Estas definiciones se realizan en ficheros ndf, como hemos hecho con el resto de los recursos.

Comenzaremos con el flujo de tareas. Lo primero que debemos hacer es crear, en la carpeta Data, el fichero concesion_beca.nmt. A continuación, abrimos el fichero con el editplus.

Los ficheros nmt se componen de métodos. Por hacer un símil, un método sería equivalente a un procedimiento de PASCAL. Cada método lanza tareas, invoca a otros métodos y ejecuta sentencias en ODL. Adicionalmente, puede tener parámetros de E/S y variables locales.

Aquí tenemos un ejemplo.

metodo RegistrarEntrada();
    var
        TareaRegistro: tarea;
inicio
    TareaRegistro = $lanzar("Registrar entrada");
    TareaRegistro.[&Destino]->[Datos generales].[Asunto] = "Esto es una prueba";
    $guardar(TareaRegistro.[&Destino]);
fin

En este segmento de código hemos definido el método RegistrarEntrada. A continuación, hemos definido la variable TareaRegistro de tipo tarea. Después hemos definido la secuencia de tareas.

Cuando comienza la ejecución de un método, el motor de workflow posiciona el cursor en la primera línea del método que está justo después de inicio. Comienza a ejecutar línea por línea hasta que alguna de las sentencias lanza una tarea. Entonces, el sistema crea una nueva tarea, le asigna un ítem de trabajo y establece el estado de la tarea a pendiente. La ejecución del método queda detenida hasta que se finalice la tarea. En nuestro ejemplo, al iniciarse la ejecución del método se lanzaría la tarea Registrar entrada.

Cualquier usuario con los permisos suficientes puede ir a la bandeja de Tareas disponibles y comenzar la tarea. Cuando lo hace, la plataforma abre el ítem de trabajo asignado y cambia el estado de la tarea a realizándose.

Cuando el usuario finaliza la tarea, el sistema cambia el estado a terminada y retoma la ejecución del método que invocó a la tarea. En nuestro ejemplo, asignaría a la variable TareaRegistro la tarea que se acaba de terminar. A continuación ejecutaría las siguientes líneas de código, que modifican el ítem de trabajo de la tarea para después almacenarlo.

Un método termina de ejecutarse cuando el cursor alcanza la palabra fin.

¿Cómo comienza a ejecutarse un método?

Todo proceso tiene un punto de entrada que lanza a ejecutar la primera línea del primer método. Este punto de entrada es un tipo de tarea que se define como raíz en los ficheros de definiciones ndf.

Por tanto, para cada proceso que exista en nuestro sistema de información, tendremos que definir una tarea, llamémosla inicializadora del proceso.

Veamos a continuación la definición de esta tarea, que se corresponde con el proceso Solicitud de beca:

tipo [Solicitud de beca] es tarea
    -descripcion = "Proceso que se encarga de realizar la resolución de una solicitud de beca";
    -fuente.definicion = [Registro de entrada y salida];
    -destino.definicion = [Expediente de beca];
    -destino.valor = $crear([Expedientes de beca].[Contenido]);
    -Al_Comenzar.Nombre = "Metodos\concesion_beca.RegistrarEntrada";
    -es_raiz = verdadero;
fin

La forma de indicar que la tarea Solicitud de beca inicia un proceso de nuestro sistema de información es mediante el atributo lógico es_raiz. Dicho atributo tiene asignado por defecto el valor falso, de forma que poniéndolo a verdadero, conseguiremos que dicha tarea inicie un proceso que será lanzado por un usuario.

Ahora bien, ¿sobre qué recurso queremos que se lance la tarea?

Siempre que lanzamos una tarea, es necesario indicar sobre qué recursos podremos lanzar esa tarea. Para ello, ODL proporciona un atributo llamado fuente.definicion. En nuestro caso, indicaremos la habitación Registro de entrada y salida. Esto significa que el usuario podrá lanzar la tarea Solicitud de beca una vez haya accedido a dicha habitación del centro. No obstante, también podremos asignar al atributo la definición de un contenedor, de manera que la tarea se lanzará una vez se haya accedido a un contenedor de ese tipo. Esta opción la contemplaremos más adelante.

El método a ejecutar una vez se lance la tarea, lo indicaremos en el atributo Al_Comenzar.Nombre, que como vemos, tiene asignado el método creado anteriormente RegistrarEntrada. La nomenclatura que se utiliza para indicar el método es especificar la ruta del fichero donde está incluído el método a partir de la carpeta Data del modelo, y una vez indicada la ruta, añadiremos un punto seguido del nombre del método.

Por último, indicaremos en el atributo destino.definicion lo que se conoce como maintarget de un proceso, es decir, aquel contenedor que se asociará al proceso durante su ejecución. El maintarget de Solicitud de beca será un contenedor de tipo Expediente de beca. ¿Por qué? Porque las tareas que se lancen dentro de este proceso y la información que se genere se almacenará en un Expediente de beca. Además, no sólo queremos indicar el maintarget del proceso Solicitud de beca, sino que también queremos crear el expediente una vez se inicie el proceso. Para ello, utilizaremos la función $crear definida en la librería de funciones de ODL, que nos permite crear un objeto, indicándole la colección o exportación donde se va a almacenar. El tipo de objeto será el definido en destino.definicion. El objeto devuelto por $crear se asignará al atributo destino.valor.

Analizando el diagrama de flujo de información

Antes de seguir desarrollando el workflow, vamos a estudiar el diagrama de flujo de información de concesión de becas facilitado al principio de este artículo. Es recomendable que abramos la imagen ampliada en una pestaña nueva del navegador, de manera que podamos ir fijándonos en el diagrama a medida que vamos comentando aspectos de él.

Fijándonos en el diagrama, vemos que el flujo de trabajo está dividido en tres secciones, donde cada una de ellas equivale a una oficina de la organización. Dentro de cada sección existen una serie de estados, que equivalen a las diferentes tareas que se pueden lanzar. Por tanto, habrá que implementar una tarea por cada estado que vemos en el diagrama.

Si las tareas equivalen a los estados, el flujo de trabajo equivaldría a las líneas de transición que nos permiten cambiar de estado. En nuestro método RegistrarEntrada tendremos que implementar este flujo de trabajo. Podemos ver que para lanzar ciertas tareas, habrá que evaluar una condición. Por ejemplo, para lanzar la tarea ComprobarDocumentacion será necesario evaluar si la documentación necesaria está completa. De no ser así, se lanzaría la tarea ElaborarRequerimiento. Por tanto, en la implementación de nuestro método tendremos que plasmar el camino de datos que observamos en el diagrama.

Además, el diagrama nos indica qué tareas puede lanzar un usuario en función de la oficina a la que pertenezca. No obstante, cuando hayamos finalizado la implementación de nuestro workflow dedicaremos un apartado a tratar los usuarios, roles y permisos de este sistema de información.

Evolucionando el workflow

Antes de meternos de lleno en la elaboración del workflow, hagamos un resumen de aquellos ficheros y nuevas definiciones que hemos creado.

Por un lado, para poder desarrollar una concesión de beca, hemos definido un expediente de beca, un registro de expedientes de beca, un requerimiento de documentación y una resolución positiva y negativa de la concesión de una beca con la elaboración de sus respectivos documentos. Todas ellas son definiciones de tipo contenedor, y serán los ítems con los que trabajaremos a lo largo de todo el flujo de información. Además, hemos definido una oficina de ayudas y becas y una oficina de dirección. Todas estas definiciones las hemos realizado en el fichero Main.ndf en la carpeta #Source.

En esa misma carpeta, se encuentra el fichero tareas.ndf donde ya hemos definido la tarea raiz Solicitud de beca y donde vamos a definir el resto de tareas.

Por último, en la carpeta Data\Metodos hemos creado el fichero concecion_beca.nmt donde hemos incluído un ejemplo del método RegistroEntrada.

Una vez hecho este resumen, ahora sí que vamos a desarrollar nuestro proceso Solicitud de beca. Iremos mostrando paso a paso el código que introduciremos siguiendo el camino de datos del diagrama. Iremos alternando la implementación del método y de las tareas según lo vayamos necesitando:

Cuando se produce una Entrada en una concesión de beca, se creará un Expediente de beca único y se registrará esa entrada que además estará asociada al expediente creado. A partir de ese momento, toda la información que genere este proceso tendrá asociado un Expediente de beca, por ello el maintarget del proceso Solicitud de beca será el expediente creado. Por tanto, una vez lanzada la tarea Solicitud de beca y se empeciece a ejecutar el método RegistrarEntrada, habrá que crear un expediente de beca y registrar la entrada recibida:

metodo RegistrarEntrada();
    var
inicio
    $lanzar("Registrar expediente de beca");
    $lanzar("Registrar entrada");
fin
La función $lanzar, lanza una tarea cuyo nombre deberemos pasar por parámetro, como vemos en el código. En este caso, no pasamos por parámetro ningún ítem (target) a la tarea, ya que lo creará la propia tarea, pero veremos que en posteriores definiciones sí tendremos que hacerlo. Además también es posible indicar la habitación o habitaciones en la cuál un usuario podrá comenzar la tarea. En caso de no especificarla, se tomará como habitación la definida en la tarea raiz, que en nuestro caso es Registro de entrada y salida para cada una de las tareas.

Definamos entonces dichas tareas en nuestro fichero tareas.ndf:

tipo [Registrar expediente de beca] es tarea
    -fuente.definicion = [Expediente de beca];
    -Al_finalizar.Codigo = "$sellar([&Destino]->[Datos generales].[Nº de expediente]); $guardar([&Destino]); ";
fin
tipo [Registrar entrada] es tarea
    -fuente.definicion = [Expediente de beca];
    -destino.definicion = [Entrada];
    -destino.valor = $crear([Libro de entrada].[Contenido]);
    -Al_finalizar.Codigo = "$sellar([&Destino]->[Datos generales].[Número]); $guardar([&Destino]); ";
fin

En la tarea encargada de crear y registrar un nuevo Expediente de beca, el atributo fuente.definicion que hay definido ya lo conocemos. En él indicaremos la referencia de la tarea. En el atributo destino.definicion, que no aparece, deberíamos indicar el contenedor (target, ítem) con el que va a trabajar la tarea, pero este atributo, si no se especifica, asumirá como destino el contenedor definido en fuente.definicion. Equivaldría a poner <code>destino.definicion=[Expediente de beca]</code>.

Por tanto, al arrancar esta tarea, se abrirá un expediente nuevo. El atributo Al_finalizar.Codigo nos permite invocar un método o directamente asignarle instrucciones en forma de ristra, que se ejecutarán en tiempo de ejecución. En nuestro caso, hemos indicado que al finalizar la tarea, se selle el campo timbre que existe en cada expediente y además se guarde el objeto. Para que entendamos bien las instrucciones que realizan estas operaciones, es necesario conocer la propiedad [&Destino] de una tarea.

Esta propiedad permite acceder al target actual de la tarea, que en la tarea que nos ocupa, es un Expediente de beca. Una vez en el contenedor, podremos acceder a otros componentes que estén definidos en él, como por ejemplo, a un campo timbre incluído en la definición de un formulario, que es exactamente lo que hacemos en la tarea Registrar expediente de beca. Con la función $sellar, sellaremos el campo timbre, y con la función $guardar, guardaremos el objeto, accediendo a él una vez más mediante la propiedad [&Destino].

Una vez registrado un nuevo expediente, procederemos a registrar una entrada de petición de beca. Si nos fijamos en la tarea Registrar entrada vemos que ya hay varios atributos que nos suenan. La diferencia que podemos observar es la inclusión de los atributos destino.definicion y destino.valor. ¿Y por qué ahora sí están incluídos? Pues porque esta tarea no va a registrar un expediente de beca, sino que registrará una entrada, y por eso le asignamos ese tipo al destino de la tarea. En caso de no hacerlo, volvería a hacer lo mismo que la tarea anterior. Además, al finalizar la tarea, ejecutaremos el mismo código que acabamos de explicar. Pero esta vez, con la propiedad [&Destino] accederemos al contenedor con el que trabaja la tarea, que es una Entrada. ¿Y el atributo destino.valor? Como ya explicamos en la definición de la tarea raiz Solicitud de beca, utilizaremos la función $crear, a la que indicaremos la colección donde se va a guardar el objeto del tipo definido en el atributo destino.definicion. Son dos atributos dependientes uno del otro.


Una vez llegados a este punto, volvemos a fijarnos en el diagrama, y vemos que una vez la entrada es recibida, registrada, y creado su expediente, el siguiente paso, sería comprobar la documentación. Para ello, es necesario que la documentación entregada por la persona que realiza la petición de la beca esté completa. En caso de no ser así, se generará un documento de requerimiento, que deberá ser firmado, dando lugar a posibles nuevas entradas, pero con un expediente de beca ya creado. Esto se producirá tantas veces como requerimientos de documentación se puedan dar. Una vez no falte ningún tipo de documentación, se lanzará la tarea Comprobar documentación.

Pero, ¿y cómo podemos saber si en la solicitud de una beca falta documentación?

Para ello, hemos modificado la definición del contenedor Entrada, añadiendo simplemente un campo tabla para registrar la documentación y un campo de tipo texto llamado [Documentación completa?].

Veamos primero los cambios, para comentarlos posteriormente:
tipo [Entrada] {{PR|es} contenedor
    [Datos generales] es formulario
        ...
        ...
        ...
        [Documentación presentada] es tabla
            [Documento] es texto
        fin
        [Documentación completa?] es texto
            -apariencia.desplegable = verdadero;
            -edicion.seleccion = verdadero;
            -edicion.valores = $matriz([Sí o No]);
    fin
fin
metodo RegistrarEntrada();
    var
        TareaRegistroBeca: tarea;
        TareaRegistroEntrada: tarea;
        ElaborarRequerimiento: tarea;
        ElaborarResolucion: tarea;
        documentacion_incompleta: logico;
inicio
    documentacion_incompleta = verdadero;
    TareaRegistroBeca = $lanzar("Registrar expediente de beca");
    mientras documentacion_incompleta
        TareaRegistroEntrada=$lanzar("Registrar entrada");
        TareaRegistroBeca.[&Destino]->[Datos generales].[Solicitud] = TareaRegistroEntrada.[&Destino];
        $guardar(TareaRegistroBeca.[&Destino]);
        si (TareaRegistroEntrada.[&Destino]->[Datos generales].[Documentación completa?] = "Sí")
            documentacion_incompleta = falso;
        sino
            ElaborarRequerimiento = $lanzar("Elaborar requerimiento");
            $lanzar("Firmar requerimiento", ElaborarRequerimiento.[&Destino]);
        fin
    fin
fin

Vemos que en la definición de Entrada hemos incluído los campos que comentamos para comprobar la documentación.

También podemos observar que hay una serie de variables declaradas en la definición de nuestro método, que nos permitirán almacenar un recurso del tipo de la variable. La variable lógica documentacion_incompleta, que inicializamos a "verdadero", la utilizaremos para controlar la salida del bucle. Dicha salida se producirá cuando el campo [Documentacion completa?] de la Entrada actual tenga valor "Sí", asignándole el valor "falso" a documentacion_incompleta.

¿Y cómo consultamos dicho campo?

Al lanzar la tarea Registrar entrada, ésta la almacenamos en la variable de tipo tarea TareaRegistroEntrada. Esto nos va a permitir acceder al target de la tarea mediante la propiedad [&Destino], que en este caso, es un objeto de tipo Entrada, por lo que podremos acceder al campo [Documentacion completa?] y realizar la consulta. En caso de tener la documentación completa, saldremos del bucle. En caso contrario, lanzaremos la tarea encargada de elaborar un requerimiento, que a su vez tendrá que ser firmada, lanzando también su respectiva tarea.

Respecto a la ejecución de las tareas Elaborar requerimiento y Firmar requerimiento es necesario hacer un inciso. Al igual que en el lanzamiento de las demás tareas, la tarea Elaborar requerimiento es asignada a una variable de tipo tarea. Y al igual que en las anteriores, esto lo hacemos para poder acceder al objeto con el que trabaja la tarea, mediante la propiedad [&Destino]. A continuación, se lanza la tarea Firmar requerimiento, pero esta vez con un nuevo parámetro.

Siguiente tarea

Véase también