API 2.0 Business Central. Como crear pedidos de venta entre tenants - Business Central

Breaking

jueves, 24 de diciembre de 2020

API 2.0 Business Central. Como crear pedidos de venta entre tenants

nivel: Developer

Siguiendo con el escenario de pasar datos entre entornos de Business Central, hoy voy a usar las API 2.0 para hacer un Intercompany pero entre diferentes tenants, con una sola llamada, utilizando lo que se llama Deep Insert.  Es decir, en una sola llamada insertar la cabecera y las líneas del pedido.  El ejemplo será el de una empresa filial en Mexico que hace pedidos de compra a una empresa matriz en España (para ella serán pedidos de venta).  De lo que se trata es de automatizar al máximo la creación de pedidos evitando posibles errores.

API 2.0 Business Central

Las API son puntos de acceso publicados por Microsoft en Business Central que nos permiten consultar, escribir y modificar datos de nuestro ERP desde el exterior, incluido por supuesto desde otro Business Central, lo cual es especialmente útil cuando tenemos diferentes compañías en el grupo, con diferentes localizaciones.

A diferencia de los servicios web oData, las API no hay que publicarlas.  Microsoft se encarga de hacerlo por nosotros.  En el siguiente enlace, puedes encontrar la documentación oficial donde puedes ver todas las API publicadas actualmente.  

Hoy en el ejemplo usaremos las API salesOrders y salesOrderLines para crear un pedido de venta desde un pedido de compra de otro tenant.  Atención no confundir con salesDocuments que corresponde a un servicio web oData publicado. 

Generar Pedido Venta mediante API 2.0

Para realizar el pedido vamos a utilizar una función que recogerá como parámetro el número de Pedido de Compra que exportaremos como Pedido de Venta a la empresa receptora-matriz.


Aunque el código es sencillo voy indicando las instrucciones:

Línea 67.  Corresponde a la URL de la API. Recordad que no hay que hacer nada en SaaS, puesto que por defecto ya están publicadas.  Atención al nombre salesOrders, ya que es sensible a las mayúsculas y minúsculas.  El entorno será vuestro entorno SaaS de destino y companies, será la empresa donde vamos a crear el pedido.

Línea 69 y 70.  Como vimos en la entrada anterior (Como pasar datos entre entornos de Business Central) debemos de tener un usuario que permita acceder a Business Central.  Lo que hacemos aquí es cargar el usuario y la contraseña, convertidos en base64, en la cabecera de la llamada (request).  De momento, mientras podamos, seguimos usando autenticación Basic en lugar de Oauth.

Línea 73.  En esta línea generamos el JSON donde enviarmos los datos del pedido de compra / venta.  Más abajo lo veremos en detalle.

Línea 75.  Cargamos el JSON en una variable HttpContent.  Es decir, el contenido de la llamada a la API incluye un JSON con el pedido a generar.  Ese contenido se guarda en una variable HttpContent.

Líneas 76, 77, 78.  Lo que hacemos aquí es indicarle que el contenido incluido (el pedido) está incorporado en formato JSON para que la API receptora sepa como interpretarlo.

Línea 80.  Aquí realmente hacemos la llamada a la API.  Como sabes si vamos a leer usaremos un GET (como en el post anterior que consultábamos disponibilidades).  En este caso vamos a añadir un pedido de venta, por lo que en lugar de GET usamos POST.  En los parametros de la función le pasamos la URL de la API, el contenido (con el correspondiente JSON) y una variable de respuesta donde nos informará del resultado de la llamada.

La línea 81, simplemente guarda el valor de la respuesta en formato texto para luego poder tratarla.

Componer el JSON del pedido

El JSON que adjuntamos a la llamada POST (función de la línea 63 anterior) debe contener el pedido de venta que vamos a insertar, por lo que tenemos que revisar la cabecera y recorrer las líneas del pedido de compra para crearlo.  Nuestro objetivo será crear algo como esto:

JSON a generar correspondiente al pedido de venta a insertar

Línea 41. "customerNumber".  Si estoy haciendo un pedido de compra desde Mexico, quiere decir que para la otra parte (España) soy un cliente.  Por tanto debo conocer que número de cliente soy para saber a quién crear el pedido de venta.  En nuestro ejemplo el cliente es CLI0001.  Recuerda que disponemos de un campo en la ficha de proveedor llamado "Nuestro nº de cuenta" que se usa precisamente para esto.

Línea 42. "externalDocumentNumber".  Corresponderá al número de documento externo del pedido de venta y pondré el número de pedido de compra, para que en España puedan referenciarlo en caso necesario.

Con estas dos líneas es sufiente para que Business Central, gracias a la API2.0 sea capaz de crear la cabecera ya que tomará la numeración de pedido de venta que le corresponda y las fechas del sistema.  Si necesitas indicarle más datos, como fecha de pedido o dirección de entrega, puedes añadirle los correspondientes campos.  La cuestión es ¿como puedo saber el nombre de los campos disponibles?  Ya te adelanto que no están todos y mucho menos los personalizados.  La mejor opción es utilizar Postman, hacer una llamada con un GET a salesOrders y al obtener la respuesta, veremos los campos disponibles:

Respuesta a la API desde Postman para comprobar los campos disponibles

Líneas del pedido.

Debemos traspasar todas las líneas del pedido de compra al pedido de venta, para lo cual usaremos el elemento "salesOrderLines" de la línea 43 del JSON mostrado arriba. Esta es la nueva funcionalidad de las API 2.0 de Business Central llamada Deep Insert, ya que en la misma llamada estamos insertando la cabecera y las líneas.  En este caso es un array ya que puede contener multiples líneas, por lo que debemos de especificarlo agrupando todas ellas entre los simbolos [ y ]

Cada una de las líneas deberá ir entre llaves { y } y separadas por comas.  Es decir, de la línea 44 a la 50 corresponderán a la línea de pedido 1 (compramos/vendemos un producto), de la 51 a la 56 a la línea del pedido 2 (compramos/vendemos con una cuenta contable) y de la 57 a la 61 a la línea de pedido 3 (ponemos un comentario).  He puesto tres opciones para abarcar más tipología de líneas pero obviamente puedes poner lo que necesites.
Opciones de línea de pedido de compra

Formas de identificar un producto o una cuenta.

Lógicamente deberá haber una relación entre lo que pides en el pedido de compra y lo que vendes en el pedido de venta.  Es decir, debemos de saber que mi producto 1234 en México a que producto corresponde en España.  Si se trata de empresas filial - matriz como en mi caso, no hay problema puesto que ambas tendrán (deberían de tener) los mismos productos, pero en caso contrario podemos usar las "Referencias cruzadas" que como sabemos sirven precisamente para esto.

Cada una de las líneas tendrán varios campos en función del tipo o la forma de identificarlo.

Business Central ahora utiliza un GUID (numerajo largo similar a esto f3af2160-227c-ea11-9be0-d0e787b03942) para identificar de forma única cada producto, cuenta, cliente, empresa,... dentro de nuestra base de datos.  Esto se hace automáticamente cuando se crea cada una de estas entidades y va en la línea ya comentada muchas veces de integrar en un futuro próximo todas los datos de sus aplicaciones empresariales Dynamics 365 en Dataverse (en la entrada de Entidades virtuales hablo de ello).  Por tanto, podemos identificar un cliente o un producto, bien por el número amigable (en nuestro caso 1234) o bien por el número GUID.  La propiedad usada en la API para identificar cada uno será diferente:

"lineType": "Item" y "lineObjectNumber": "1234" si lo que queremos es identificarlo a través del número habitual.  "itemId": "f3af2160-227c-ea11-9be0-d0e787b03942" si lo que queremos es identificarlo a través del GUID.  En este caso no tenemos que decir si es una cuenta o un producto (lineType), puesto que al indicar "itemID" ya le estamos diciendo que es un producto.

Lo mismo ocurre para las cuentas contables:

"lineType": "Account" y "lineObjectNumber": "7050001" o bien "accountId": "8ab89de5-641d-eb11-bbf8-000d3a29cc88"

Las líneas 54 y 55, corresponderán a la cantidad ("quantity") y el precio ("unitPrice").  En caso de que no pongamos el precio, éste correspondería a la tarifa que tuviese especificada el cliente.  Como siempre que trabajamos con diferentes Regiones, mucho cuidado con los puntos y las comas separadores de miles o decimales.  En caso necesario habrá que hacer ciertas transformaciones ya que la API va a entender el punto (.) como separador de decimales.

Para conformar dicho fichero JSON utilizo la siguiente función, en la que no utilizo los nuevos tipos JSON, sino simplemente cadenas de textos:


Lo que hace es recorrer las líneas del pedido de compra y en función del tipo de línea (comentario, cuenta o producto), la compongo de una u otra forma.  En la línea 235, utilizo una cuenta fija ya que el plan de cuentas no será igual en las dos empresas, por lo que siempre la convierto a una definida en la empresa destino.

El resultado es que con una sencillas funciones, estamos traspasando pedidos desde un Business Central a otro usando las API2.0.  Sólo con una llamada. 
 


En la respuesta, si es correcta, nos suministrará el número de pedido generado que luego podemos almacenar para relacionar la información de ambas empresas.


Conclusión

Hemos visto en este post y en el anterior las grandes posibilidades de integración con las API y los web services de Business Central, no sólo con los productos Microsoft, también con otros software.   Seguiré investigando las posibilidades de la API con Dataverse pero se nos abre un abanico impresionante de posibilidades.

Quiero agradecer también al crack Arend-Jan Kauffmann que me ha ayudado a descubrir los errores más tontos en mi código.

Como siempre, cualquier duda, podéis comentarme por aquí o por los canales habituales de Linkedin o Twitter



No hay comentarios: