top of page
réunion

Fonctionnement des formules

Dernière mise à jour : il y a 4 jours

Une formule est un champ qui permet d'afficher une valeur définie par une fonction javascript personnalisée.


Les différents points seront abordés au cours de cet article :


Règle de calcul

Il est possible de choisir l'une des trois règles de calcul suivante :


  • Manuel: les utilisateurs doivent cliquer sur un bouton afin que la formule se calcule.

  • Automatique : la formule se calcule automatiquement à chaque fois que c'est pertinent (quand un champ utilisé est modifié, quand la fiche est enregistrée...)

  • Une seule fois : cette nouvelle méthode se comporte comme le mode automatique mais une fois que le résultat est calculé il ne change plus (même si un champ lié est modifié)


Types de donnée

Pour paramétrer une formule, vous devez d'abord spécifier le type de donnée qu'elle va retourner.Voici les types disponibles :


  • Texte

  • Nombre

  • Booléen

  • Durée

  • Date

  • Liste


Pour chacun de ces types de données vous avez une ou deux options pour l'affichage de la donnée.











Écriture de la formule

La formule doit s'écrire en javascript. Elle doit inclure un « return » pour renvoyer l’information souhaitée.


Quelques cas à prendre en compte :

  • Type Date :

    • Renvoie un Unix timestamp (le nombre de secondes entre la date souhaitée et le 1er janvier 1970 minuit UTC)

    • Exemple, pour le 26 mars 2020 10h (UTC) :

return 1585216800;

Par défaut, les dates sont traitées avec la timezone système de votre appareil. Il est possible de contourner cela et d'imposer l'heure UTC. Exemple :

var date = new Date();return (date.getTime() + date.getTimezoneOffset()*60*1000)/1000;
  • Type Durée :

    • Renvoie un entier avec le nombre de secondes

    • Exemple pour 58 min 26 sec :

return (58 * 60) + 26; 

  • Type Liste :

    • Renvoie un tableau d'objets liste complets. Pour le formatage il est fortement recommandé de passer par la fonction searchList détaillée juste après.

    • Il ne faut pas utiliser de caractère spéciaux dans l'external id d'un élément de liste (exemple : l'underscore "_")

    • Exemple :

return services.searchList({ type: "id", value : 427459});


Accéder aux listes (searchlist)

En appelant services.searchList(); vous pouvez accéder directement aux éléments d'une liste liée à votre formule.


Elle prend un objet en paramètre qui peut avoir 3 valeurs :

  • type (obligatoire) : vous avez le choix du mode de recherche parmi "name", "external_id" ou "id"

  • value (obligatoire) : à vous de renseigner le nom cherché (ou l'id ou l'external_id en fonction du type) ; attention, dans le cas de l'external_id, la valeur doit être de type String ;

  • parent (facultatif) : vous pouvez renseigner l'id du noeud dans votre liste arborescente auquel vous souhaitez restreindre la recherche.


La fonction searchList renvoie un tableau d'objets liste complets :

[  {    
"id": 123,    
"external_id": null,    
"caption": "Nom de l'élément de liste",    
"color":null,    
"imageId": "504d4a60-0db2-4bed-b234-a6d75e9950f4"  
},{    
"id": 124,    
"external_id": "456,    
"caption": "Autre nom de l'élément de liste",    
"color": null,    "imageId": null  
}]


Récupération d'une valeur dans un champ simple

On utilise la même manière de récupérer les informations de la fiche courante pour la plupart des éléments d’un formulaire :

  • Texte

  • Nombre

  • Booléen

  • Date

  • Durée

  • Email

  • Téléphone

  • Formule d'un type mentionné dans cette liste


On utilise pour cela le nom système du champ concerné.

items['nom_systeme']

Par exemple, si on veut calculer un prix TTC en se basant sur un prix HT :

return items['prix_ht'] * ( 1 + 20/100);

NB : si le champ n'est pas encore renseigné, il n'est pas forcément présent dans l'objet items. Il peut donc être intéressant d'inclure une vérification pour afficher une information cohérente :

if(items['prix_ht']){     
return items['prix_ht'] * ( 1 + 20/100);} else {    
return 0; }


Récupération des données système de la fiche

Il est possible d'accéder aux données système de la fiche en utilisant l'objet javascript metadata :

  • number permet de récupérer un nombre unique permettant d'identifier la fiche

  • uuid est également un identifiant permettant de retrouver la fiche

  • number_in_structure permet de connaitre le numéro de la fiche dans son formulaire

  • created_at permet d'avoir la date de création de fiche (Unix timestamp)

  • user permet d'avoir des informations sur l'utilisateur ayant créé la fiche. Il s'agit d'un objet avec les informations email, prénom et nom de famille.


Voici la structure de l'objet :

{   
"number": 63930,   
"number_in_structure" : 12,   
"uuid": "38c6d76e-5442-4cbd-baef-cb9e5d6c4daa",   
"created_at": 1550242752,   
"user": {      
"email": "toto@gmail.com",      
"last_name": "Toto",      
"first_name": "Toto"   
}}

Voici un exemple :

return metadata['number'];

NB : number, number_in_structure et created_at ne sont disponibles qu'après le premier enregistrement de la fiche sur le web.



Récupération des données d'un champ localisation

Un champ localisation est composé d'une adresse textuelle (ex : 21A boulevard Guist'hau, 44 000 Nantes, France) et de cordonnées géographiques (ex : lat 47.2165879, long -1.566951)


Pour récupérer ces informations, il faut donc préciser la donnée souhaitée. Voici un exemple pour un champ localisation dont le nom système est "adresse" (formule de type texte) :

var result = "";if(items['adresse']){
    
if(items['adresse'].address){        
result = "Adresse : "+ items['adresse'].address ;    
}    

if(items['adresse'].lat && items['adresse'].lng){        
result = result + "\nlat: " + items['adresse'].lat;         
result =  result + ", long: " +items['adresse'].lng;    
}}
return result;

Résultat :

Adresse : 21A boulevard Guist'hau, 44 000 Nantes, France

lat: 47.2165879, long: -1.566951


Attention, les formules localisation ne sont pas compatibles avec l'application Android V1.



Récupération des données d’un champ liste

Une liste peut avoir plusieurs éléments sélectionnés. Nous avons donc mis en place une méthode plus complète pour accéder à ces informations.


Utilisons un exemple avec des animaux :

  • Animal

    • Félin

      • Chat (external_id : cat)

      • Tigre

    • Oiseau

      • Mouette

      • Pigeon

Parmi ces choix, on va imaginer que "Chat" et "Mouette" sont sélectionnés.


items[‘liste_animal’] sera alors un tableau d’objets :

  • Pour obtenir le nom du premier élément sélectionné :

items['liste_animal'][0].caption
  • Réponse : Chat

  • Pour obtenir l’identifiant externe du premier élément sélectionné :

items['liste_animal'][0].external_id
  • Réponse : cat

  • Pour obtenir le parent le plus proche de la souche :

items['liste_animal'][0].parents[0].caption
  • Réponse : Animal

  • Pour obtenir le parent direct :

items['liste_animal'][0].parents[ items['liste_animal'][0].parents.length – 1 ].caption
  • Réponse : Félin


Exemple complet pour liste l’ensemble des choix sélectionnes :

if(items['liste_animal']){  
return items['liste_animal'].reduce(function(result,element){
    return result + " - " + element.caption + ".";
  },"");} else {  
return "Aucun élément sélectionné dans la liste.";}

Réponse : " - Chat. - Mouette."


Récupération des données d’une relation

Il est également possible de chercher des informations dans les fiches qui sont en relations avec la fiche courante.


Pour cela, on peut chercher ces fiches en relation à l’aide de l’objet javascript relations.


Fiches enfants

Si la relation est définie dans la fiche courante avec le nom système ‘nom_systeme’, on peut accéder aux fiches avec :

relations.children.nom_systeme.submissions

Du coup pour récupérer le champ ‘titre’ de la première fiche en relation :

relations.children.nom_systeme.submissions[0].items['titre'];

Fiches parentes

Si la relation est définie dans un formulaire parent, la syntaxe est similaire, mais en utilisant ‘parents’ à la place de ‘children’ :

relations.parents.nom_systeme.submissions[0].items['titre'];

Donc pour lister l’ensemble des titres des fiches qui ont établi une relation vers la fiche courante avec la relation ‘nom_relation’ (il faut donc que ces fiches aient un champ dont le nom système soit titre) :

if(relations.parents.nom_relation &&relations.parents.nom_relation.submissions){  return relations.parents.nom_relation.submissions.reduce(function(result,element){
    return result + " - " + element.items['titre'] + ".";
  },"");} else { 
return "Aucune fiche parente trouvée";}

Relations quantifiables

Certaines relations comme les relations quantifiables possèdent des attributs qu'il peut être utile d'utiliser dans des formules.


Pour accéder aux attributs d'une relation, il faut utiliser l'attribut relationProperties à la place de itemsdans la fiche en relation. Du coup, si la relation a pour nom système produits et que l'on cherche la quantité associée (paramètre "count"), cela donne :

relations.children.produits.submissions.relationProperties.count

Cas pratique : La fiche parente est une commande avec les produits entrés au sein d'une relation quantifiable (nom système : "produit"). Le prix de chaque produit apparait dans le champ "prix" des produits. Si je cherche à obtenir le prix total de ma commande, je peux faire :

var prix = 0;
if(relations && relations.children && relations.children.produits && relations.children.produits.submissions && relations.children.produits.submissions.length > 0){  relations.children.produits.submissions.forEach(function(prod){    
var quant = 1;    
if(prod.relationProperties.count && prod.relationProperties.count){      quant = prod.relationProperties.count    
}    
if (prod.items && prod.items['prix']){      
prix += prod.items['prix'] * quant;    
}  });} 
return prix;


Récupération des données d'un champ utilisateur

Comme pour les listes, un champ utilisateur peut avoir plusieurs éléments sélectionnés. Nous avons donc mis en place une méthode similaire pour accéder à ces informations.

return items['user_field_system_name'][0]['propriété_utilisateur'];

Exemple, pour récupérer l'adresse mail de l'utilisateur

return items['user_field_system_name'][0]['email'];

Renvoie un tableau d'utilisateurs.

Ensuite, voici les différentes propriétés d'un utilisateur :

  • email

  • first_name

  • last_name


Donc pour afficher les noms et prénoms d'un utilisateur dans un champ utilisateur non multiple, cela donne :

if(items['user_field_system_name'] &&items['user_field_system_name'].length > 0){  return items['user_field_system_name'][0].first_name + ' ' +items['user_field_system_name'][0].last_name;} else {  
return "Pas d'utilisateur sélectionné";}


Remarque de syntaxe

Lorsqu'une formule est mise en place dans un formulaire, Daxium-Air vient lire la formule pour en déduire les champs qui sont nécessaires au calcul de cette dernière. Pour cela, nous parsons le javascript à la recherche de items['nom_systeme']. Il est donc important de bien laisser cette syntaxe dans l'écriture de vos formules.


Voici deux exemples qui ne fonctionnent pas :


Exemple 1
return items.number * 2 ;

On pourrait s'imaginer que les valeurs des champs de la fiche sont directement incluses dans l'objet items et que donc la syntaxe items['number'] est identique à items.number. Or dans certains cas, l'objet items est créé dynamiquement pour la formule en question.


Exemple 2
var total = 0 ;for(var i=1 ; i<10; i++){  
if(items['number'+i]){    
total += items['number'+i];  }}
return total;

A partir du moment où les champs sont bien formatés, on a envie de se faciliter la vie avec des formules qui viennent chercher les champs dynamiquement. Mais pour les raisons évoquées plus haut, cette formule ne fonctionnera pas correctement dans la plupart des cas.


179 vues

Posts similaires

Voir tout

Espace Utilisateurs

bottom of page