Ahora que hemos conseguido establecer una conexión entre nuestro sistema de archivos local y Azure y obtener el contenido de nuestro archivo plano con los valores pronosticados, veamos cómo podemos dar un paso más y completar toda la solución.
Concluimos la primera parte sabiendo que teníamos que añadir algunos pasos adicionales:
- Añadir validación al nombre del archivo para filtrar los archivos no deseados que caen en nuestra carpeta, activando nuestra Logic App.
- Convertir el contenido del archivo en un cuerpo JSON legible con el que podamos trabajar
- Conversión de números de semana en fechas que representarán el primer día laborable de la semana en el que podría actualizarse una previsión para un artículo (la capa de servicio de SAP Business One sólo puede aceptar fechas cuando se invoca la actualización de la previsión semanal, a diferencia de la interfaz de usuario de B1).
- Generación de la carga útil para la previsión e incorporación de la generación de previsiones en nuestra solución.
- Algunos conceptos de gestión de errores
Abordemos cada uno de esos pasos y finalicemos nuestra solución.
Añadir validación al nombre del archivo
En primer lugar, queremos añadir una validación que compruebe el nombre del archivo que se está soltando en nuestra carpeta local y se asegure de que aplicamos una convención de nomenclatura.
Esto nos ahorrará ejecuciones innecesarias por nombres de archivo que no se corresponden con lo que la empresa ha decidido respetar.
Digamos que queremos que nuestro nombre de archivo contenga al menos la cadena «Pronóstico». Añadiríamos un conector de control que lo verifique:
Si la comprobación devuelve «True», nuestro flujo se pone en marcha; de lo contrario, cancelamos la ejecución.
Convertir el contenido del archivo en un JSON legible
En este caso, el método sería crear una matriz JSON
array
que contendrá tanto las cabeceras CSV como los elementos.
Nuestro primer paso será añadir una acción «Componer» de la siguiente manera:
Nota importante sobre los finales de línea: Utilicé el componente
decodeUriComponent
para dividir el CSV.
decodeUriComponent(‘%0A’)
Representa un nuevo carácter de avance de línea (LF), a menudo mostrado como \n. Este es el estándar de Unix.
Los archivos CSV generados en Windows pueden utilizar este formato, pero a menudo utilizan un retorno de carro y un salto de línea (CR+LF). Esto se representa como \r\n.
La expresión de división anterior seguirá funcionando con CR+LF, pero se quedará con caracteres \r en sus datos. La expresión correcta para dividir en un CR+LF es:
decodeUriComponent(‘%0D%0A’)
Si carga su archivo CSV en el Bloc de notas, podrá ver fácilmente el formato de su archivo en la esquina inferior derecha. Aparecerá «Unix (LF)» o «Windows (CR LF)».
La función «Split» devuelve un Array y requiere un String como primer argumento. A menudo utilizamos esa función en esta solución, ya que es bastante potente.
La estructura única de nuestro CSV dicta que separemos las cabeceras y los elementos del archivo en dos matrices.
La razón es que cada código de artículo tiene 12 periodos de previsión, y necesitamos actualizar una cantidad diferente para cada periodo.
Observe cómo he utilizado la función primero en mi expresión para obtener sólo el primer elemento de la matriz creada por la función «Split».
Para obtener sólo las filas, utilicé la función «Skip» en mi acción «Componer» y obligué a mi conector a ignorar el primer elemento (= las cabeceras), dejándome así sólo con las filas.
Si ejecutamos nuestro flujo, veremos que la última línea devuelve una cadena vacía:
Para limpiar la salida, añadiríamos una acción «Filtrar matriz» y nos aseguraríamos de utilizar la función «longitud» sólo para seleccionar elementos que sean mayores que cero (0):
Nuestra siguiente acción sería «Seleccionar» donde la fuente sería el array «FiltrarFilas».
Tenga en cuenta que la acción «Seleccionar» sólo acepta matrices como entrada y las itera a través de un bucle interno para mostrar todas las apariciones de un elemento específico:
La acción «Seleccionar» anterior es donde se produce la verdadera magia. Necesitamos reconstruir la carga útil de tal manera que para cada código de artículo, obtengamos la cantidad pronosticada para cada número de semana, donde tenemos 12 semanas en total en nuestro escenario.
Esta es precisamente la razón por la que desacoplé la cabecera de los ítems – necesitamos contar la posición de cada periodo en nuestro array de cabecera y asociarle la cantidad correspondiente desde el array de ítems y, por el camino, ocuparnos de algunas «limpiezas/conversiones de datos»:
- Nuestros números de semana tienen un carácter no deseado (‘W’) que debemos eliminar.
- Nuestros números de semana no se pueden utilizar tal y como aparecen en el fichero ya que SAP Business One espera obtener, para una
previsión semanal
modo
el
primer día laborable
de cada semana que aparecía en nuestro fichero plano.
Mira la salida de nuestra acción «FilterRows»:
Necesitamos identificar la posición de cada elemento, pero no antes de convertir cada iteración de la acción «Seleccionar» en un array.
El «Código de artículo» es el primero, por lo que la posición es 0. Entonces tendrá el siguiente aspecto:
trim(split(item(), ‘,’)
[0]
)
Lo mismo para la cantidad:
split(item(), ‘,’)
[
2………13
]
El resultado de nuestra sentencia «Select» sería el siguiente:
¡Hemos conseguido crear un array JSON significativo con el que podemos trabajar con éxito!
Si lee la Referencia API de SAP Business One Service Layer (vaya a https://<nombre de host>:50000) donde <nombre de host> es el nombre del servidor donde instaló sus componentes de servidor de SAP Business One, encontrará que para parchear con éxito un objeto de previsión semanal MRPdebe incluir la siguiente carga útil en el cuerpo de la solicitud:
Aquí es donde tenemos que añadir más magia a nuestra solución para que esto suceda.
Nuestro archivo contiene 13 periodos que representan la semana #, por lo que necesitaríamos hacer un bucle a través de cada uno de nuestros elementos, pero también necesitaremos anidar otro bucle que se ejecute 13 veces y asignar los valores de pronóstico para cada uno de los periodos #.
Para ello, creemos una variable global llamada
varIDStep
que servirá como numerador/contador en nuestro escenario y pongámosla a ‘1’.
:
Ahora, vamos a añadir dos bucles anidados – un bucle «Do-Until» y un bucle «For each»:
Esto significa que tendríamos que iterar 12 veces por cada código de elemento para asignar los valores.
Cada vez que el bucle interno («For each») finaliza su ejecución (¡Recuerde, itera a través de cada uno de nuestros códigos de ítems!), nuestra variable se incrementa utilizando la acción «Incrementar variable»:
Cuando el valor del contador es 13 también existe el bucle exterior («Until-Do»).
Para optimizar aún más nuestra solución y evitar ejecuciones innecesarias, recomendaría añadir una condición que ignore las iteraciones en las que la Cantidad sea igual a ‘null’:
Observe cómo he utilizado la función «concat» para encadenar la «Cantidad» y nuestra variable (contador) valor de iteración actual, por lo que corresponde a nuestra «Seleccionar» definición anterior :
items(‘For_each’)?[concat(‘Quantity’,variables(‘varIDStep’))]
Esto asegurará que siempre haga referencia a la
actual
actual de «Cantidad» o «Período».
Utilizando esta metodología, la siguiente acción será convertir la representación de la semana que se escribió en nuestro archivo en una fecha que SAP Business One pueda utilizar para contabilizar los valores de previsión (recuerde que es el primer día laborable de la semana).
No voy a profundizar demasiado en cómo se realiza esta conversión, pero eres más que bienvenido a ponerte en contacto conmigo si deseas conocer esta lógica añadida.
Mencionaré brevemente cómo utilizar «Relative Paths» para invocar otro sub-flujo de trabajo y pasar un parámetro a ese flujo.
Observe cómo he definido la ruta relativa en el conector :
/Período/{Period}
El parámetro se pasará a través de una llamada HTTP desde nuestro flujo de trabajo principal de la siguiente manera :
Una vez más, utilizamos el método «concat» para hacer referencia al archivo
actual
dentro del bucle que queremos convertir en fecha.
Una vez convertida la fecha, podemos seguir adelante y preparar la salida y activar el cambio :
El resultado final será que los valores de la previsión se introducen en el cliente de SAP Business One:
Podríamos potencialmente (principalmente para una solución Productiva) añadir algunos pasos de interacción con el usuario que notifiquen al remitente de un éxito/fracaso al final de la ejecución y hacer nuestra solución un poco más «fácil de usar».
Una forma de hacerlo es utilizar una variable Array que se rellenará desde dentro del bucle en tiempo de ejecución cada vez que hagamos una llamada a la Capa de Servicio:
A continuación, podemos comprobar el código de estado de la respuesta que obtenemos y decidir qué matriz rellenar:
A continuación, podríamos utilizar el conector «Enviar un correo electrónico (V2)» en combinación con la función «longitud» para dimensionar la longitud de cada matriz fuera del bucle externo (que es igual a la cantidad de registros correctos/erróneos que obtuvimos):
Resumen
Ahora que nosotros hemos concluido la construcción de nuestra solución, podemos podemos seguir construir escenarios de extensión que combinen esos enfoques «heredados» de trabajar con sistemas de archivos locales con enfoques más nuevos que nos ayuden a construir una integración ganadora con nuestros sistemas SAP Business One.
Puede utilizar la plantilla que hemos creado para responder a casos similares en los que un usuario desencadena un evento que se aprovecha posteriormente y se incrusta en nuestro ERP con poco o ningún esfuerzo.
Esta configuración le permite desarrollar extensiones empresariales desacopladas utilizando
Aplicaciones lógicas
con todas las herramientas y servicios proporcionados por
Plataforma Microsoft Azure
en el idioma más le convenga a usted o a su caso de uso.
Si está interesado en más casos de uso que podrían beneficiarse de una configuración tan desacoplada, ponte en contacto conmigo y estaré encantado de escuchar también tus ideas.
Únase a nosotros en la Comunidad SAP Business One para añadir sus opiniones, comentarios e ideas.
Deja tu comentario
Debe iniciar sesión para escribir un comentario.