Fonctionnement du moteur des rapports

From Documentation de la solution web de gestion OpenFlyers
Revision as of 09:59, 18 December 2023 by imported>Claratte (→‎Export CSV)
Jump to navigation Jump to search

Présentation

L'objet de cette page est de présenter le fonctionnement du moteur des rapports.

Bibliothèque des rapports

Conversion des nombres stockés en sexacentimal avec sexa2HoursMinute

Cette fonction n'est possible que pour les rapports de la bibliothèque.

Certaines durées, comme les temps d'activités, sont stockés en unité sexacentimal.

La fonction stockée sexa2HoursMinute permet de convertir ces valeurs en heure minute.

Il est recommandé pour les rapports devant être utilisés au travers de l'API OpenFlyers de transmettre les valeurs directement en sexacentimal et d'effectuer la conversion en une autre unité côté serveur.

Export CSV

Les nombres sont formatés selon le chapitre formatage des nombres.

L'encodage de l'export CSV est défini par le champ Jeu de caractère CSV par défaut du paramétrage de la plateforme.

Formatage des nombres

Pour l'affichage dans le navigateur et pour les exports CSV, les nombres sont formatés en conservant uniquement les chiffres significatifs, c'est à dire en supprimant les zéros non significatifs. Le formatage n'est fait que sur les colonnes contenant exclusivement des nombres.

Exemples de formatage :

  • 2.10 sera formaté 2.1
  • 2.00 sera formaté 2
  • 2.135 sera formaté 2.135

Le séparateur décimal est défini par le champ Séparateur décimal du paramétrage de la plateforme.

Multilinguisme

Cette fonction n'est possible que pour les rapports de la bibliothèque.

Il est possible d'avoir des phrases traduites dans la langue de l'utilisateur par l'utilisation des tags _tr(XXX)XXX est un tag de traduction.

Lorsque le moteur repère une occurrence de _tr(XXX), il :

  • extrait le tag de traduction XXX
  • lance la traduction du tag dans la langue de l'utilisateur connecté
  • échappe les apostrophes
  • remplace _tr(XXX) par le tag traduit

Exemple de requête : <sql>SELECT id, name AS login, first_name AS '_tr(FIRST_NAME)', last_name AS '_tr(LAST_NAME)' FROM person</sql>

Exemple d'affichage :

id login Nom Prénom
1 bjean Beau Jean
5 dmichel Dupont Michel

Le parsage des tags _tr(XXX) s'effectue avant l'exécution de la requête SQL afin de n'avoir à traduire que la requête elle-même et non pas l'intégralité des résultats. Dans le cas d'une requête dynamique, le parsage a lieu après la première passe qui génère la 2ème requête et avant la 2ème passe qui génère les résultats.

Requête dynamique

La présence du tag "[OF_DYNAMIC_SQL]" dans un rapport, permet d'identifier une requête dynamique.

Une requête dynamique est une requête SELECT construisant une autre requête SELECT à l'intérieur d'elle-même. L'on nomme cette autre requête, une requête imbriquée.

Les requêtes dynamiques sont principalement utilisées pour afficher sous forme de colonne, des données provenant de champs métiers comme par exemple, pour le rapport Coordonnées (avec profil X et/ou validité Y expirant à une date postérieure ou égale à Z).

Exemple de requête dynamique avec des variables : La requête imbriquée sert à obtenir les utilisateurs d'un certain profil. <sql>[OF_DYNAMIC_SQL] SELECT '

 SELECT *
 FROM person
 LEFT profile ON person.profile & profile.id
 WHERE profile.id=\'$profileId\'

' FROM ma_table WHERE mon_champ='$monId'</sql>

Pour les variable associé à un champ de type dbObject::Multi, l'utilisation de la variable dans la requête imbriquée doit être écrite de telle sorte : <sql>[OF_DYNAMIC_SQL] SELECT CONCAT('

 SELECT *
 FROM person
 LEFT profile ON person.profile & profile.id
 WHERE ( profile.id IN (', IF('-' IN ($profileId), '\'-\, '$profileId'), ') OR \'-\' IN (', IF('-' IN ($profileId), '\'-\, '$profileId'), ') )')

FROM ma_table WHERE mon_champ='$monId'</sql>

La requête imbriquée permet d'obtenir cela : <sql>SELECT * FROM person LEFT profile ON person.profile & profile.id WHERE ( profile.id IN ($profileId) OR '-' IN ($profileId) )</sql>

Afficher/cacher des colonnes en fonction des champs

L'utilisation de requête dynamique permet d'afficher/cacher des colonnes en fonction des champs.

C'est dans la requête imbriquée où se fait le choix d'afficher ou non, les colonnes désirées.

Par exemple, le rapport Coordonnées (avec profil X et/ou validité Y expirant à une date postérieure ou égale à Z) cache les colonnes liées aux validités lorsqu'aucun type de validité n'est sélectionné.

Exemple de requête de base qui récupère les utilisateurs et leurs validités : <sql>SELECT person.id AS ID, last_name AS Nom, first_name AS Prénom,

   validity_type.name AS 'Validité'

FROM person LEFT JOIN validity ON (person.id=validity.person_id) LEFT JOIN validity_type ON (validity_type.id=validity.validity_type_id) WHERE person.activated=1

 AND (
     (validity.validity_type_id IN ($validityTypeId) AND validity_type.time_limitation=1)
     OR
     '-' IN ($validityTypeId)
 )

ORDER BY last_name, first_name</sql>

Exemple de la requête transformée en requête dynamique : <sql>[OF_DYNAMIC_SQL] SELECT CONCAT('

   SELECT person.id AS ID, last_name AS Nom, first_name AS Prénom,
       validity_type.name AS \'Validité\'
   FROM person
   LEFT JOIN validity ON (person.id=validity.person_id)
   LEFT JOIN validity_type ON (validity_type.id=validity.validity_type_id)
   WHERE person.activated=1
     AND (
         (validity.validity_type_id IN ($validityTypeId) AND validity_type.time_limitation=1)
         OR
         \'-\' IN (', IF('-' IN ($validityTypeId), '\'-\, '$validityTypeId'), ')
     )
   ORDER BY last_name, first_name

')</sql>

Exemple pour cacher la colonne "Validité" lorsque rien n'est sélectionné pour la variable $validityTypeId : <sql>[OF_DYNAMIC_SQL] SELECT CONCAT('

   SELECT person.id AS ID, last_name AS Nom, first_name AS Prénom',
       IF('-' IN ($validityTypeId), , ', validity_type.name AS \'Validité\', )', ' 
   FROM person
   LEFT JOIN validity ON (person.id=validity.person_id)
   LEFT JOIN validity_type ON (validity_type.id=validity.validity_type_id)
   WHERE person.activated=1
     AND (
         (validity.validity_type_id IN ($validityTypeId) AND validity_type.time_limitation=1)
         OR
         \'-\' IN (', IF('-' IN ($validityTypeId), '\'-\, '$validityTypeId'), ')
     )
   ORDER BY last_name, first_name

')</sql>

Remplacement des variables

Variable associé à un champ de type dbObject

Une variable associée à ce type de champ recevra comme valeur possible :

  • Lorsque "Pas de filtre" est sélectionné, le caractère : -
  • Lorsqu'une valeur est sélectionnée, un id sous forme de nombre

Exemple de rapport : Liste des utilisateurs actifs possédant le profil "$profileId" <sql>SELECT person.* FROM person LEFT JOIN profile ON person.profile & profile.id WHERE profile.id='$profileId'

 AND activated=1</sql>

Exemple de remplacement : <sql>SELECT person.* FROM person LEFT JOIN profile ON person.profile & profile.id WHERE profile.id='1'

 AND activated=1</sql>

Exemple de rapport : Liste des utilisateurs actifs avec ou non, un filtrage sur le profil "$profileId" <sql>SELECT * FROM person LEFT JOIN profile ON person.profile & profile.id WHERE ( profile.id='$profileId' OR '-'='$profileId' )</sql>

Dans ce rapport, cette partie permet d'assurer le filtrage : <sql>profile.id='$profileId'</sql> Et cette partie s'assurer le non-filtrage : <sql>'-'='$profileId'</sql>

Exemple de remplacement assurant le filtrage : <sql>SELECT * FROM person LEFT JOIN profile ON person.profile & profile.id WHERE ( profile.id='1' OR '-'='1' )</sql>

Exemple de remplacement assurant le non-filtrage : <sql>SELECT * FROM person LEFT JOIN profile ON person.profile & profile.id WHERE ( profile.id='-' OR '-'='-' )</sql>

Exemple de rapport avec une requête dynamique : <sql>[OF_DYNAMIC_SQL] SELECT 'SELECT *

 FROM person
 LEFT JOIN profile ON person.profile & profile.id
 WHERE ( profile.id=\'$profileId\' OR \'-\'=\'$profileId\' )'

FROM ma_table WHERE mon_champ='$unId'</sql>

Variable associé à un champ de type dbObjectMulti

Une variable associée à ce type de champ recevra comme valeur possible :

  • Lorsque rien n'est coché, la chaîne : '-'. Cela est considéré comme "Pas de filtre".
  • Lorsqu'une valeur est cochée, un id sous forme de nombre
  • Lorsque plusieurs valeurs sont cochées, plusieurs id sous forme de chaîne suivante : 1,2,3

Exemple de rapport : Liste des utilisateurs actifs avec ou non, un filtrage sur le(s) profil(s) "$profileId" <sql>SELECT * FROM person LEFT JOIN profile ON person.profile & profile.id WHERE ( profile.id IN ($profileId) OR '-' IN ($profileId) )</sql>

Dans ce rapport, cette partie permet d'assurer le filtrage : <sql>profile.id IN ($profileId)</sql> Et cette partie s'assurer le non-filtrage : <sql>'-' IN ($profileId)</sql>

Exemples de remplacement assurant le filtrage : <sql>SELECT * FROM person LEFT JOIN profile ON person.profile & profile.id WHERE ( profile.id IN (1) OR '-' IN (1) )</sql>

<sql>SELECT * FROM person LEFT JOIN profile ON person.profile & profile.id WHERE ( profile.id IN (1,2,4) OR '-' IN (1,2,4) )</sql>

Exemple de remplacement assurant le non-filtrage : <sql>SELECT * FROM person LEFT JOIN profile ON person.profile & profile.id WHERE ( profile.id IN ('-') OR '-' IN ('-') )</sql>

Exemple de rapport avec une requête dynamique : <sql>[OF_DYNAMIC_SQL] SELECT CONCAT('SELECT *

 FROM person
 LEFT JOIN profile ON person.profile & profile.id
 WHERE ( profile.id IN (', IF('-' IN ($profileId), '\'-\, '$profileId'), ') OR \'-\' IN (', IF('-' IN ($profileId), '\'-\, '$profileId'), ') )')

FROM ma_table WHERE mon_champ='$unId'</sql>

Rendre des liens cliquables

Par défaut, si du contenu dans les rapports produit des liens, ceux-ci ne sont pas cliquables.

Pour que les liens le deviennent, ceux-ci doivent être sur la forme :

[LINK=lien_cliquable]Du texte[/LINK]

Les liens sont construits pour que le contenu s'ouvre dans un nouvel onglet ou une nouvelle fenêtre (selon la configuration du navigateur).

Par exemple :

[LINK=http://openflyers.com]Site OpenFlyers[/LINK]

Attention : s'il est nécessaire de mettre un point d'interrogation dans l'URL, alors il faut remplacer le point d'interrogation par [QUESTION_MARK].

Exemple de construction de lien permettant d'éditer les 50 derniers vols : <sql>SELECT CONCAT( '[LINK=index.php[QUESTION_MARK]menuAction=flight_record&menuParameter=', flight.id, ']Edit[/LINK]' ) AS Link, flight.* FROM flight WHERE flight.validated=0 ORDER BY flight.start_date DESC LIMIT 50</sql>

Totaux

Lorsqu'on visualise un rapport dans le navigateur, une ligne est ajoutée en fin d'édition pour contenir les totaux des colonnes.

Le total est calcule pour les colonnes dont soit :

  • toutes les cellules de la colonne contiennent un nombre
  • toutes les cellules de la colonne contiennent une durée inférieure à 24h.

De plus, la première cellule de cette dernière ligne contient le nombre total de lignes affichées (sans la dernière).

Visualisation de rapport

Lors d'une demande de visualisation de rapport, le moteur des rapports :

  • Récupère les valeurs des champs de saisie affichées dans le formulaire et stocke ces valeurs dans les variables correspondantes à ces champs de saisie
  • Extrait la requête du rapport
  • Remplace dans la requête, chaque variable par leur valeur correspondante
  • Interprète la requête. Lors d'une requête dynamique, celle-ci est interprété une seconde fois
  • Affiche le résultat sous forme de tableau

Exemple de rapport : <sql>SELECT * FROM ma_table WHERE mon_champ='$maVariable'</sql>

Exemple de rapport après remplacement des variables : <sql>SELECT * FROM ma_table WHERE mon_champ='1'</sql> <sql>SELECT * FROM ma_table WHERE mon_champ='test'</sql>