En el anterior artículo estuvimos hablando de una solución que nos iba a permitir personalizar el contenido y la estructura del payload que se envía a través de Business Events de forma drástica, de modo que seamos capaces de adaptarnos a un formato de JSON diferente al estándar de #MSDyn365FO, todo ello sin dejar de utilizar toda la potencia de este framework. Ahora, vamos a pasar a ver con más detalle los pasos realizados para llegar a esta solución.
Como comentábamos en el último post, esta solución la dividiremos en dos partes diferenciadas:
- Identificar los eventos que deben cumplir con el nuevo formato.
- Modificar el payload a enviar en al exterior.
En este artículo concreto, hablaremos de los aspectos técnicos y los pasos llevados a cabo para poder cumplir con el primero de los puntos.
Identificar los eventos en el catálogo de eventos
Para poder identificar correctamente que eventos deben cumplir con el formato específico hemos decidido «marcarlos» dentro del catálogo de eventos.
Cuando lanzamos la funcionalidad que se encarga de generar (o regenerar) el catálogo de eventos de negocio, el sistema recorre todas las clases que están decoradas con el atributo BusinessEventsAttribute y genera un registro en el catálogo de eventos (BusinessEventsTable) por cada una de las clases obtenidas (eventos).
La decisión que se ha tomado para identificar aquellos eventos de negocio que cumplen con estas nuevas condiciones no fue otra que la de imitar la funcionalidad estándar, por este motivo, se generó un nuevo atributo que se encargará de decorar estos eventos específicos, pudiendo indicar el tipo de evento concreto (dato solicitado en el nuevo formato), de forma que, al generar o regenerar este catálogo de eventos, podríamos obtener todas las clases decoradas con el nuevo atributo y marcarlas de algún modo dentro del catálogo de eventos.
Para poder cumplir con este objetivo, se llevaron a cabo los siguientes pasos.
1. Añadir 2 nuevos campos a la tabla BusinessEventsTable.
Para ello, creamos la extensión de la tabla BusinessEventsTable.JATCustomEvent, y añadimos los campos en cuestión:
- JATCustomEvent: Enumerado de tipo NoYes que indicará si ese evento de negocio pertenece o no a nuestro catálogo de eventos personalizados.
- JATEventType: String que almacenará el tipo de evento concreto.
2. Crear nuevo atributo para decorar los eventos de negocio personalizados.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class JATCustomBusinessEventAttribute extends SysAttribute { private str eventType; public void new(str _eventType) { super(); eventType = _eventType; } public str getEventType() { return eventType; } } |
Para generar el nuevo atributo, básicamente hay que crear una clase que herede de la SysAttribute. Aparte, añadimos una propiedad privada para poder indicar en el propio atributo (a través del método new) el tipo de evento en cuestión, y un método que permitirá obtener el valor asociado más adelante.
3. Decorar nuestro evento de negocio con el nuevo atributo.
1 2 3 4 5 6 7 8 9 |
[JATCustomBusinessEvent('Project.ERP.InvoiceCreated'), BusinessEvents(classStr(JATInvoiceBusinessEventContract), "@JATCustomEvent:InvoiceEvent", "@JATCustomEvent:InvoiceEventDesc", ModuleAxapta::Customer)] public class JATInvoiceBusinessEvent extends BusinessEventsBase { ... } |
Como podéis ver, aparte de decorar nuestro evento de negocio con el atributo BusinessEventsAttribute, añadimos el atributo que hemos creado, indicando por parámetros el tipo de evento, valor que se añadirá más adelante al payload.
(Si necesitas más detalles acerca de cómo crear nuevos eventos de negocio, puedes obtener más información en el este artículo).
4. Marcar los eventos como «personalizados» dentro del catálogo de eventos.
Para este último paso, nos vamos a ayudar de la clase BusinessEventsCatalogHelper, ya que es la encargada de recorrer los distintos eventos de negocio del sistema y crear tantos registros como eventos haya dentro de la tabla BusinessEventsTable. Concretamente, vamos a extender el método addCodeBusinessEvents, que es el encargado de realizar esta gestión, añadiendo al final (después del next) el código necesario para actualizar nuestros eventos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
[ExtensionOf(classStr(BusinessEventsCatalogHelper))] final class BusinessEventsCatalogHelperJATCustomEvent_Extension { public static void addCodeBusinessEvents() { BusinessEventsTable businessEventsTable; next addCodeBusinessEvents(); Array customEvents = new Array(Types::Integer); customEvents = DictClass::getAttributedClasses(classStr(JATCustomBusinessEventAttribute)); ttsbegin; for (int i = 1; i <= customEvents.lastIndex(); i++) { SysDictClass businessEventDictClass = new SysDictClass(customEvents.value(i)); JATCustomBusinessEventAttribute businessEventsAttribute = businessEventDictClass.getAttribute(classStr(JATCustomBusinessEventAttribute)); BusinessEventsId businessEventId = businessEventDictClass.name(); select firstonly forupdate businessEventsTable where businessEventsTable.BusinessEventId == businessEventId; if (businessEventsTable.RecId) { businessEventsTable.JATCustomEvent = NoYes::Yes; businessEventsTable.JATEventType = businessEventsAttribute.getEventType(); businessEventsTable.update(); } } ttscommit; } } |
Lo que hacemos en este método es obtener todos los eventos (clases) que están decorados con el atributo que creamos en el paso número 2 y actualizar el registro correspondiente de la tabla BusinessEventsTable de modo que quedará marcado con el valor del campo JATCustomEvent a «Sí» y tendrá asignado el valor del tipo de evento en el campo JATEventType.
Con estas modificaciones ya cumpliríamos con el objetivo de este artículo, identificar los eventos de negocio para que, como veremos en el próximo artículo, seamos capaces de modificar la estructura del mensaje enviado solo para aquellos eventos que necesitemos.
PD: Este código se ejecutará cada vez que alguien lance la acción desde el botón de Volver a generar catálogo de eventos de negocio o cada vez que se realice una sincronización de la base de datos.
2 comments / Add your comment below