Dataverse y Dual-Write: un modelo de datos para Customer Service, Field Service y Marketing

 


Hoy os traigo un artículo basado en un caso real implementado para un cliente. Veréis de primera mano como tuvimos que resolver un problema de compatibilidad de modelo de datos, módulos de D365 y en general… como no todo está “tan listo” para ser desplegado directamente cuando nos vamos a casos más complejos.

Cuando integramos distintos sistemas que requieren trabajar con los mismos datos y gestionar la lectura y escritura en distintos procesos de negocio, es principalmente importante la interfaz que definimos para que los sistemas integrados se comuniquen y podamos asegurar la integridad del dato. Si partimos de una base que nos da Microsoft, en este caso las entidades base de Dataverse y los modelos de datos de los distintos módulos, hay unas reglas del juego y no deberíamos destrozar ese modelo.

Para los que estéis familiarizados con el ecosistema de Dynamics 365 sabéis que está compuesto por una galaxia de módulos para todas las necesidades: Sales, Finance, Supply Chain, Marketing… pero lo cierto es que en cuanto a arquitectura como tal, podríamos diferenciar los que co-habitan en lo que anteriormente se conocía como un sistema CRM y aquellos que forman parte del ERP. Los módulos que corresponden a CRM están construidos sobre Dataverse, comparten un modelo de datos común y desplegar varios módulos en un mismo entorno se vuelve cada vez mas sencillo (con excepciones). En cambio, cuando hablamos de F&O (en el momento en el que escribo este artículo) los datos existen en un entorno totalmente independiente. Seré sincera, no tengo ni la más remota idea de cómo se despliega un entorno de Finance, pero sí conozco bien como integrarme en éste.

Para que los datos fluyan entre los dos sistemas, existe una aplicación conocida como Dual-Write. Quiero evitar dedicarle demasiadas líneas, pero imaginemos que es el puente que conecta ambos mundos, define el mapeado de campos y además ya viene establecido de manera base. Establece el flujo de datos y define el sistema origen (single source of truth) y el tipo de actualización de datos.

Para presentaros este caso de uso, os voy a exponer brevemente el contexto y a continuación pasamos a ver el diseño completo de la solución y las “trampas” o pequeños arreglos que tuvimos que hacer.

Contexto

Un cliente de Retail implementa con nosotros F&O para Retail y extendido con otros 3PL. Los clientes con los que se interactúa pueden ser B2B o B2C (Organización o Persona) y ambos pueden generar compras.  Una vez implementado, se nos pide implementar Customer Service, Field Service y Marketing. Customer Service se utilizará para dar soporte a los clientes sobre el servicio y los productos comprados. Field Service, se utilizará para el equipo técnico de post-ventas, para la instalación (si se necesita) de algunos productos y el soporte técnico para productos específicos. Por último, Marketing se utilizará para realizar campañas de comunicación en distintos canales para todo tipo de cliente.

Partiendo con el modelo de datos de F&O como origen principal de datos y añadiendo los módulos adicionales de D365 utilizamos DW (Siglas de Dual-Write) para asegurar el flujo y la actualización, sobre todo, de los datos de clientes. Nos quedaría (solo con lo descrito) una estructura tal que así:


Los problemas que plantea la solución

Sin entrar en detalle en cada módulo, esta solución nos supone los siguientes problemas en cuanto integridad y estandarización de modelo de datos:

- La integración por defecto de F&O con DW nos permite sincronizar 1:1 la tabla “customers” a “contacts” o de “customers” a “accounts”. Recordemos que tenemos customers de tipo B2B o de tipo B2C por lo que debemos configurar 1 único mapping y se dificulta, aunque no imposibilita, el hecho de coexistir con dos tablas de Dataverse si quisiéramos que los clientes B2B fueran “Accounts” en Dataverse y los clientes “B2C” fueran “Contacts” tal y como recomiendan los guidelines de negocio de Microsoft (Por ejemplo, perder el libro de direcciones).

- Field Service enlaza de manera directa los Activos de cliente (Customer Assets) y las Órdenes de trabajo (Work Orders) con una cuenta de servicio a la que posteriormente, se facturarán los servicios realizados. Por defecto, los activos de cliente enlazados en una orden de trabajo pertenecen a la cuenta de servicio seleccionada (Account).

- Marketing (¡mi querido marketing!) require que las campañas en tiempo real se apunten siempre a Contactos, pues el modelo de datos de Microsoft presupone que las campañas solo se dirigen a personas reales finales, por lo que estos deberán ser siempre contactos (Contacts).

Por si no habéis empezado a visualizar donde tenemos el problema: ¿En qué convertimos nuestros clientes de F&O en Dataverse? ¿Accounts, o Contacts? La lógica nos diría, los B2B serán Account y los B2C serán Contacts. Entonces planteo la siguiente pregunta: ¿Cómo abrimos órdenes de trabajo para máquinas y productos que pertenecen a un B2C si Field Service por defecto no lo permite? Y voy con la siguiente pregunta: ¿Cómo nos aseguramos que los clientes B2B son también incluidos en las campañas de Marketing?

Pues bien, en este momento teníamos que tomar una decisión. Obviamente habíamos realizado integraciones con Dual Write y Customer Service o Field Service, pero cualquier decisión que tomásemos tenía impacto en alguno de los módulos y requería una profunda personalización del modelo de datos. Abrí un foro de debate con el resto de compañeros arquitectos de mi equipo (muy necesario en escenario de este estilo) y planteamos las preguntas:

- ¿Realizamos cambios en el tipo de integración permitiendo la creación de los dos tipos de entradas en las entidades Account y Contacts? Aún sabiendo la complejidad añadida y lo que perdemos en esa integración...

- ¿Salimos de lo establecido para Field Service y creamos campos personalizados para permitir Accounts y Contacts? Obviamente esto se carga por completo el módulo de facturación y afecta también a los Customer Assets.

- ¿Creamos contactos para todo el mundo y así permitir la clasificación de Marketing? ¿Cómo nos aseguramos que la segmentación a partir de datos de ventas se apliquen por igual a Accounts y Contacts?

Y muchísimas más preguntas se incluyeron en un foro largo y muy movido, pues había miles de detalles que ponían en peligro cualquier decisión que tomábamos. Así que decidimos tirar por el recto e informar a Microsoft y buscar la decisión "oficial". Está bien saber que ellos mismos son conscientes de estas limitaciones, pero también sabemos que no éramos los primeros que nos encontrábamos en esta situación. 

La solución final (pero no perfecta)

Al final junto con mi equipo ideamos una propuesta de solución, revisamos el impacto y esfuerzo y tras obtener la aprobación de Microsoft nos lanzamos al desarrollo. La que ahora es la solución ya está funcionando perfectamente en producción:

Diseño comunicación de datos

El resumen de la decisión elegida es:

- Todos los cientes son Cuentas (Accounts) y utilizando un campo los clasificamos entre B2B y B2C.

- Cuando se crea una cuenta en Dataverse, a través de un flujo se crea automáticamente un Contacto con el nombre, teléfono e email y se asigna como contacto principal ( se bloquea su edición y el usuario final no podrá realizar cambios a este contacto).

- Se sincronizan SOLO los elementos de tipo cuenta (Account), evitando así duplicados de contactos en F&O. Cuando se cambia uno de los campos principales de la cuenta en cualquier lado, automáticamente se actualiza el contacto que hay detrás.

- El sistema permite tener otro tipo de contactos para gestionar contactos secundarios de cuentas B2B, asistentes a eventos, Leads y otros…

- Field Service termina trabajando siempre con cuentas, por lo que no hubo que realizar ningún cambio. Tenemos facturación, activos y órdenes tanto para clientes B2B como B2C.

- Los datos de ventas se enlazan a la cuenta que SIEMPRE tiene un contacto principal, por lo que realizamos la segmentación con los datos de cuenta y el target siempre es el contacto, no hubo mucha personalización que hacer en Marketing.

Obviamente la solución no es perfecta, tenemos un duplicado de datos entre cuentas y contactos, pero preferimos eso que realizar grandes cambios en cualquier otros módulos. Creamos un proceso (job) que aseguraba la integridad y simetría de las cuentas y sus contactos, siempre buscando tener una Base de Datos lo más estable posible.

No entraré en detalles, pero para Customer Service solo tuvimos que excluir los contactos generados automáticamente por el sistema, un simple filtro de nada.

La solución nos permite que todos los módulos coexistan a la vez. Es extraño que en tiempos de Dataverse tengamos que estar realizado estos parches que obviamente preferiríamos no tener que realizar, pero se evaluó el esfuerzo VS el riesgo en cada solución posible y para nuestra solución, era lo mejor.

Después lo presentamos como respuesta a Microsoft, los cuales nos han acompañado en todo momento y a los que agradecemos la confianza depositada en nosotros. Espero que este caso de uso sea un ejemplo más de los vacíos que existen aún cuando queremos trabajar con distintos módulos. A la vez, esperemos que cuando los datos de F&O vengan finalmente a Dataverse no empeoren estos escenarios.

Conclusión 

En conclusión, como veis el trabajo del arquitecto es aún muy necesario en estos casos de múltiples módulos por mucho que Microsoft predique el “Common Data Model” entre soluciones. Entender el funcionamiento de todo el ecosistema Dynamics 365 es imprescindible cuando se requiere tomar una decisión así. Agradezco muchísimo estar rodeada de compañeros como Seb Waksmundzki, nuestro maestro Yoda y Fast Track Architect de referencia en KPMG, con el cual trabajé codo a codo para diseñar la arquitectura final que os he presentado hoy.

¿Y vosotros, os habéis encontrado en la tesitura de personalizar el modelo de datos por defecto de D365? ¿Os habéis tenido que pelear con Dual Write para esos campos o entidades que no podíais integrar y habéis optado por otra opción? Contadme vuestras penas y las convertiremos en risas y experiencias 😊 


0 Comentarios