Visión funcional
Estamos de vuelta con una funcionalidad que ya hace un tiempo que tenemos disponible en nuestros entornos D365FO. Se trata de la integración de nuestro entorno con un sistema de fabricación de terceros mediante el intercambio de mensajes por API.
En la siguiente imagen podemos ver el objetivo de esta funcionalidad. Así como D365FO llevará a cabo el control de stock y la funcionalidad propia de ERP, el sistema externo proporcionará a Dynamics datos sobre el estado de la fabricación.
Este sistema de terceros tanto puede ser una aplicación compleja de control en planta como un simple sensor de presencia que va leyendo el paso de elementos por una linea de producción. Lo único que necesitamos es que estos impulsos/eventos se traduzcan en mensajes para poderlos enviar a la API de D365FO.
Los distintos eventos y mensajes que se intercambian entre ambas plataformas pueden ser los siguientes:
Nombre del proceso | Descripción |
Cambios de estado del pedido de producción | D365FO indica a MES los cambios de estado de las producciones |
Inicio del pedido de producción | MES indica a D365FO qué pedidos de producción iniciar |
Notificado como terminado | MES indica a D365FO qué cantidades se han producido |
Consumo | MES indica a D365FO qué productos se han consumido |
Tiempo consumido | MES indica a D365FO los tiempos de operación |
Finalizar pedido de producción | MES indica a D365FO la finalización de un pedido de producción |
El detalle de cada uno de ellos así como los campos que podemos proporcionar a la API los podéis encontrar en la documentación oficial de la característica:
Este intercambio de información se produce en tiempo real y D365FO va procesando los mensajes recibidos mediante un proceso por lotes configurado.
Podemos consultar los mensajes recibidos en la siguiente ruta:
Control de producción / Configurar / Ejecución de la fabricación / Integración de sistemas de ejecución de fabricación
En la siguiente imagen podemos ver la estructura del control:
Como podemos observar los mensajes (grid de arriba) se ordenan por orden de llegada y van referenciados a la orden de producción que hayamos introducido en el mensaje.
En la columna "Tipo de mensaje" nos indica qué tipo de proceso descrito en la tabla anterior se va a producir.
En la columna "Estado de mensaje" vemos en qué situación se encuentra ese mensaje:
En cola: el mensaje está pendiente de ser procesado hasta un máximo de 3 intentos
Con error: después de 3 intentos el mensaje queda marcado como error y todos los mensajes de esa producción quedan "En cola" hasta que se resuelva este caso
Cancelado: el mensaje ha sido cancelado por el usuario mediante el botón Cancelar. Solo se pueden cancelar mensajes que estén en estado "Con error". Una vez cancelados no son tomados en cuenta por el procesamiento.
Procesado: el mensaje se ha ejecutado con éxito.
Mediante los botones del panel superior podemos realizar las siguientes acciones:
Proceso: nos permite ejecutar manualmente mensajes que estén en estado "En cola" o "Con error"
Editar antes de registro: nos permite modificar manualmente parámetros del mensaje para poder procesarlo satisfactoriamente. Si hacemos click nos abre la ventana estándar del proceso en particular.
Cancelar: nos permite cancelar mensajes que estén en estado "Con error"
Cola: nos permite volver a poner en cola mensajes con estado "Con error"
En el grid inferior podemos ver el contenido del mensaje así como un histórico de su procesamiento y consultar el log del error.
Las imágenes siguientes son relativas a un proceso de finalización de una orden de producción:
Como pincelada final a la parte teórica del proceso es importante destacar que el procesamiento es independiente para cada orden de producción; es decir, cada orden de producción toma su propio hilo de procesamiento y no se ve alterada por los errores de los demás mensajes. Sin embargo, si una orden de producción tiene un mensaje erróneo, el procesamiento de mensajes para esa orden queda retenido hasta que se solvente el problema.
Es por ello que es interesante configurarse alertas o avisos para que el responsable de planta sepa si en algún momento ha ocurrido algún error que obstaculice el procesamiento de los mensajes.
Visión técnica
Ahora vamos a ver más en profundidad la parte técnica de esta funcionalidad.
Primero de todo definiremos cual es la URL de la API que hay que atacar con los mensajes:
{URLEntorno}/api/services/SysMessageServices/SysMessageService/SendMessage
La estructura general de los mensajes en común en todos y va definida en el cuerpo del mensaje:
{
"_companyId": "dataAreaId",
"_messageQueue": "JmgMES3P",
"_messageType": "ProdProductionOrderStart",
"_messageContent": ""
}
Donde:
_companyId = dataAreaId de la empresa de destino del mensaje dentro de D365FO
_messageQueue = corresponde a un enumerado que distingue las distintas colas de mensajes de D365FO. En esta funcionalidad en particular esta propiedad es fija con el valor "JmgMES3P".
_messageType = corresponde al enumerado sobre el tipo de mensaje dentro de esta cola. Puede tomar los siguientes valores dependiendo del proceso a realizar:
ProdProductionOrderStart
ProdProductionOrderEnd
ProdProductionOrderReportFinished
ProdProductionOrderRouteCard
ProdProductionOrderPickingList
_messageContent = corresponde al contenido propio del mensaje y depende de la operación a realizar.
A continuación os dejo un ejemplo para cada tipo de operación:
Proceso | Cuerpo de ejemplo |
ProdProductionOrderStart | { "_companyId": "USMF", "_messageQueue": "JmgMES3P", "_messageType": "ProdProductionOrderStart", "_messageContent": "{\"ProductionOrderNumber\": \"P000211\"}" } |
ProdProductionOrderEnd | { "_companyId": "USMF", "_messageQueue": "JmgMES3P", "_messageType": "ProdProductionOrderEnd", "_messageContent": "{\"ProductionOrderNumber\": \"P000214\"}" } |
ProdProductionOrderReportFinished | { "_companyId": "USMF", "_messageQueue": "JmgMES3P", "_messageType": "ProdProductionOrderReportFinished", "_messageContent": "{\"ProductionOrderNumber\": \"P000214\", \"ReportFinishedLines\": [{\"ItemNumber\": \"L0100\", \"ReportedGoodQuantity\": 1, \"ReportAsFinishedDate\": \"2021-01-01\"}]}" } |
ProdProductionOrderRouteCard | { "_companyId": "USMF", "_messageQueue": "JmgMES3P", "_messageType": "ProdProductionOrderRouteCard", "_messageContent": "{\"ProductionOrderNumber\": \"P000214\", \"RouteCardLines\": [{\"OperationNumber\": \"10\"}]}" } |
ProdProductionOrderPickingList | { "_companyId": "USMF", "_messageQueue": "JmgMES3P", "_messageType": "ProdProductionOrderPickingList", "_messageContent": "{\"ProductionOrderNumber\": \"P000214\"}" } |
Con toda esta información en cuenta solo tenemos que añadir la autenticación en la cabecera de la llamada y ya tendremos nuestro MES integrado.
Vamos a ver un ejemplo de la llamada para iniciar una orden de producción:
1. Obtenemos el token de acceso al entorno
2. Realizamos el envío del mensaje
A continuación os dejo un enlace al repositorio de Github donde encontraréis una colección de Postman para hacer todas las llamadas de las que estamos hablando solo configurando las distintas variables.
Desde luego con esta funcionalidad podemos integrar en tiempo real el control en planta de una empresa y, tomándolo como base, crear nuevos tipos de mensajes a intercambiar para otras aplicaciones de terceros. ¿Os atrevéis a probar?