Commit 92d4bff4ecfdb5507381dcb3364bbd6666f80c51
1 parent
4d218b8d
Exists in
master
and in
1 other branch
Nouveau diagramme UML Etats-Transitions du statut d'un matériel
(pour préparer la nouvelle version V5 de janvier 2021)
Showing
13 changed files
with
157 additions
and
45 deletions
Show diff stats
.gitignore
CHANGES.txt
... | ... | @@ -134,6 +134,11 @@ Outre ces changements, voici d'autres changements importants : |
134 | 134 | ======= CHANGES ======= |
135 | 135 | |
136 | 136 | ------- |
137 | +02/11/2020 v4.106.9-3.7.9 | |
138 | + - Nouveau diagramme UML Etats-Transitions du statut d'un matériel | |
139 | + (pour préparer la nouvelle version V5 de janvier 2021) | |
140 | + | |
141 | +------- | |
137 | 142 | 27/10/2020 v4.106.8-3.7.9 |
138 | 143 | - (i) Nouvelle simplification de la logique des stats |
139 | 144 | => On utilise AppController.beforeFilter() au lieu de afterFilter() (ou encore config/bootstrap.php et src/Routing/Filter/SessionTimeoutFilter.php) | ... | ... |
README.md
... | ... | @@ -42,8 +42,8 @@ Logiciel testé et validé sur les configurations suivantes : |
42 | 42 | |
43 | 43 | -------------------------------------------------------------------------------------------- |
44 | 44 | |
45 | -Date: 27/10/2020 | |
46 | -Version: 4.106.8-3.7.9 | |
45 | +Date: 02/11/2020 | |
46 | +Version: 4.106.9-3.7.9 | |
47 | 47 | |
48 | 48 | |
49 | 49 | HISTORIQUE DES CHANGEMENTS DE VERSION : voir le fichier CHANGES.txt (ou la page web /pages/changes) | ... | ... |
database/update/script_sql/db-update-2020-10-23.sql
... | ... | @@ -23,14 +23,16 @@ ALTER TABLE type_suivis ADD description TEXT NULL DEFAULT NULL AFTER nom; |
23 | 23 | -- Ajout d'une contrainte d'unicité (index UNIQUE) sur le champ nom pour toutes les tables qui en manquent |
24 | 24 | -- |
25 | 25 | |
26 | -ALTER TABLE fakeldapusers ADD UNIQUE(uid); | |
27 | - | |
28 | 26 | ALTER TABLE groupes_metiers ADD UNIQUE(nom); |
29 | 27 | ALTER TABLE groupes_thematiques ADD UNIQUE(nom); |
30 | 28 | ALTER TABLE organismes ADD UNIQUE(nom); |
31 | 29 | ALTER TABLE sites ADD UNIQUE(nom); |
32 | 30 | ALTER TABLE type_suivis ADD UNIQUE(nom); |
33 | - | |
34 | 31 | ALTER TABLE type_documents ADD UNIQUE(nom); |
35 | --- Ajout aussi du type DEVIS (obligatoire) | |
32 | + | |
33 | +ALTER TABLE fakeldapusers ADD UNIQUE(uid); | |
34 | + | |
35 | + | |
36 | +-- Ajout aussi du type DEVIS (désormais obligatoire pour passer commande) | |
37 | + | |
36 | 38 | INSERT INTO type_documents (nom) VALUES ("DEVIS"); | ... | ... |
src/Controller/MaterielsController.php
... | ... | @@ -1754,29 +1754,33 @@ class MaterielsController extends AppController { |
1754 | 1754 | //$materiel = ($IS_ADD && !$id) ? $this->Materiels->newEntity() : $this->e; |
1755 | 1755 | //$materiel = ($IS_ADD && !$id) ? $this->Materiels->newEntity() : $this->getEntity($id); |
1756 | 1756 | $materiel = $IS_ADD ? $this->Materiels->newEntity() : $this->getEntity($id); |
1757 | - // ADD par copie : mettre id et numero labo à null | |
1758 | - if ($IS_ADD && $id) { | |
1759 | - // IMPORTANT: validate=False car sinon, les données sont validées avant la copie, | |
1760 | - // et le numero_laboratoire est vu comme invalide car déjà utilisé et doit etre unique !!! | |
1761 | - // et on a pour résultat : "le matériel n'a pas pu être ajouté" (sans savoir pourquoi !!!) | |
1762 | - //$materiel = $this->Materiels->newEntity($this->getEntity($id)->toArray(), ['validate' => false]); | |
1763 | - //$materiel = $this->Materiels->patchEntity($materiel, $this->getEntity($id, false, false)->toArray(), [ | |
1764 | - $materiel = $this->Materiels->patchEntity($materiel, $this->Materiels->get($id, ['contain' => []])->toArray(), [ | |
1765 | - 'validate' => false, | |
1766 | - // Ne pas valider non plus les entités associées | |
1767 | - /* | |
1768 | - 'associated' => [ | |
1769 | - 'SurCategories' => ['validate' => false], | |
1770 | - 'Categories' => ['validate' => false], | |
1771 | - 'SousCategories' => ['validate' => false], | |
1772 | - ] | |
1773 | - */ | |
1774 | - ]); | |
1775 | - // IMPORTANT: on ne doit pas laisser l'id égal à celui du matériel copié !!! il en faut un nouveau | |
1776 | - $materiel->id = null; | |
1777 | - // on supprime le champ numero_laboratoire car il va être généré automatiquement | |
1778 | - //unset($materiel->numero_laboratoire); | |
1779 | - $materiel->numero_laboratoire = null; | |
1757 | + if ($IS_ADD) { | |
1758 | + // Par défaut, l'Acheteur du matériel c'est l'utilisateur courant | |
1759 | + $materiel->nom_responsable = $this->u->nom; | |
1760 | + // ADD par copie : mettre id et numero labo à null | |
1761 | + if ($id) { | |
1762 | + // IMPORTANT: validate=False car sinon, les données sont validées avant la copie, | |
1763 | + // et le numero_laboratoire est vu comme invalide car déjà utilisé et doit etre unique !!! | |
1764 | + // et on a pour résultat : "le matériel n'a pas pu être ajouté" (sans savoir pourquoi !!!) | |
1765 | + //$materiel = $this->Materiels->newEntity($this->getEntity($id)->toArray(), ['validate' => false]); | |
1766 | + //$materiel = $this->Materiels->patchEntity($materiel, $this->getEntity($id, false, false)->toArray(), [ | |
1767 | + $materiel = $this->Materiels->patchEntity($materiel, $this->Materiels->get($id, ['contain' => []])->toArray(), [ | |
1768 | + 'validate' => false, | |
1769 | + // Ne pas valider non plus les entités associées | |
1770 | + /* | |
1771 | + 'associated' => [ | |
1772 | + 'SurCategories' => ['validate' => false], | |
1773 | + 'Categories' => ['validate' => false], | |
1774 | + 'SousCategories' => ['validate' => false], | |
1775 | + ] | |
1776 | + */ | |
1777 | + ]); | |
1778 | + // IMPORTANT: on ne doit pas laisser l'id égal à celui du matériel copié !!! il en faut un nouveau | |
1779 | + $materiel->id = null; | |
1780 | + // on supprime le champ numero_laboratoire car il va être généré automatiquement | |
1781 | + //unset($materiel->numero_laboratoire); | |
1782 | + $materiel->numero_laboratoire = null; | |
1783 | + } | |
1780 | 1784 | } |
1781 | 1785 | //debug($materiel); exit; |
1782 | 1786 | /* | ... | ... |
src/Template/Materiels/add_edit.ctp
... | ... | @@ -73,9 +73,12 @@ $IS_ADD = $IS_ADD; |
73 | 73 | $IS_EDIT = !$IS_ADD; |
74 | 74 | |
75 | 75 | $entity = $entity; |
76 | +// ATTENTION (A CONFIRMER mais je crois...) : | |
77 | +// TOUJOURS NÉCESSAIRE POUR QUE LES VALEURS PAR DÉFAUT SOIENT AUTOMATIQUEMENT TROUVÉES | |
78 | +// CAR CAKEPHP CHERCHE DANS UNE VARIABLE NOMMÉE $materiel... | |
79 | +// @deprecated | |
80 | +$materiel = $entity; | |
76 | 81 | //debug($entity); |
77 | -//TODO: supprimer | |
78 | -$materiel = $entity; // @deprecated | |
79 | 82 | |
80 | 83 | $entity_name = 'matériel'; |
81 | 84 | |
... | ... | @@ -349,7 +352,7 @@ if (isset($cpMateriel)) { |
349 | 352 | 'label' => 'Désignation', |
350 | 353 | //'default' => $Designation, |
351 | 354 | // ADD only |
352 | - //'default' => $materiel->designation, | |
355 | + /////'default' => $materiel->designation, | |
353 | 356 | //'default' => $designations, |
354 | 357 | //'default' => $designations->toArray(), |
355 | 358 | // EDIT only |
... | ... | @@ -379,7 +382,7 @@ if (isset($cpMateriel)) { |
379 | 382 | 'label' => 'Description', |
380 | 383 | // ADD only |
381 | 384 | //'default' => $Description |
382 | - 'default' => $materiel->description, | |
385 | + /////'default' => $materiel->description, | |
383 | 386 | // EDIT only |
384 | 387 | 'disabled' => $IS_ADD ? false : $isReadonlyField('description', $myReadonlyFields) |
385 | 388 | ]); |
... | ... | @@ -423,7 +426,7 @@ if (isset($cpMateriel)) { |
423 | 426 | 'empty' => 'Choisir un domaine', |
424 | 427 | //'default' => $Sur_categ_id |
425 | 428 | // ADD only |
426 | - //'default' => $materiel->sur_categorie_id, | |
429 | + //////'default' => $materiel->sur_categorie_id, | |
427 | 430 | // EDIT only |
428 | 431 | 'readonly' => $IS_ADD ? false : $isReadonlyField('sur_categorie_id', $myReadonlyFields), |
429 | 432 | 'disabled' => $IS_ADD ? false : $isReadonlyField('sur_categorie_id', $myReadonlyFields) |
... | ... | @@ -447,7 +450,7 @@ if (isset($cpMateriel)) { |
447 | 450 | 'empty' => 'Choisir une catégorie', |
448 | 451 | //'default' => $Categ_id |
449 | 452 | // ADD only |
450 | - 'default' => $materiel->categorie_id, | |
453 | + //////'default' => $materiel->categorie_id, | |
451 | 454 | // EDIT only |
452 | 455 | 'disabled' => $IS_ADD ? false : $isReadonlyField('categorie_id', $myReadonlyFields) |
453 | 456 | ]); |
... | ... | @@ -472,7 +475,7 @@ if (isset($cpMateriel)) { |
472 | 475 | 'empty' => 'Choisir une sous-catégorie', |
473 | 476 | // ADD only |
474 | 477 | //'default' => $Sous_categ_id |
475 | - 'default' => $materiel->sous_categorie_id, | |
478 | + /////////'default' => $materiel->sous_categorie_id, | |
476 | 479 | // EDIT only |
477 | 480 | 'disabled' => $IS_ADD ? false : $isReadonlyField('sous_categorie_id', $myReadonlyFields) |
478 | 481 | |
... | ... | @@ -533,7 +536,7 @@ if (isset($cpMateriel)) { |
533 | 536 | 'label' => "Technique (pas pour l'inventaire officiel)", |
534 | 537 | // ADD only |
535 | 538 | //'default' => $Mat_technique |
536 | - 'default' => $materiel->materiel_technique, | |
539 | + /////////'default' => $materiel->materiel_technique, | |
537 | 540 | // EDIT only |
538 | 541 | 'disabled' => $IS_ADD ? false : $isReadonlyField('materiel_technique', $myReadonlyFields) |
539 | 542 | ]); |
... | ... | @@ -654,7 +657,7 @@ if (isset($cpMateriel)) { |
654 | 657 | 'empty' => true, |
655 | 658 | // ADD only |
656 | 659 | //'default' => $Date_reception |
657 | - 'default' => $materiel->date_reception, | |
660 | + ////////'default' => $materiel->date_reception, | |
658 | 661 | |
659 | 662 | // php5... |
660 | 663 | 'value' => $IS_ADD ? null : $value_edit, |
... | ... | @@ -700,7 +703,7 @@ if (isset($cpMateriel)) { |
700 | 703 | 'label' => 'Date fin de garantie', |
701 | 704 | 'placeholder' => $comment, |
702 | 705 | 'class' => 'datepicker', |
703 | - 'default' => NULL, | |
706 | + 'default' => null, | |
704 | 707 | |
705 | 708 | // php5... |
706 | 709 | //'value' => $IS_ADD ? null : $materiel->date_fin_garantie->format('d/m/Y'), |
... | ... | @@ -738,7 +741,8 @@ if (isset($cpMateriel)) { |
738 | 741 | //$readonly = $USER_IS_UTILISATEUR ? TRUE : FALSE; |
739 | 742 | echo $this->Form->control('nom_user', [ |
740 | 743 | 'label' => "Nom de l'Utilisateur (ou destination du bien)", |
741 | - 'empty' => 'Choisir une personne', | |
744 | + //'empty' => 'Choisir une personne', | |
745 | + 'empty' => $username, | |
742 | 746 | //'default' => $username, |
743 | 747 | //'options' => $utilisateurs |
744 | 748 | //'options' => $users_option_list, |
... | ... | @@ -753,11 +757,15 @@ if (isset($cpMateriel)) { |
753 | 757 | $readonly = $USER_IS_UTILISATEUR ? TRUE : FALSE; |
754 | 758 | echo $this->Form->control('nom_responsable', [ |
755 | 759 | 'label' => "Nom de l'Acheteur", |
756 | - 'empty' => 'Choisir une personne', | |
757 | - 'default' => $username, | |
760 | + //'empty' => 'Choisir une personne', | |
761 | + //'empty' => $entity->nom_responsable, | |
762 | + //'default' => $entity->nom_responsable, | |
763 | + //'default' => $username, | |
758 | 764 | //'options' => $utilisateurs |
759 | 765 | 'options' => $users_option_list, |
760 | - 'readonly' => $IS_EDIT ? false : $readonly, | |
766 | + //'readonly' => $IS_EDIT ? false : $readonly, | |
767 | + //'readonly' => $readonly, | |
768 | + 'disabled' => $readonly, | |
761 | 769 | ]); |
762 | 770 | |
763 | 771 | // EDIT only |
... | ... | @@ -806,6 +814,7 @@ if (isset($cpMateriel)) { |
806 | 814 | echo $this->Form->control('gestionnaire_id', [ |
807 | 815 | 'label' => 'Nom gestionnaire de référence', |
808 | 816 | 'empty' => 'Choisir un gestionnaire', |
817 | + // TODO: pas joli ! | |
809 | 818 | 'default' => $_SESSION['Auth']['User']['sn'][0], |
810 | 819 | 'options' => $administrateurs |
811 | 820 | ]); |
... | ... | @@ -914,7 +923,7 @@ if (isset($cpMateriel)) { |
914 | 923 | 'empty' => 'Choisir un organisme', |
915 | 924 | // ADD only |
916 | 925 | //'default' => $Organisme_id |
917 | - 'default' => $materiel->organisme_id, | |
926 | + ///////'default' => $materiel->organisme_id, | |
918 | 927 | // EDIT only |
919 | 928 | 'disabled' => $IS_ADD ? false : $isReadonlyField('organisme_id', $myReadonlyFields) |
920 | 929 | ]); |
... | ... | @@ -924,7 +933,7 @@ if (isset($cpMateriel)) { |
924 | 933 | 'label' => 'Prix HT (€)', |
925 | 934 | // ADD only |
926 | 935 | //'default' => $Prix_ht |
927 | - 'default' => $materiel->prix_ht, | |
936 | + ///////'default' => $materiel->prix_ht, | |
928 | 937 | // EDIT only |
929 | 938 | 'disabled' => $IS_ADD ? false : $isReadonlyField('prix_ht', $myReadonlyFields) |
930 | 939 | ]); | ... | ... |
webroot/doc/diagrams/.DS_Store deleted
No preview for this file type
webroot/doc/diagrams/materiel_state_diagram.png renamed to webroot/doc/diagrams/Materiel_status_state_diagram_v4_2019.png
122 KB
webroot/doc/diagrams/materiel_state_diagram.txt renamed to webroot/doc/diagrams/Materiel_status_state_diagram_v4_2019.txt
webroot/doc/diagrams/INVENTIRAP - equipment_status_state_diagram.png renamed to webroot/doc/diagrams/Materiel_status_state_diagram_v4_2019_old.png
144 KB
webroot/doc/diagrams/INVENTIRAP - equipment_status_state_diagram.txt renamed to webroot/doc/diagrams/Materiel_status_state_diagram_v4_2019_old.txt
245 KB
webroot/doc/diagrams/Materiel_status_state_diagram_v5_2021_01.txt
0 → 100755
... | ... | @@ -0,0 +1,88 @@ |
1 | +@startuml | |
2 | + | |
3 | +'cf http://plantuml.com/fr/state-diagram' | |
4 | + | |
5 | +'Taille des etats :' | |
6 | +'skinparam stateFontSize 10' | |
7 | + | |
8 | + | |
9 | +skinparam titleFontSize 18 | |
10 | +title | |
11 | +__CYCLE DE VIE D'UN MATÉRIEL (SES 4 ÉTATS)__ | |
12 | + | |
13 | +end title | |
14 | + | |
15 | + | |
16 | +state "**CREATED** (créé)" as CREATED | |
17 | +state "**TOBEORDERED** (à commander)" as TOBEORDERED | |
18 | +state "**VALIDATED** (livré et validé)" as VALIDATED | |
19 | +state "**TOBEARCHIVED** (à archiver)" as TOBEARCHIVED | |
20 | +state "**ARCHIVED** (archivé)" as ARCHIVED | |
21 | + | |
22 | + | |
23 | +[*] --> CREATED : \l**Créer** (add) \n(par tout profil) \nInfos obligatoires (LOT1) : \n+ désignation \n+ domaine/catégorie \n+ prix (peut être approximatif) \n + utilisateur destination (champ texte libre) | |
24 | +CREATED -u-> [*]: \l**Supprimer** (delete) \n(par Acheteur, Responsable, ou un ADMIN) \n => Mail à : Acheteur/Utilisateur | |
25 | +CREATED: C'est un état "virtuel", "temporaire" (s'il perdure trop longtemps il sera vu comme "zombie" et supprimé) \n(la section administrative ne peut être saisie que par un ADMIN) | |
26 | +CREATED --> CREATED: \l**Modifier** (edit) \n(par Acheteur/Utilisateur, Responsable, ou un ADMIN)\n (LOT1 reste obligatoire) | |
27 | + | |
28 | +CREATED --> TOBEORDERED: \l**Commander** (order) \n(par Acheteur) \nInfos obligatoires (LOT2) : \n+ LOT1\n+ devis joint\n+ ligne budgétaire\n+ gestionnaire de référence \n => Mail à : Gestionnaire de ref., Gestion [cc], Utilisateur, Responsable | |
29 | +TOBEORDERED --> CREATED : \l **Annuler commande** (deorder) \n (par un ADMIN) \n => Mail à : Acheteur, Utilisateur, Responsable | |
30 | +TOBEORDERED: Le matériel est en attente de commande\n par le gestionnaire de référence | |
31 | +TOBEORDERED --> TOBEORDERED: \l**Actions possibles :**\n - **Modifier** (edit) \n (par Acheteur/Utilisateur, Responsable, ou un ADMIN)\n (LOT2 obligatoire et NON MODIFIABLE, sauf le champ "utilisateur") \n => Mail à : Gestionnaire de référence \n **- Imprimer étiquette(*) ** (par Acheteur/Utilisateur, ou un ADMIN) \n (LOT3 obligatoirement saisi) | |
32 | + | |
33 | +TOBEORDERED --> VALIDATED: \l**Valider** (validate) \n(par Acheteur/Utilisateur ou un ADMIN) \nInfos obligatoires (LOT3) : \n+ LOT2\n+ entité dépens. + n° BC + date BC (ADMIN only) \n+ date livraison \n+ [ n° BL + BL (signé) joint ] \n+ si > 10K€ : S/N + lieu stockage précis... \n+ __Etiquette imprimée(*)__ (on ne peut pas valider sinon) \n => Mail à : Acheteur/Utilisateur, Responsable | |
34 | +VALIDATED --> TOBEORDERED : \l **Invalider** (invalidate) \n (par un ADMIN) \n => Mail à : Acheteur/Utilisateur | |
35 | +VALIDATED: Le matériel a été livré et validé, \net son étiquette imprimée(*) \n(et collée) | |
36 | +VALIDATED --> VALIDATED: \l**Actions possibles :**\n\n - **Modifier** (edit) \n (par Acheteur/Utilisateur, Responsable, ou un ADMIN) \n (LOT3 obligatoire et NON MODIFIABLE, sauf champ "utilisateur") \n (//NB: on ne devrait pas pouvoir modifier la "nature" du bien)// \n => Mail à : Acheteur/Utilisateur, Responsable, Gestionnaire ref. \n\n - **Imprimer étiquette(*) ** (par Acheteur/Utilisateur ou ADMIN) \n - **Prêter** (par Acheteur/Utilisateur) \n - **Faire un Suivi** (par Acheteur/Utilisateur ou Responsable) \n - **Imprimer fiche ENTRÉE matériel** (par ADMIN) | |
37 | + | |
38 | +VALIDATED --> TOBEARCHIVED : \l**Demander archivage** (tobearchived) \n(par Acheteur/Utilisateur, Responsable ou un ADMIN) \n => Mail à : Acheteur/Utilisateur, Responsable, Gestionnaire ref. | |
39 | +TOBEARCHIVED --> VALIDATED : \l **Annuler demande archivage** \n (par Acheteur/Utilisateur, Responsable ou un ADMIN) \n => Mail à : Acheteur/Utilisateur, Responsable, Gestionnaire ref. | |
40 | +TOBEARCHIVED: Le matériel est en demande d'archivage | |
41 | + | |
42 | +TOBEARCHIVED --> ARCHIVED : \l**Archiver** (archive) \n(par ADMIN) \n => Mail à : Acheteur/Utilisateur, Responsable | |
43 | +ARCHIVED --> VALIDATED : \l **Désarchiver** (unarchive) \n (par ADMIN) \n => Mail à : Acheteur/Utilisateur, Responsable | |
44 | +ARCHIVED: Le matériel n'est plus visible (sauf par ADMIN) | |
45 | +ARCHIVED --> ARCHIVED: \l**Imprimer fiche SORTIE matériel** \n(par ADMIN) | |
46 | + | |
47 | + | |
48 | + | |
49 | + | |
50 | + | |
51 | +'On pouvait aussi utiliser _note_ au lieu de _legend_ mais ca se met tout en haut:' | |
52 | +'(cf note dans http://plantuml.com/fr/class-diagram)' | |
53 | +'note as N1' | |
54 | + | |
55 | + | |
56 | +skinparam legendFontSize 11 | |
57 | +legend left | |
58 | +<u>Légende</u>: | |
59 | + | |
60 | +Diagramme UML d'États-Transitions du 02/11/20 - Logiciel LabInvent v5.x - E. Pallier - IRAP | |
61 | + | |
62 | +Acteurs: | |
63 | +- Acheteur : la personne qui commande le matériel | |
64 | +- Utilisateur : le destinataire du matériel (ou la destination) | |
65 | +- Responsable : le(s) responsable(s) (métier, thématique, projet, ou service) du/des groupe(s) auquel(s) le matériel appartient | |
66 | +- Gestionnaire de référence : l'administratif qui passe la commande du matériel (désigné par Acheteur) | |
67 | + (par défaut, celui qui est responsable du projet auquel le matériel est associé) | |
68 | + | |
69 | +Profils (rôles, pouvoirs) : | |
70 | +- UTILISATEUR = Utilisateur quelconque (authentifié) du laboratoire, profil avec les droits minimum | |
71 | +- RESPONSABLE = Responsable d'un groupe (métier, thématique, projet ou service) auquel est rattaché le matériel | |
72 | +- ADMIN = Gestionnaire (Administratif) | |
73 | +- SUPERADMIN = Super utilisateur, il a au moins les mêmes droits que ADMIN | |
74 | + (mais il peut aussi intervenir sur la configuration technique du logiciel) | |
75 | + | |
76 | +Matériel inventoriable = au moins 1000€ HT (en-dessous, le matériel peut quand même être inventorié, mais ne fait pas partie de l'inventaire officiel) | |
77 | + | |
78 | +Un email est envoyé à chaque changement d'état du matériel: | |
79 | +- à l'acheteur et à l'utilisateur | |
80 | +- au(x) responsable(s) du/des groupe(s) (métier, thématique, projet, ou service) auquel(s) le matériel est affecté | |
81 | +- au gestionnaire de référence (éventuellement avec copie au service Gestion) | |
82 | + | |
83 | +//(*) étiquette imprimée => seulement si étiqueteuse disponible// | |
84 | +endlegend | |
85 | +'end note' | |
86 | + | |
87 | + | |
88 | +@enduml | ... | ... |