Los mensajes se usan para informar a los usuarios de éxito, advertencia, error o informativos.
Su objetivo es guiar a los usuarios en el uso, conocer el estado de la aplicación y en caso de error explican por qué ocurrió y cómo recuperarse.
Hay diferentes mensajes según su objetivo y cada uno tiene una estética diferente.
El mensaje debe ser:
Trata al usuario de tú (no de vos, no de usted) e invítalo a corregir el error, no des órdenes.
Incorrecto: Debe ingresar el código o No ingresaste el código
Correcto: "Ingresa el código"
Antes de escribir un mensaje de error, pregúntate si puedes evitarlo, restringiendo lo que el usuario puede hacer o elegir, incluir alguna lógica para evitar que ocurra el error, etc. En caso que esto no sea posible, hay que tener en cuenta los siguientes puntos al redactar y mostrar el mensaje:
Lo que hizo el usuario, por qué no es correcto y ofrece alguna alternativa para recuperarse del error si es necesaria. A veces no es necesario incluir todas estas partes en el error, si ves que no es necesario o es redundante.
Si para recuperarse del error se necesita más información o realizar otra tarea lo mejor sería tener como parte del mensaje de error un link a ello.
Ejemplo:
En lugar de "fecha inválida" debemos decir
"Has ingresado una fecha de pago anterior a la fecha de factura, revisa la fecha de pago o la factura a la que estás asociando el pago"
En lugar de decir "El período no está abierto" podríamos decir:
"Para hacer operaciones con fecha 12/12/2018, tienes que tener abierto el período de tesorería correspondiente para la unidad organizacional Tres Marías”
No usar "error: " delante del mensaje, ni en ninguna parte de su texto.
No poner "no existe xxx" cuando se está´ingresando, sino "Ingrese xxxx".
Evitar la palabra "inválido".
No usar la palabra "nexo" - usar habilitada para, dependiendo la que más de adecúe.
Por ejemplo "El producto no está habilitado en ......."
Hay ciertas pautas en el desarrollo que contribuyen a tener buenos mensajes.
Antes de escribir un mensaje de error, pregúntate si puedes evitarlo, restringiendo lo que el usuario puede hacer o elegir, ocultar campos que no se deben ingresar en ciertos casos, incluir alguna lógica para evitar que ocurra el error, etc.
Ejemplos:
Preguntas si hay que generar asiento o no para una transacción dada y en caso de que si, pides qué tipo de asiento debes generar.
Bien: Si no hay que generar asiento, no pidas el tipo a generar. Oculta el control en pantalla.
Mal: Dejar ingresar el tipo de asiento y emitir un error : "Si no genera asiento, el tipo de asiento debe ser nulo" .
Este mensaje tiene dos problemas, te deja ingresar tipo de asiento cuando no corresponde y además el lenguaje (nunca uses términos técnicos como "nulo")
Hay otros casos que los mensajes o errores se dan porque la configuración no es correcta. Por lo tanto evitar errores, implica muchas veces poner controles en la configuración. No siempre esos controles se pueden hacer en el momento que el usuario está configurando, porque a veces la configuración pasa por estados inválidos cuando se está en el proceso de configurar, y esto no es evitable.
En ese caso, debemos tener un proceso de CheckConfiguración, que ejecuten siempre luego de configurar, de forma de detectarlos en ese momento y no trasladar el problema al usuario final.
La forma que usa GeneXus para los mensajes de integridad referencial, se basa en datos de implementación. (tablas, atributos).
Por lo tanto hay que modificarlos con RefMsg o el mecanismo que se adecúe.
Si dejamos el default de GeneXus nos saldrá este mensaje: "No existe proveedor unidad organizacional producto" cuando en realidad deberíamos decir "El proveedor Juan Perez no está habilitado en la unidad organizacional Tres Marías"
"Ingresa un proveedor válido" - Cuando no existe la referencia y la misma se está ingresando
"El usuario Juan Perez no está habilitado a operar en la unidad organizacional Tres Marías" - Cuando no existe la relación o habilitación de ese usuario en esa unidad organizacional.
Ver en cada caso si es necesario además decir que es lo que hay que hacer para recuperarse del error. En el ejemplo del proveedor parece que no aporta decir que "ingrese un proveedor válido o de de alta el proveedor". En el caso de que no exista la habilitación de un usuario a un centro, quizás si amerita decirle al usuario donde debe hacer esa asociación o a quien pedirle.
Programa para que solo aparezca el mensaje raíz del error y no todos los que son consecuencias de él.
Esto confunde al usuario y hace que aparezcan muchos errores, cuando en realidad hay uno solo.
Ejemplo 1:
Si en un evento no ingresaste la forma de pago y además la forma de pago debe estar habilitada en la UO, si no haces nada especial van a salir dos mensajes:
Debes evitar el segundo mensaje, ya que es consecuencia del primero.
Ejemplo 2:
No ingresaste la distribución a contabilidad (que es obligatoria) y das continuar...
Antes de controlar que la distribución sea válida, controla que haya sido ingresada. Si no controlas esto, te van a salir varios mensajes producto de controlar algunas "partes" de la distribución, por ejemplo:
Error en la distribución de la linea, El total de la distribución debe ser 100%, etc.
Cuando en realidad el error raíz es que no la ingresaste, por lo que deberías decir solamente:
"Ingresa la distribución"
GeneXus no tiene mecanismo para sustituir los mensajes por default al borrar.
La solución es llamar al BC al borrar y capturar esos errores, y dar un mensaje en dos partes:
No se pudo borrar el proveedor, porque existe información asociada al mismo
y con un ver mas, mostrar todos los mensajes del BC
Cuando invocamos a componentes genéricos, éstos emiten mensajes genéricos que muchas veces no están asociados a lo que está haciendo o visualizando el usuario.
Esto puede provocar que un usuario esté seleccionando órdenes de fondo para pagar (está en un selector de órdenes) y le salga el mensaje "ingrese persona" El error no tiene sentido en su contexto, el usuario no tiene persona para ingresar, no entiende el error y no sabe como recuperarse.
Para evitar resto tenemos que hacer lo siguiente
Ejemplo: Si cuando generaste la orden de stock, mientras el usuario estaba ingresando una orden de compra, y falla algo en la generación de la orden de stock (falta alguna configuración, etc..) sería bueno dar un mensaje relacionado a lo que el usuario está haciendo. (el está ingresando una Orden de compra recuerda)
En K2B existen muchas relaciones entre entidades cuya semántica es "pertenece a" o "habilitado en" o "asociado"
Estas relaciones permiten declarar por ejemplo: Los compradores que trabajan en un centro de compra, las transacciones que puede hacer un usuario, los Centros de Almacenaje que una UO puede usar, etc.
Si dejamos el default de GeneXus estos mensajes serán del tipo "no existe usuario-centro de compra"
Hay que interceptarlos y poner un mensaje que cumpla con la guía general del lenguaje.
La propuesta
Ejemplos
El proveedor no esta habilitado en el centro de compras
El usuario no está habilitado para realizar esa transacción
El usuario no está habilitado a operar en el centro de compras
Muchas veces es complejo dar un mensaje diferente para cada posible problema de los componentes a los que llamo, teniendo en cuenta el contexto del usuario y de donde son llamados. En este caso debemos dar un mensaje genérico y permitir ver más detalle.
"No se pudo generar la orden de stock asociada a la orden de compra ingresada" y luego incluir un "ver detalles" que despliegue los errores dados por los componentes invocados.
Un ejemplo es el selector de órdenes de fondo, luego de que se selecciona, vamos a generar un movimiento de fondos para luego dejar al usuario completar sus datos. Esto es una forma de implementación que no es necesario traslucir inicialmente. O sea, lo ideal sería tener un botón continuar al seleccionar órdenes y seguir. Pero si no somos capaces o es muy costoso ocultar totalmente que estamos generando el movimiento al seleccionar las órdenes, a veces es mejor dejar explícito y en lugar de continuar, que la acción sea generar movimiento. De esta forma si la generación da algún error del movimiento, tendrá sentido para el usuario y lo podrá entender.
O sea, ocultar implementación es muy bueno, pero siempre que se pueda ocultar completamente.
Cuando hay una grilla en un panel, y no tiene datos, el mensaje predeterminado es “No hay resultados”.
Este mensaje debe ser modificado para adaptarse a cada caso, según lo que la grilla esté representando.
Pon semántica a "resultados": Ej: Cuando es una grilla para mostrar órdenes de compra, y hay una búsqueda explícita, es mejor indicar qué es lo que “no hay”, por ejemplo “No hay órdenes de compra”
A veces la palabra "no hay" tampoco es la más indicada para una grilla sin datos. Ejemplo: Cuando estás mostrando información en una grilla, donde al principio no hay datos y el usuario lo tiene que agregar, ahora o después, un mejor mensaje es por ejemplo “Aún no has agregado ninguna orden de compra”
Cuando hay un error de una tarea que se hace Batch desde la bandeja (ej: Posting al autorizar) se envía un mensaje a la bandeja notificando el error.
En este caso al ingresar a ver el error hay que reintentar automáticamente esa tarea. Ver en cada caso
Capturar estos mensajes y en su lugar desplegar un componente más amigable e incluso con humor.
Existen 3 formas de visualizar los mensajes segun el tipo de mensaje de error.
1. Mensajes que se dan durante la interacción, que el usuario puede corregir durante la misma.
Estos pueden ser de dos tipos.
2. Mensajes que deben ser guardados, porque pueden ser procesados por el usuario en otro momento o porque tiene que irse a otras pantallas. Ejemplo: Problemas al confirmar de la registración contable o presupuestal.
Estos se graban asociados al evento u objeto, de forma de poder volver en otro momento y visualizarlos. Muéstralos en el Entity manager del evento u objeto.
3. Mensajes que sirven para encontrar problemas, soporte, mesa de ayuda.
Se sugiere grabarlos en un log, y tener configuración para definir "niveles" de mensajes de log. Un log bien detallado ayuda mucho a encontrar problemas pero degrada la performance. Por lo tanto use sugerimos tener una forma de inhabilitar el log y habilitarlo, teniendo hasta 3 niveles de detalle de log.