/

 

The manual

Self-training

Experimentation

Contact

 

Language

Le module organisations

Cette leçon présente le module organisations, qui est assez semblable au module personnes.

Voici le module organisations complet, prêt à l'emploi. Commencez par le copier coller sur votre site Storga d'expérimentation :

   

Les organisations

Le formulaire de recherche

La mécanique du formulaire de recherche est exactement la même que celle utilisée dans le module personnes.

Le formulaire de création

Il s'agit d'une version plus sophistiqué que ce que l'on trouve dans le module personnes. En effet, ce formulaire permet de éventuellement créer en un seul temps à la fois une fiche organisation et une fiche personne correspondant au contact principal dans cette organisation.

Examinons le code du programme :

if button_name="organisation_changed"
  organisation_message := shunt organisation="" "" (lookup_form_id @organisations_list organisation organisation)="" "Nouvelle organisation" "Organisation existante !"
if button_name="person_changed"
  person_message := shunt name="" "" (lookup_form_id @people_list full_name (shunt first_name<>"" first_name+" " "")+name+(shunt extra<>"" " "+extra "") any)<>"" "✘" "✔"
 
if button_name="create"
  if organisation=""
    error "Vous devez indiquer le nom de la nouvelle organisation"
  if (lookup_form_id @organisations_list organisation organisation)<>""
    error "Cette fiche organisation existe déjà"
  if name<>"" and (lookup_form_id @people_list full_name (shunt first_name<>"" first_name+" " "")+name+(shunt extra<>"" " "+extra ""))<>""
    error "Cette fiche personne existe déjà"
  new_form @organisation_model page @organisations_folders subpage (organisation 0 1) (organisation 0 1) subpage organisation organisation url_call copy_fields
    new_form @organisation_people_model
      void
  if name<>""
    new_form @people_model page @people_folders subpage (name 0 1) (name 0 1) subpage (shunt first_name<>"" first_name+" " "")+name (shunt first_name<>"" first_name+" " "")+name copy_fields
      field Str organisation -> organisation2
      delete_all organisation2
      create organisation2
        organisation2 := organisation
  # réinitialiser les champs du formulaire de création
  organisation := ""
  organisation_message := ""
  first_name := ""
  name := ""
  extra := ""

Les quatre premières lignes sont de même nature que dans le formulaire de création du module personnes : certains champs activent un bouton virtuel, qui provoque le recalcul d'un champ fournissant un feedback à l'utilisateur :

if button_name="organisation_changed"
  organisation_message := shunt organisation="" "" (lookup_form_id @organisations_list organisation organisation)="" "Nouvelle organisation" "Organisation existante !"
if button_name="person_changed"
  person_message := shunt name="" "" (lookup_form_id @people_list full_name (shunt first_name<>"" first_name+" " "")+name+(shunt extra<>"" " "+extra "") any)<>"" "✘" "✔"

Les trois 'if' qui effectuent les contrôles juste avant la création des nouveaux formulaires sont aussi semblables à ceux que nous avions vu lors des leçons précédentes, donc n'appellent pas de commentaires particuliers :

if organisation=""
  error "Vous devez indiquer le nom de la nouvelle organisation"
if (lookup_form_id @organisations_list organisation organisation)<>""
  error "Cette fiche organisation existe déjà"
if name<>"" and (lookup_form_id @people_list full_name (shunt first_name<>"" first_name+" " "")+name+(shunt extra<>"" " "+extra ""))<>""
  error "Cette fiche personne existe déjà"

En revance, la création du formulaire appelle une explication :

new_form @organisation_model page @organisations_folders subpage (organisation 0 1) (organisation 0 1) subpage organisation organisation url_call copy_fields
  new_form @organisation_people_model
    void

On a deux instructions 'new_form' imbriquées. La première est quasi identique à ce que l'on trouvait au niveau du formulaire de création d'une fiche dans le module personnes, à savoir à partir de la page dont le nom est 'organisations_folders', créer un premier niveau de sous page avec la première lettre de l'organisation, comme dans un carnet d'adresses papier, puis un second avec le nom complet, et y placer la nouvelle fiche en recopiant les champs communs, à savoir le nom de l'organisation.

Par contre, au lieu d'avoir une simple instruction 'void' dans le bloc sous cette première instruction, on trouve une seconde instruction 'new_form' qui demande l'ajout d'une seconde fiche, dont le modèle a pour nom 'organisation_people_model', et qui, du fait que cette instruction est imbriquée dans la précédente, sera ajoutée juste sous la première fiche.

Nous allons finir le commentaire du programme de création, puis nous reviendrons sur le rôle et le contenu de cette seconde fiche.
La suite du programme est :

  if name<>""
    new_form @people_model page @people_folders subpage (name 0 1) (name 0 1) subpage (shunt first_name<>"" first_name+" " "")+name (shunt first_name<>"" first_name+" " "")+name copy_fields
      field Str organisation -> organisation2
      delete_all organisation2
      create organisation2
        organisation2 := organisation

On constate tout d'abord que l'exécution de l'instruction 'new_form' qui crée une fiche dont le modèle à pour nom 'people_model' (une fiche personne du module personnes), est conditionnée par 'name<>""', ce qui signifie que cette fiche ne sera crée que si le champ 'Nom' de la seconde partie du formulaire avait été rempli.
Ensuite, sous l'instruction 'new_form', au lieu de la simple instruction 'void', on trouve toute une série d'instructions qui ne nous sont pas familières à ce stade de l'autoformation.
L'instruction 'field' déclare que la nouvelle fiche contient un champ 'organisation' auquel nous souhaitons accéder dans ce programme. Mais il existe déjà un champ 'organisation' au niveau du formulaire de création, donc il y a ambiguïté. Celle-ci est levée par l'ajout des paramètres '-> organisation2' qui indique que le champ 'organisation' de la nouvelle fiche sera identifié par le terme 'organisation2' dans la suite de ce programme.
L'instruction suivante 'delete_all organisation2' indique que ce champ fait partie d'une sous table, et demande à supprimer toutes les lignes de la sous table.
L'instruction 'create organisation2' qui suit ajoute une ligne dans la même sous table, et le bloc juste dessous sert à initialiser cette ligne.
L'initialisation est 'organisation2 := organisation' qui signifie recopier le champ organisation du formulaire de création (le nom de la nouvelle organisation) dans le champ organisation de la sous table de la nouvelle fiche créée.
Au final, la sous table de la fiche personnes aura donc une unique ligne, qui contient le nom de l'organisation, et c'est bien ce que l'on voulait.

La fin du programme réinitialise les champs du formulaire de création et n'appelle pas de commentaire particulier.

La fiche 'Personnes impliquées'

Revenons maintenant au contenu de cette fiche dont le titre est 'Personnes impliquées'.

Constatons tout d'abord que, quand elle a été créée via le formulaire de création d'une fiche organisation, en mode éditer, elle apparaît collée sous la fiche organisation :

En mode organiser détaillé, on constate cependant qu'il s'agit bien de deux blocs fiches distincts, l'un sous l'autre :

Si vous affichez les propriétés du formulaire 'Personnes impliquées', vous trouvez 'Hérite des champs du formulaire antérieur de type: organisation', et c'est ce qui provoque le collage de la fiche sous la fiche organisation qui la précède.
Cela a aussi d'autres effets qui ne sont pas utilisés dans le cas présents. Tout d'abord, les champs de la fiche organisation sont directement utilisables dans les éventuels programmes de la fiche 'Personnes impliquées'. Ensuite, les états qui collecteraient la fiche 'Personnes impliquées' pourraient aussi utiliser les champs de la fiche organisation qui la précède. Tout se passe donc comme si la fiche organisation faisait partie de la fiche 'Personnes impliquées'.

Cette fiche 'Personnes impliquées' contient un seul bloc Storga de type 'vue'. En voici les propriétés :

Un vue est l'affichage d'un autre état, identifié ici par son nom, ici 'people_list'. De plus, la vue va utiliser les valeurs prises dans un autre formulaire de la page, précédent ou englobant le bloc vue, pour remplir les paramètres permettant de configurer l'affichage de l'état.
Ici, on utilise le formulaire de type 'organisation' qui précède, et on utilise la valeur de son champ 'organisation' pour remplir le champ 'organisation_filter' au niveau de l'entête de l'état.
Au final, la vue va donc afficher la liste des personnes ayant une ligne correspondant à cette organisation particulière.

La liste des organisations

Cette liste est semblable, au niveau de sa construction, à celle du module des personnes.

Les fiches modèles des organisations

Nous avons vu qu'il existe deux fiches modèles, l'une 'Organisation' qui correspond à la fiche de base, l'autre 'Personnes impliquées' qui correspond à l'extension permettant de voir la liste des personnes impliquées dans cette organisation.

La fiche 'Organisation' est très semblable, et plus simple que la fiche 'Personne' du module des personnes, donc n'appelle pas d'explication supplémentaire, hormis la mécanique d'extension que nous allons évoquer ci-après.
La fiche 'Personnes impliquées' a été explicitée ci-avant.

Un exemple d'extension

Voici un exemple d'extension pour la fiche 'Organisation' :

   

Extension 'Client' pour les fiches organisation

Une extension est constituée de deux parties :

Une fiche 'Extension de fiche organisation' qui sert à déclarer l'extension, et lui permettre d'être affichée dans le champ choix multiple 'Extension de fiche organisation' de chaque fiche organisation.

Une fiche modèle de la fiche extension.

Dans l'exemple mis à disposition ci-dessus, l'extension permet d'ajouter à la fiche organisation une série de champs supplémentaires nécessaires pour émettre une facture.

Examinons maintenant le programme associé à chaque fiche organisation :

web_link := web
tel_link := "tel:"+(replace tel " " "")

if exists:@organisation_extension_list
  if button_name="add_extension"
    var Str type := lookup @organisation_extension_list extension type new_extension_code
    var Str last := form_id
    var Bool found := false
    each_form
      if form_version:type<>undefined and (lookup @organisation_extension_list extension multiple new_extension_code)<>"true"
        unfold_form
        found := true
      if form_version:"organisation"<>undefined # if the form inherits "organisation", then form_version:"organisation"=(-1)
        last := form_id
    if not found
      new_form (lookup @organisation_extension_list extension model new_extension_code) after last copy_fields
        unfold_form

Le début est du déjà vu, et sert à positionner les champs liens dans la colonne de gauche à partir des valeurs saisies dans la colonne de droite, pour l'URL du site web et le numéro de téléphone :

web_link := web
tel_link := "tel:"+(replace tel " " "")

Ensuite, vient la ligne :

if exists:@organisation_extension_list

Cette ligne n'a pas d'effet pratique. Elle évite juste que le programme se mette en erreur si le nom 'organisation_extension_list' n'est pas défini, c'est à dire si la page fournissant la mécanique des extensions des fiches organisations n'est pas en place.
Pour les programmeurs avancés connaissant le langage de programmation C, le 'if' de Storga, comme celui du langage Pliant, est tout à la fois l'équivalent du 'if' du C, et du '#if' du précompilateur C. Ici, 'if exists ...' est l'équivalent au '#ifdef' du précompilateur C, donc si la condition évaluée au moment de la compilation n'est pas satisfaite, le code qui se trouve juste dessous est complètement ignoré, c'est à dire pas compilé, donc ne risque pas de provoquer d'erreur.

Voyons maintenant la signification du bloc :

var Str type := lookup @organisation_extension_list extension type new_extension_code
var Str last := form_id
var Bool found := false
each_form
  if form_version:type<>undefined and (lookup @organisation_extension_list extension multiple new_extension_code)<>"true"
    unfold_form
    found := true
  if form_version:"organisation"<>undefined # if the form inherits "organisation", then form_version:"organisation"=(-1)
    last := form_id

Les trois premières lignes initialisent des variables locales.
'type' est le type de formulaire correspondant à l'extension souhaitée.
'last' sera le code du dernier formulaire trouvé dans la page correspondant à une fiche de type 'organisation' ou une extension.
'found' indiquera si une fiche correspondant au type d'organisation souhaité a déjà été trouvée, et qu'au niveau de la fiche définissant cette extension, le champ 'Cette extension peut être ajoutée plusieurs fois' est à 'non'.
Ensuite l'instruction 'each_form' parcours successivement tous les formulaires présent dans la page.

'(form_version x)' ou au choix 'form_version:x' retourne le numéro de version si la fiche en cours de parcourt est de type 'x', et retourne 'undefined' sinon.
'unfold_form' est une instruction qui commande le dépli de la fiche en cours de parcourt, comme si l'on avait cliqué sur le triangle qui apparaît sur la droite du titre de certaines fiches et permet de les déplier ou replier.
'form_id' est le code Storga correspondant à la fiche en court. Il s'agit, par défaut de la fiche dont le programme s'exécute, mais à l'intérieur d'une boucle 'each_form', il s'agit de la fiche en court de parcours.

Sous l'instruction 'each_form', le premier 'if' se lit donc : si la fiche a le type de l'extension souhaitée, et que ce type d'extension n'est pas déclaré multiple au niveau de la fiche servant à le définir, alors déplier la fiche qui existe déjà, et positionner la variable 'found' à vrai.

Le second 'if' se lit : si la fiche a le type 'organisation', ou est une extension d'une fiche organisation (c'est à dire hérite des champs du formulaire de type 'organisation'), alors enregistrer le code Storga de la fiche dans la variable 'last'.

La fin du programme est :

if not found
  new_form (lookup @organisation_extension_list extension model new_extension_code) after last copy_fields
    unfold_form

C'est à dire que si la variable 'found' est à faux, ce qui signifie que l'on a pas trouvé de fiche correspondant à l'extension souhaitée, ou que c'est une organisation que l'on peut ajouter plusieurs fois, alors on ajoute une fiche extension sous la fiche dont le code est 'last', c'est à dire sous la dernière fiche de la série. Cette nouvelle fiche sera affichée en mode déplié.
La fonction 'lookup' permet de retrouver le nom du modèle de la fiche extension à partir du code de l'extension sélectionné via le champ choix multiple 'new_extension_code'.

Travaux pratiques

Créez simultanément une fiche organisation et une fiche personne via le formulaire de création d'une nouvelle organisation, et vérifiez le résultat, en particulier où ont été crées les différentes fiches, y compris la fiche 'Personnes impliquées'. Vérifiez aussi que ce qui a été prérempli dans ces trois fiches correspond bien à ce que vous attendez en relisant le code du programme de création.

 

Nouveau message

From :

Message Title:

Message: