Maintenant que nous avons réussi à établir une connexion entre notre système de fichiers local et Azure et à obtenir le contenu de notre fichier plat avec les valeurs prévisionnelles, voyons comment nous pouvons aller plus loin et compléter l’ensemble de la solution.
Nous avons conclu la première partie en sachant que nous devions ajouter quelques étapes supplémentaires :
- Ajout d’une validation au nom du fichier pour filtrer les fichiers indésirables déposés dans notre dossier, ce qui déclenche notre application logique.
- Conversion du contenu du fichier en un corps JSON lisible avec lequel nous pouvons travailler
- Conversion des numéros de semaine en dates qui représenteront le premier jour ouvrable de la semaine où une prévision pourrait être maintenue pour un élément (la couche de service de SAP Business One ne peut accepter que des dates lorsqu’elle invoque la mise à jour des prévisions hebdomadaires, contrairement à l’interface utilisateur B1).
- Générer la charge utile pour les prévisions et intégrer la génération des prévisions dans notre solution
- Couvrir quelques concepts de gestion des erreurs
Abordons chacune de ces étapes et finalisons notre solution.
Ajout d’une validation au nom du fichier
Nous voulons d’abord ajouter une validation qui vérifie le nom du fichier qui est déposé dans notre dossier local et s’assurer que nous respectons une convention de nommage.
Cela nous évitera des exécutions inutiles pour des noms de fichiers qui ne correspondent pas à ce que l’entreprise a décidé de respecter.
Disons que nous voulons que le nom de notre fichier contienne au moins la chaîne « Forecast ». Nous ajouterions un connecteur de contrôle qui le vérifierait :
Si la vérification renvoie la mention « Vrai », notre flux est activé ; dans le cas contraire, nous annulons l’exécution.
Conversion du contenu du fichier en JSON lisible
L’approche consiste à créer un tableau JSON
JSON
qui contiendra à la fois les en-têtes et les éléments du CSV.
Notre première étape consistera à ajouter une action « Composer » comme suit :
Note importante concernant les fins de ligne : J’ai utilisé le composant
decodeUriComponent
pour découper le CSV.
decodeUriComponent(‘%0A’)
Il s’agit d’un nouveau caractère de saut de ligne (LF), souvent affiché sous la forme \n. C’est la norme Unix.
Les fichiers CSV générés sous Windows peuvent utiliser ce format mais utilisent souvent un retour chariot et un saut de ligne (CR+LF). Ce phénomène est représenté par l’expression « \r\n ».
L’expression fractionnée ci-dessus fonctionnera toujours avec CR+LF, mais vous vous retrouverez avec des caractères \r dans vos données. L’expression correcte pour scinder un CR+LF est la suivante :
decodeUriComponent(‘%0D%0A’)
Si vous chargez votre fichier CSV dans le Bloc-notes, vous pouvez facilement voir le format de votre fichier dans le coin inférieur droit. Il affichera soit « Unix (LF) », soit « Windows (CR LF) ».
La fonction « Split » renvoie un tableau et requiert une chaîne de caractères comme premier argument. Nous utilisons souvent cette fonction dans cette solution car elle est très puissante.
La structure unique de notre fichier CSV nous oblige à séparer les en-têtes et les éléments du fichier en deux tableaux.
En effet, chaque code de poste comporte 12 périodes de prévision et nous devons gérer une quantité différente pour chaque période.
Remarquez que j’ai utilisé la fonction en premier dans mon expression pour ne récupérer que le premier élément du tableau créé par la fonction « Split ».
Pour n’obtenir que les lignes, j’ai utilisé la fonction « Skip » dans mon action « Compose » et j’ai forcé mon connecteur à ignorer le premier élément (= les en-têtes), ce qui m’a permis de n’obtenir que les lignes.
Si nous exécutons notre flux, nous verrons que la dernière ligne renvoie une chaîne vide :
Pour nettoyer la sortie, nous ajouterions une action « Filtrer le tableau » et veillerions à utiliser la fonction « longueur » uniquement pour sélectionner les éléments qui sont supérieurs à zéro (0) :
Notre action suivante serait de « Sélectionner » où la source serait le tableau « FilterRows ».
Gardez à l’esprit que l’action « Select » n’accepte que des tableaux en entrée et les itère via une boucle interne pour afficher toutes les occurrences d’un élément spécifique :
C’est dans l’action « Sélectionner » ci-dessus que la véritable magie opère. Nous devons reconstruire la charge utile de manière à obtenir, pour chaque code d’article, la quantité prévue pour chaque numéro de semaine, sachant que notre scénario comporte 12 semaines au total.
C’est précisément la raison pour laquelle j’ai découplé l’en-tête des éléments – nous devons compter la position de chaque période dans notre tableau d’en-tête et lui associer la quantité correspondante à partir du tableau des éléments et, en cours de route, procéder à quelques « nettoyages/conversions de données » :
- Nos numéros de semaine comportent un caractère indésirable (‘W’) dont nous devons nous débarrasser.
- Nos numéros de semaine ne peuvent pas être utilisés tels qu’ils apparaissent dans le fichier car SAP Business One s’attend à obtenir, pour une
prévision hebdomadaire
mode
le
premier jour ouvrable
pour chaque semaine figurant dans notre fichier plat.
Regardez le résultat de notre action « FilterRows » :
Nous devons identifier la position de chaque élément, mais pas avant d’avoir transformé chaque itération de l’action « Select » en un tableau.
Le « Code article » est le premier, sa position est donc 0. Il se présentera alors comme suit :
trim(split(item(), ‘,’)
[0]
)
Il en va de même pour la quantité :
split(item(), ‘,’)
[
2………13
]
La sortie de notre instruction « Select » ressemblerait à ceci :
Nous avons réussi à créer un tableau JSON significatif avec lequel nous pouvons travailler avec succès !
Si vous lisez le document SAP Business One Service Layer API Reference (cliquez sur https://<nom d’hôte>:50000) où <nom d’hôte> est le nom du serveur sur lequel vous avez installé vos composants SAP Business One Server, vous constaterez que pour patcher avec succès un objet MRP weekly Forecastvous devez inclure la charge utile suivante dans le corps de la requête :
C’est ici que nous devons ajouter plus de magie à notre solution pour que cela se produise.
Notre fichier contient 13 périodes qui représentent le numéro de semaine. Nous devrons donc passer en revue chacun de nos éléments, mais nous devrons également créer une autre boucle qui s’exécutera 13 fois et attribuera les valeurs prévisionnelles pour chaque numéro de période.
Pour cela, créons une variable globale appelée
varIDStep
qui servira de numérateur/compteur dans notre scénario et fixons-la à ‘1’
:
Ajoutons maintenant deux boucles imbriquées : une boucle « Do-Until » et une boucle « For each » :
Cela signifie que nous devrions itérer 12 fois pour chaque code d’article afin d’attribuer les valeurs.
Chaque fois que la boucle interne (« Pour chaque ») termine son exécution (rappelez-vous, elle parcourt chacun de nos codes d’article !), notre variable est incrémentée en utilisant l’action « Incrémenter la variable » :
Lorsque la valeur du compteur est de 13, la boucle extérieure (« Until-Do ») existe également.
Pour optimiser davantage notre solution et éviter les exécutions inutiles, je recommanderais d’ajouter une condition qui ignore les itérations où la quantité est égale à « null » :
Notez que j’ai utilisé la fonction « concat » pour enchaîner la « Quantité » et la valeur actuelle de l’itération de notre variable (compteur), de manière à ce que cela corresponde à notre définition de « Select » ci-dessus :
items(‘For_each’) ?[concat(‘Quantity’,variables(‘varIDStep’))]
Cela permet de s’assurer que je fais toujours référence à la
valeur
de la « Quantité » ou de la « Période ».
En utilisant cette méthodologie, l’action suivante consistera à convertir la représentation de la semaine qui a été écrite dans notre fichier en une date que SAP Business One peut utiliser pour enregistrer les valeurs prévisionnelles (rappelez-vous qu’il s’agit du premier jour ouvrable de la semaine).
Je n’entrerai pas dans les détails de cette conversion, mais vous pouvez me contacter si vous souhaitez en savoir plus sur cette logique supplémentaire.
Je mentionnerai brièvement comment utiliser les « chemins relatifs » pour invoquer un autre sous-workflow et transmettre un paramètre à ce flux.
Notez que j’ai défini le chemin relatif sur le connecteur :
/Période/{Period}
Le paramètre sera transmis via un appel HTTP à partir de notre flux de travail principal de la manière suivante :
Là encore, nous utilisons la méthode « concat » pour référencer le fichier
période
à l’intérieur de la boucle que nous souhaitons convertir en date.
Une fois la date convertie, nous pouvons préparer la sortie et déclencher la modification :
Au final, les valeurs prévisionnelles sont transférées dans le client SAP Business One :
Nous pourrions éventuellement (principalement pour une solution productive) ajouter des étapes d’interaction avec l’utilisateur qui notifieraient à l’auteur de la soumission un succès/échec à la fin de l’exécution et rendraient notre solution un peu plus « conviviale ».
Une façon de procéder consiste à utiliser une variable de type tableau qui sera remplie à l’intérieur de la boucle au moment de l’exécution, chaque fois que nous ferons un appel à la couche de service :
Nous pouvons alors vérifier le code d’état de la réponse que nous obtenons et décider du tableau à remplir :
Nous pourrions alors utiliser le connecteur « Send an email (V2) » en combinaison avec la fonction « length » pour dimensionner la longueur de chaque tableau en dehors de la boucle externe (ce qui équivaut au nombre d’enregistrements réussis/erreux que nous avons obtenus) :
Résumé
Maintenant que nous avons terminé la construction de notre solution, nous pouvons poursuivre construire des scénarios d’extension qui combinent ces approches « anciennes » de travail avec des systèmes de fichiers locaux avec des approches plus récentes qui nous aident à construire une intégration gagnante avec nos systèmes SAP Business One.
Vous pouvez utiliser le modèle que nous avons créé pour répondre à des cas similaires où un utilisateur déclenche un événement qui est ensuite exploité et intégré dans notre ERP avec peu ou pas d’effort.
Cette configuration vous permet de développer des extensions commerciales découplées à l’aide de
Logic Apps
avec tous les outils et services fournis par
Microsoft Azure Platform
dans la langue qui vous qui vous convient le mieux ou qui convient le mieux à votre cas d’utilisation.
Si vous êtes intéressé par d’autres cas d’utilisation qui pourraient bénéficier d’une telle configuration découplée, n’hésitez pas à me contacter, et je serai ravi d’entendre vos idées.
Rejoignez-nous dans la communauté SAP Business One pour nous faire part de vos réflexions, commentaires et idées !
Laisser un commentaire
Vous devez être identifié pour poster un commentaire.