Nuestra intención ahora es mostrar un formulario informativo final con todos los datos de la solicitud de compra, incluidos los votos que han autorizado o denegado la solicitud.
Para no perder las versiones anteriores, vamos a duplicar el diagrama MultiParalelo v1.2 subiendo las versiones a 2.0.
Vamos a añadir nuevos BDM.
Opinion será el almacén de cada voto. Contiene un texto con el nombre de usuario del supervisor que verifica la compra y su voto particular.
OrdenCompra2 es prácticamente idéntica al BDM que hemos estado manejando hasta ahora, excepto que también almacena la lista de votos emitidos: votos es de tipo Opinion y de valor múltiple.
El objetivo es que tanto la solicitud como los votos emitidos persistan una vez finalizado el proceso.
Opinion
username STRING
voto BOOLEAN
OrdenCompra2
articulo - STRING
cantidad - INTEGER
precio - INTEGER
aprobado - BOOLEAN
afavor - INTEGER
encontra - INTEGER
votos - Opinion - múltiple
Edita la variable de negocio vncompra. El "objeto de negocio" debe ser com.company.model.OrdenCompra2.
También hemos de editar el "valor predeterminado" initVncompra(). El código debe quedar así:
def ordenCompraVar = new com.company.model.OrdenCompra2()
ordenCompraVar.articulo = vncompraInput?.articulo
ordenCompraVar.cantidad = vncompraInput?.cantidad
ordenCompraVar.precio = vncompraInput?.precio
ordenCompraVar.votos = []
return ordenCompraVar
Tipo de retorno: com.company.model.OrdenCompra2
Básicamente, al cambiar de BDM tenemos que ajustar las referencias donde sea necesario. También inicializamos la lista de votos a una lista vacía.
Una vez modificada la variable de negocio, en la tarea "aprobar" no necesitamos modificar nada excepto las operaciones. Recuerda que esta tarea permite a los supervisores emitir su voto. Hasta ahora solo utilizábamos variables de proceso, no guardábamos esa información en base de datos. Pero ahora queremos añadir los votos a la solicitud. Para ello debemos tratar la salida del formulario.
Añade una operación que actualice al variable de negocio vncompra mediante el método Java addToVotos(). Recuerda que al definir un BDM se crean automáticamente todas las funciones necesarias para manejar el objeto, entre ellas la mencionada, añadir un voto (Opinion) a la lista de votos.
El código asociado a esa función (anyadirVoto)— es un script con este contenido:
def user = apiAccessor.getIdentityAPI().getUser(taskAssigneeId)
String userName = user.getUserName()
def x = new com.company.model.Opinion()
x.setUsername(userName)
x.setVoto(aprobacion)
return x
Estamos trabajando con el tipo Opinion que contiene dos atributos: userName y voto. La primera parte del código accede a la API de Bonita para recuperar la información del usuario que está ejecutando la tarea y, en concreto, su nombre de usuario. La segunda parte aprovecha ese dato y el valor retornado desde el formulario (aprobado) para instanciar un objeto de tipo Opinion que es lo que se devuelve desde esta función.
Aunque esta tarea solo es informativa —no requiere ninguna acción del usuario salvo terminar con el botón "enviar"— vamos a definir un contrato añadiendo desde datos la variable de negocio completa. Tengamos la precaución de marcar que no genere operaciones.
Si lo hemos hecho correctamente, no tendremos operaciones. Y así lo dejamos.
Creamos un formulario (fInformar) y lo examinamos. Vemos una parte "normal", lo que habitualmente nos encontramos en estos formularios generados automáticamente, y un "contenedor repetido", la forma que tiene Bonita de presentar y gestionar listas de objetos en un formulario.
De momento vamos a limpiar el formulario de aquellos controles que no necesitamos: seleccióna el widget select "Votos" y elimínalo. Aprovechamos y recolocamos los demás.
Todos los widgets, excepto el botón de enviar, han de ser de "solo lectura".
En vez de una marca —o la inexistencia de ella— en "Aprobado", queremos conseguir un mensaje algo más descriptivo. Para ello necesitamos una variable nueva:
laaprobacion
Javascript expression
return $data.vncompra.aprobado?"COMPRA AUTORIZADA":"COMPRA DESAUTORIZADA"
Esta variable nos devolverá un texto acorde al valor de verdad del atributo vncompra.aprobado. Recuerda que este es el estado final de la solicitud tras el recuento de votos.
Ahora, cambiamos el widget a TEXT y le damos el siguiente texto:
<br>
ESTADO: {{laaprobacion}}
Vamos a cambiar el widget CHECKBOX "Voto" a RADIO BUTTON. Antes necesitamos una variable con nuestras opciones:
opciones
JSON
[ {"etiqueta": "sí", "valor": true}, {"etiqueta": "no", "valor": false} ]
Transformamos el widget y enlazamos las propiedades.
Para que el formulario funcione como queremos tenemos que vincular a una expresión, es decir, que el formulario sepa que debe interpretar el atributo opciones.etiqueta.
En la "clave mostrada" pincha en el botón fx y, aunque sale una lista desplegable, escribe directamente el texto "etiqueta", comillas incluidas. Parecido en "clave de retorno", pero para "valor".
Al final, el aspecto de "Valores disponibles debe ser este:
Los contenedores de repetición trabajan en base a un iterador: $item. De ahí la expresión $item.voto en "valor seleccionado", o dicho de otra forma, "muestra el voto emitido por esa persona".
Otra cosa que vamos a cambiar es la visibilidad del dato en función de su valor. En la propiedad "oculto" hay definida una expresión que hace que no se muestre nada si el valor del voto es falso. Simplemente la eliminamos.
Ya solo queda que coloques los widgets a tu gusto en función del disposito destino.
Esta es la última parte del "truco" que hemos usado. Al definir una entrada de contrato hemos podido crear el formulario evitando la definición de algunas variables y el poner los widgets de forma manual. Pero es un formulario sin retorno, solo necesitamos presentar los datos. Vamos a limpiarlo de elementos innecesarios.
elimina la variable formInput —si existiera—
elimina la variable formOutput
guarda el formulario
elimina el contrato de la tarea "informar"
Comprueba que todo funciona como se espera.
Datos del caso
Una vez finalizado el proceso solemos comprobar los datos almacenados en el caso archivado. Sin embargo, en este caso, la estructura del BDM es más compleja y la lista de votos no se muestra. Entre otras cosas, para eso hemos montado la tarea "informar".
Otra forma de comprobar lo almacenado es acceder directamente a la base de datos de negocio en el servidor de desarrollo H2.
El esquema de base de datos nos muestra los BDM que hemos definido, en concreto ORDENCOMPRA2 y OPINION. Bonita relaciona ambas tablas mediante una tercera, ORDENCOMPRA2_VOTOS, utilizando el nombre del atributo del BDM OrdenCompra2.votos.
Consultemos esas tres tablas.
Efectivamente, OPINION almacena los tres votos emitidos, identificados por 2, 3 y 4, y los enlaza con la orden de compra 1 en ORDENCOMPRA2_VOTOS mediante las parejas {(1,2), (1,3), (1,4)}.