Gérer et comprendre les scripts

Présentation

Comprendre comment s’articulent les scripts, leur rôle et toutes les informations techniques telles que le bodyData ou l'anti-loop.
Nous partons du principe que le paramétrage du datatracking est acquis.
Si ce n’est pas le cas, il est conseillé de consulter cette page en amont : Traquer une table et un champ

Fonctionnement

Lorsqu’une entité est intégrée dans la gestion des notifications du studio, le datatracking sera déclenché suivant les actions définis dans le paramétrage.
Le déclenchement se fera depuis :

  • Le BackOffice

  • La Synchronisation

  • Les backend

  • Les webhook

  • Les événements

S’en suivra plusieurs étapes :

  • Le système écrira une ligne dans sw_sys_brokermessage. Table à ne pas altérer.

  • Le service broker-message-gateway parcourt tous les projets et regarde s'il y a des messages à envoyer au serveur RabbitMQ.

  • Le service JobCenter crée les queues de messages dans RabitMQ au démarrage et gère le dispatching, qui au final appel le script d'endpoint définis dans le notifications managment du studio.

Les types de script

Il existe actuellement un schéma logique utilisé par le standard pour traiter les data :

  • Le script d’endpoint ou script d’entrée

    • C’est le script définit dans la paramétrage du studio dans Tools > Notifications managment
      En l’appelant, le système lui passe un document JSON appelé bodyData détaillé plus bas, accessible via la variable éponyme.

      • Exemple : SysNotifcation_Customer

  • Le script de parsing

    • Appelé par le script d'endpoint. Il permet de boucler sur les data présentes dans le document JSON bodyData et de les traiter en conséquence.

      • Exemple : SysNotification_Customer_ParseForEach

  • Le script d’overload

    • Appelé en amont du script de parsing. Il permet d'intégrer un point de surcharge afin de proposer des traitements supplémentaires à ceux du standard.

      • Exemple : SysNotificationOverload_Customer

  • Le script annexe

    • Permet d’exécuter des instructions qui pourraient êtres appelés par les script de parsing ou script de surchage.

      • Exemple : FuncSysNotification_InsertNotification

Les domaines d’application

Actuellement, nous utilisons le datatracking pour trois raisons :

  • Les notifications système

    • Les script SysNotification

  • La gestion d’une entité

    • Les script Datatracking_MainHandling

  • Les échanges externes

    • Les scripts ExtDataUpdateAsync

BodyData

Lorsque le script d'endpoint est exécuté, il reçoit en entrée un document JSON accessible via la variable bodyData.

Le document JSON contient un tableau dont chaque élément à les propriétés suivantes :

  • ProjectCode

  • TableName

  • RowID : Clé primaire de l'enregistrement, exemple : customer_ID

  • RowCode : Code de l'enregistrement, exemple : codeCustomer

  • Company_ID

  • Device_ID : il s'agit du device à l'origine de la notification

  • Action : indique le type d'action à l'origine de la notification, les valeurs possibles sont :

    • 1 : Ajout de l'enregistrement

    • 2 : Mise à jour de l'enregistrement

    • 4 : Suppression de l'enregistrement

  • BeforeValues : contient les valeurs avant modification des champs suivis.

  • AfterValues : contient les valeurs après modification des champs suivis.

Le nombre d'élément maximum de ce tableau pour un appel de script est défini par le paramètre Pack size dans l'écran de configuration des notifications. Se référer à la page Traquer une table et un champ pour visualiser ce paramètre.

Anti-loop

Par défaut, un script appelé via datatracking n'ira pas déclencher un nouvel appel lors de la modification d'une table. Ceci pourrait créer des boucles infinies.
Cependant, il existe une fonction SwingScript nommée DATA_TRACKING permettant d'indiquer explicitement de déclencher le datatracking sur une ligne.
A utiliser en connaissance de cause. Il faut être certain de maitriser le cycle d’exécution.

Debug

En cas d’erreur, voici différentes pistes à explorer

  • Vérifier dans la table sw_sys_brokermessage que le champ logs n'est pas rempli.

  • Vérifier les data du bodyData dans le champ messageBody de la table sw_sys_brokermessage en faisant clique droit Copy content et en l’enregistrant dans un fichier .txt

  • Utiliser la fonctionnalité script tester directement depuis le studio afin de s’assurer de ne pas avoir d’erreur de script.

Exemple pratique

Cet extrait provient du standard.

// Script d'endpoint // Nous récupérons la variable bodyData afin de la parser dans le script de parsing EXECUTE_SCRIPT_FOREACH_ROW( "SysNotification_Customer_ParseForEach", "json", "<varscript>bodyData</varscript>" ) // Script de parsing // Initialisation des variables contenant les data nécessaires du bodyData rowid = TRANSLATE( "<varscript>rowid</varscript>" ) action = TRANSLATE( "<varscript>action</varscript>" ) device_ID = TRANSLATE( "<varscript>device_ID</varscript>" ) entity = "customer" baseentity_ID = VARGET_DBSQL( "SELECT baseentity_ID FROM sw_data_baseentity WHERE codebaseentity = '<varscript>entity</varscript>'" ) messageToSubscribers = "" // Surcharge messageOverloadToSubscribers = CALL_SCRIPT( "SysNotificationOverload_Customer", rowid, action ) translationKeyToSubscribers = "" // Initialisation de variable dépendantes de l'entité principale. name, city, postalCode. entityDataQuery = TRANSLATE( " SELECT t.code<varscript>entity</varscript> AS entityCode, t.name, t.city, t.postalCode FROM sw_data_<varscript>entity</varscript> AS t WHERE <varscript>entity</varscript>_ID = '<varscript>rowid</varscript>' " ) VARINITIALIZE_SCRIPT_BYSQL( "<varscript>entityDataQuery</varscript>" ) // Echappement des appostrophes. name = REPLACE( "<varscript>name</varscript>", "'", "''" ) city = REPLACE( "<varscript>city</varscript>", "'", "''" ) // Condition sur chaque actions IF( EQUALS( action, "1" ) )THEN actionKey = "insert" ENDIF IF( EQUALS( action, "2" ) )THEN actionKey = "update" translationKeyToSubscribers = TRANSLATE( "NotificationModel_<varscript>entity</varscript>_<varscript>actionKey</varscript>" ) ENDIF IF( EQUALS( action, "4" ) )THEN actionKey = "delete" ENDIF IF( LEN( messageOverloadToSubscribers ) > 0 )THEN messageToSubscribers = TRANSLATE( "<varscript>messageOverloadToSubscribers</varscript>" ) ENDIF // Notification des subscribers IF( ( LEN( messageToSubscribers ) > 0 ) || ( LEN( translationKeyToSubscribers ) > 0 ) )THEN CALL_SCRIPT( "FuncSysNotification_NotifySubscription", actionKey, device_ID, entity, rowid, baseentity_ID, "NOTIFICATION", messageToSubscribers, translationKeyToSubscribers, "REPLACE( REPLACE( REPLACE( REPLACE( ltMessage.text, '%codecustomer%', '<varscript>entityCode</varscript>' ), '%name%', '<varscript>name</varscript>' ), '%city%', '<varscript>city</varscript>' ), '%postalCode%', '<varscript>postalCode</varscript>' )") ENDIF