Commit 3c4f9138ae3fe491f92fab3e26e1955555a21faf
1 parent
cf782ac0
Exists in
master
and in
1 other branch
BIG NEW FEATURE: Config des champs obligatoires et readonly via page web
=> plus besoin de modifier manuellement le fichier de config texte yaml et aussi : - ajout lien vers stats utilisateurs depuis page accueil superadmin - modif page Apropos v5.3.1-3.7.9
Showing
19 changed files
with
899 additions
and
891 deletions
Show diff stats
CHANGELOG
@@ -373,12 +373,6 @@ Par contre, ok avec FPDF | @@ -373,12 +373,6 @@ Par contre, ok avec FPDF | ||
373 | 373 | ||
374 | *) LDAP trou sécu (autres labos) : user se connecte avec bad mdp | 374 | *) LDAP trou sécu (autres labos) : user se connecte avec bad mdp |
375 | 375 | ||
376 | - *) | ||
377 | - Rendre modifiable la config via page web "Gérer les champs obligatoires" | ||
378 | - - OFF_nom_du_champ : 'libellé' | ||
379 | - - Restaurer la config par défaut | ||
380 | - - Réactiver une variable : OFF_nom_du_champ => nom_du_champ | ||
381 | - | ||
382 | *) => update matos lifecycle diag | 376 | *) => update matos lifecycle diag |
383 | 377 | ||
384 | 378 | ||
@@ -541,11 +535,19 @@ TODO : | @@ -541,11 +535,19 @@ TODO : | ||
541 | 535 | ||
542 | - add_edit generic | 536 | - add_edit generic |
543 | 537 | ||
544 | -- fusionner groupe thematique et metier (et projet ?) | 538 | +- fusionner groupe thematique et metier (et projet ?) : |
539 | + => faire hériter les Controller et les Table d'une meme superclasse GroupController et GroupTable | ||
540 | + => avoir un seul template | ||
541 | + => c'est vraiment stupide d'avoir 2 classes qui font la meme chose... | ||
545 | 542 | ||
546 | - Utiliser les vues "index" des entités associées pour la vue "view" de materiel (et suivi) : | 543 | - Utiliser les vues "index" des entités associées pour la vue "view" de materiel (et suivi) : |
547 | => éviter la redondance, le contenu est pratiquement le meme (???, sauf que les colonnes ne sont pas triables) | 544 | => éviter la redondance, le contenu est pratiquement le meme (???, sauf que les colonnes ne sont pas triables) |
548 | 545 | ||
546 | +- Bien préciser quels sont les champs obligatoires avec une asterisque (et pour chaque LOT) | ||
547 | + | ||
548 | +- S/N à renseigner (recommended) ssi > 10000€ | ||
549 | + Ajouter champ attributes.condition = "prix > 10000" | ||
550 | + | ||
549 | ======= NEXT ======= | 551 | ======= NEXT ======= |
550 | 552 | ||
551 | print etiquette pour les 2 serveurs + tester fin garantie orange | 553 | print etiquette pour les 2 serveurs + tester fin garantie orange |
@@ -563,9 +565,45 @@ Vues génériques (index et view) : | @@ -563,9 +565,45 @@ Vues génériques (index et view) : | ||
563 | - Suivis.statut => "en cours" ou "à terminer" => à calculer auto | 565 | - Suivis.statut => "en cours" ou "à terminer" => à calculer auto |
564 | 566 | ||
565 | 567 | ||
568 | + *) | ||
569 | + Rendre modifiable la config via page web "Gérer les champs obligatoires" | ||
570 | + - OFF_nom_du_champ : 'libellé' | ||
571 | + - Restaurer la config par défaut | ||
572 | + - Réactiver une variable : OFF_nom_du_champ => nom_du_champ | ||
573 | + | ||
574 | + | ||
575 | +saisir les personnes du gt2i et de tous les groupes... | ||
576 | + | ||
577 | +groupe.users associés : ajouter "(responsable)" when relevant | ||
578 | + | ||
579 | +comment faire un tri sur la dernière colonne des stats (connexDurAvg) ? | ||
580 | + | ||
581 | +erreur download depuis page documents/ (ou depuis vue du matériel) sur inventirap : erreur 404 (action impossible) | ||
582 | + | ||
583 | +TODO config fields : | ||
584 | +- réadapter lecture config à new file format | ||
585 | +- compléter le fichier config avec tous les champs possibles à chaque lot !!! | ||
586 | +- fichier read-write par web server | ||
587 | +- ./UPDATE cral et ip2i + new config file | ||
588 | +- pub | ||
589 | +- soigner la présentation du form (peu lisible now) | ||
590 | + | ||
591 | + | ||
592 | + - (b) Bugfix fournisseur perdu (et champ vide qui n'est plus modifiable !) après validation du matos | ||
593 | + (quand il manque un champ pour valider), et pourtant bien enregistré dans listes des fournisseurs | ||
594 | + | ||
595 | + | ||
566 | ======= CHANGES ======= | 596 | ======= CHANGES ======= |
567 | 597 | ||
568 | ------- | 598 | ------- |
599 | +22/11/2021 v5.3.1-3.7.9 | ||
600 | + - (e) BIG NEW FEATURE : Configuration des champs obligatoires et readonly se fait maintenant via page WEB !!! | ||
601 | + => plus besoin de modifier manuellement le fichier de config texte yaml | ||
602 | + - (e) ajout lien vers stats utilisateurs depuis page accueil superadmin | ||
603 | + - (e) modif page Apropos | ||
604 | + | ||
605 | + | ||
606 | +------- | ||
569 | 15/11/2021 v5.3.0-3.7.9 | 607 | 15/11/2021 v5.3.0-3.7.9 |
570 | - (e) Refactorisation : Vue détaillée users (view) générique avec contenu enrichi ("(responsable)") | 608 | - (e) Refactorisation : Vue détaillée users (view) générique avec contenu enrichi ("(responsable)") |
571 | - (e) Refactorisation : Vue liste users (index) générique avec contenu enrichi ("(responsable)") | 609 | - (e) Refactorisation : Vue liste users (index) générique avec contenu enrichi ("(responsable)") |
README.md
@@ -52,8 +52,8 @@ Logiciel testé et validé sur les configurations suivantes : | @@ -52,8 +52,8 @@ Logiciel testé et validé sur les configurations suivantes : | ||
52 | 52 | ||
53 | -------------------------------------------------------------------------------------------- | 53 | -------------------------------------------------------------------------------------------- |
54 | 54 | ||
55 | -Date: 15/11/2021 | ||
56 | -Version: v5.3.0-3.7.9 | 55 | +Date: 22/11/2021 |
56 | +Version: v5.3.1-3.7.9 | ||
57 | 57 | ||
58 | 58 | ||
59 | HISTORIQUE DES CHANGEMENTS DE VERSION : voir le fichier CHANGES.txt (ou la page web /pages/changes) | 59 | HISTORIQUE DES CHANGEMENTS DE VERSION : voir le fichier CHANGES.txt (ou la page web /pages/changes) |
config/app_labinvent_mandatory_fields.default.yml deleted
@@ -1,616 +0,0 @@ | @@ -1,616 +0,0 @@ | ||
1 | -# FICHIER DE CONFIGURATION PAR DÉFAUT POUR LES CHAMPS D'UN MATÉRIEL | ||
2 | - | ||
3 | - | ||
4 | -# Activer la possibilité de commander un matériel (au service gestion) en cliquant sur un bouton "Commander" ? | ||
5 | -# L'étape "A commander" (status TOBEORDERED) devient alors une étape intermédiaire OPTIONNELLE entre CREATED et VALIDATED | ||
6 | -# Les transitions de statut d'un materiel sont alors : CREATED => [ TEBEORDERED (à commander) ] => VALIDATED => TOBEARCHIVED => ARCHIVED | ||
7 | -HAS_ORDER_BUTTON: true | ||
8 | -#HAS_ORDER_BUTTON: false | ||
9 | - | ||
10 | - | ||
11 | - | ||
12 | -# ************************************************************ | ||
13 | -# ************** CHAMPS INITIALEMENT READONLY **************** | ||
14 | -# ************************************************************ | ||
15 | - | ||
16 | -# Un champ peut etre readonly pour 3 raisons : | ||
17 | -# - soit parce qu’il a une valeur par défaut non modifiable (ex: Acheteur = celui qui crée la fiche), | ||
18 | -# - soit parce qu’il est réservé à l’Administration (champs administratifs, « Admin only »), | ||
19 | -# - soit parce qu’il a servi à valider une étape et ne doit donc plus être changé (sous peine d’invalider l’étape) | ||
20 | - | ||
21 | -UNEDITABLE_FIELDS: | ||
22 | - | ||
23 | - # #### CHAMPS GÉNÉRAUX #### | ||
24 | - | ||
25 | - #- designation | ||
26 | - | ||
27 | - #- will_stay | ||
28 | - | ||
29 | - #- description | ||
30 | - | ||
31 | - #- hors_service | ||
32 | - | ||
33 | - #- sur_categorie_id | ||
34 | - | ||
35 | - #- categorie_id | ||
36 | - | ||
37 | - #- sous_categorie_id | ||
38 | - | ||
39 | - #- groupes_thematique_id | ||
40 | - | ||
41 | - #- groupes_metier_id | ||
42 | - | ||
43 | - #- projet_id | ||
44 | - | ||
45 | - #- materiel_technique | ||
46 | - #- materiel_administratif | ||
47 | - | ||
48 | - #- metrologie | ||
49 | - | ||
50 | - #- etiquette | ||
51 | - | ||
52 | - #- site_id | ||
53 | - | ||
54 | - #- lieu_detail | ||
55 | - | ||
56 | - #- date_acquisition | ||
57 | - | ||
58 | - #- date_reception | ||
59 | - | ||
60 | - # Garantie | ||
61 | - #- duree_garantie | ||
62 | - #- unite_duree_garantie | ||
63 | - #- date_fin_garantie | ||
64 | - | ||
65 | - # Super Administrateur only | ||
66 | - #- status | ||
67 | - | ||
68 | - #- numero_serie | ||
69 | - | ||
70 | - # Utilisateur du materiel (destinataire du bien) | ||
71 | - #- nom_user | ||
72 | - | ||
73 | - # - Acheteur (le Créateur de la fiche) - Un role "Utilisateur" ne peut pas changer ça, c'est par défaut lui-même | ||
74 | - - nom_responsable (sauf Responsable, Administration) | ||
75 | - | ||
76 | - #- nom_ancien_responsable | ||
77 | - | ||
78 | - #- resp_credit | ||
79 | - | ||
80 | - #- gestionnaire_id | ||
81 | - | ||
82 | - #- fournisseur_id | ||
83 | - | ||
84 | - #- organisme_id | ||
85 | - | ||
86 | - #- prix_ht | ||
87 | - | ||
88 | - #- budgets | ||
89 | - | ||
90 | - | ||
91 | - # #### CHAMPS ADMINISTRATIFS : #### | ||
92 | - | ||
93 | - # Entité(s) dépensière(s) (budget(s)) // ligne budgétaire (sur quel(s) budget(s)) ou entité(s) dépensière(s) ?) | ||
94 | - - eotp (sauf Administration) | ||
95 | - - numero_commande (sauf Administration) | ||
96 | - - numero_inventaire_organisme (sauf Administration) | ||
97 | - - numero_inventaire_old (sauf Administration) | ||
98 | - - numero_laboratoire # READONLY toujours car généré automatiquement | ||
99 | - | ||
100 | - | ||
101 | - | ||
102 | - | ||
103 | - | ||
104 | - | ||
105 | -# *************************************************************** | ||
106 | -# ************** LOT 0 - CRÉATION FICHE MATÉRIEL **************** | ||
107 | -# *************************************************************** | ||
108 | - | ||
109 | -# Champs OBLIGATOIRES pour CRÉER une fiche Matériel | ||
110 | -# - Aucun champ | ||
111 | -#MANDATORY_FIELDS_FOR_LOT0: [] | ||
112 | -# - Au moins un champ | ||
113 | -MANDATORY_FIELDS_FOR_LOT0: | ||
114 | - | ||
115 | - # Infos toujours obligatoires (cachées car calculées automatiquement) | ||
116 | - #'status', | ||
117 | - #'tobeordered', | ||
118 | - | ||
119 | - designation: 'Désignation' | ||
120 | - | ||
121 | - description: 'Description' | ||
122 | - | ||
123 | - sur_categorie_id: 'Domaine' | ||
124 | - categorie_id: 'Catégorie' | ||
125 | - | ||
126 | - # - Acheteur (le Créateur de la fiche) | ||
127 | - nom_responsable: "Nom de l'Acheteur" | ||
128 | - #// (rempli automatiquement) | ||
129 | - email_responsable: "Email de l'Acheteur" | ||
130 | - | ||
131 | - # - Utilisateur | ||
132 | - nom_user: "Nom de l'utilisateur" | ||
133 | - | ||
134 | - # Calculé auto au moment du save() | ||
135 | - #'numero_laboratoire', | ||
136 | - | ||
137 | - # ******* END OF MANDATORY_FIELDS_LOT0 ******** | ||
138 | - | ||
139 | - | ||
140 | -# Liste des champs qui sont NON MODIFIABLES APRÈS la CRÉATION d'une fiche | ||
141 | -# Attention, les champs UNEDITABLE_FIELDS (voir au début du fichier) sont aussi pris en compte (donc, inutile de les répéter) | ||
142 | - | ||
143 | -# - Aucun champ | ||
144 | -UNEDITABLE_FIELDS_AFTER_LOT0: [] | ||
145 | - | ||
146 | -# - Au moins un champ | ||
147 | -#UNEDITABLE_FIELDS_AFTER_LOT0: | ||
148 | - | ||
149 | - # #### CHAMPS GÉNÉRAUX #### | ||
150 | - | ||
151 | - #- designation | ||
152 | - | ||
153 | - #- will_stay | ||
154 | - | ||
155 | - #- description | ||
156 | - | ||
157 | - #- hors_service | ||
158 | - | ||
159 | - #- sur_categorie_id | ||
160 | - | ||
161 | - #- categorie_id | ||
162 | - | ||
163 | - #- sous_categorie_id | ||
164 | - | ||
165 | - #- groupes_thematique_id | ||
166 | - | ||
167 | - #- groupes_metier_id | ||
168 | - | ||
169 | - #- projet_id | ||
170 | - | ||
171 | - #- materiel_technique | ||
172 | - #- materiel_administratif | ||
173 | - | ||
174 | - #- metrologie | ||
175 | - | ||
176 | - #- etiquette | ||
177 | - | ||
178 | - #- site_id | ||
179 | - | ||
180 | - #- lieu_detail | ||
181 | - | ||
182 | - #- date_acquisition | ||
183 | - | ||
184 | - #- date_reception | ||
185 | - | ||
186 | - # Garantie | ||
187 | - #- duree_garantie | ||
188 | - #- unite_duree_garantie | ||
189 | - #- date_fin_garantie | ||
190 | - | ||
191 | - # Super Administrateur only | ||
192 | - #- status | ||
193 | - | ||
194 | - #- numero_serie | ||
195 | - | ||
196 | - # Utilisateur du materiel (destinataire du bien) | ||
197 | - #- nom_user | ||
198 | - | ||
199 | - # - Acheteur (le Créateur de la fiche) - Un role "Utilisateur" ne peut pas changer ça, c'est par défaut lui-même | ||
200 | - #- nom_responsable (sauf Responsable, Administration) | ||
201 | - | ||
202 | - #- nom_ancien_responsable | ||
203 | - | ||
204 | - #- resp_credit | ||
205 | - | ||
206 | - #- gestionnaire_id | ||
207 | - | ||
208 | - #- fournisseur_id | ||
209 | - | ||
210 | - #- organisme_id | ||
211 | - | ||
212 | - #- prix_ht | ||
213 | - | ||
214 | - #- budgets | ||
215 | - | ||
216 | - # #### CHAMPS ADMINISTRATIFS : #### | ||
217 | - #- eotp (sauf Administration) | ||
218 | - #- numero_commande (sauf Administration) | ||
219 | - #- numero_laboratoire # READONLY toujours car généré automatiquement | ||
220 | - #- numero_inventaire_organisme (sauf Administration) | ||
221 | - #- numero_inventaire_old (sauf Administration) | ||
222 | - | ||
223 | - | ||
224 | -# Champs NON OBLIGATOIRES MAIS FORTEMENT RECOMMANDÉS APRÈS COMMANDE | ||
225 | -# Ces champs ne seront pas demandés à la saisie, mais un simple rappel sera affiché sur la vue détaillée du matériel (tant que ces éléments sont absents) | ||
226 | -# Attention, les champs RECOMMENDED_FIELDS_XXX définis plus haut sont aussi pris en compte (donc, inutile de les répéter) | ||
227 | -# - Aucun champ | ||
228 | -RECOMMENDED_FIELDS_AFTER_LOT0: [] | ||
229 | - | ||
230 | - | ||
231 | - | ||
232 | - | ||
233 | - | ||
234 | - | ||
235 | - | ||
236 | - | ||
237 | -# ****************************************************************************** | ||
238 | -# ************** LOT 1 - COMMANDE (DEMANDE D'ACHAT) (optionnel) **************** | ||
239 | -# ****************************************************************************** | ||
240 | - | ||
241 | -# Champs OBLIGATOIRES POUR passer la COMMANDE (La commande est une action optionnelle) | ||
242 | -# Attention, les champs MANDATORY_FIELDS_XXX définis plus haut sont aussi pris en compte (donc, inutile de les répéter) | ||
243 | -# - Aucun champ | ||
244 | -#MANDATORY_FIELDS_FOR_LOT1: [] | ||
245 | -# - Au moins un champ | ||
246 | -MANDATORY_FIELDS_FOR_LOT1: | ||
247 | - | ||
248 | - # Infos toujours obligatoires (cachées car calculées automatiquement) | ||
249 | - #'status', | ||
250 | - #'tobeordered', | ||
251 | - | ||
252 | - #'hors_service', // O/N | ||
253 | - | ||
254 | - ##designation: 'Désignation' | ||
255 | - | ||
256 | - ##description: 'Description' | ||
257 | - | ||
258 | - #'permanent', | ||
259 | - #'will_stay', // O/N | ||
260 | - | ||
261 | - ##sur_categorie_id: 'Domaine' | ||
262 | - ##categorie_id: 'Catégorie' | ||
263 | - | ||
264 | - # - Utilisateur | ||
265 | - #nom_user: "Nom de l'utilisateur de ce matériel" | ||
266 | - | ||
267 | - # - Acheteur | ||
268 | - #nom_responsable: 'Nom du responsable' | ||
269 | - # (rempli automatiquement) | ||
270 | - #email_responsable: 'Email du responsable' | ||
271 | - | ||
272 | - # Calculé auto au moment du save() | ||
273 | - #'numero_laboratoire', | ||
274 | - | ||
275 | - organisme_id: 'Organisme' | ||
276 | - | ||
277 | - prix_ht: 'Prix HT' | ||
278 | - | ||
279 | - # (par défaut = acheteur) | ||
280 | - resp_credit: 'Responsable du crédit' | ||
281 | - | ||
282 | - # Gestionnaire de référence (recevra la commande) | ||
283 | - gestionnaire_id: 'Gestionnaire de référence' | ||
284 | - | ||
285 | - # Fournisseur | ||
286 | - fournisseur_id: 'Fournisseur' | ||
287 | - | ||
288 | - # Utilisé par la Gestion pour remplir le champ eotp | ||
289 | - budgets: 'Budgets' | ||
290 | - | ||
291 | - # INFOS ADMINISTRATIVES | ||
292 | - # - EOTP : obligatoire seulement dans LOT2 | ||
293 | - | ||
294 | - # - Devis joint : c'est un champ virtuel, il n'existe pas physiquement (sauf dans la table Documents) | ||
295 | - DOC_DEVIS: 'Devis' | ||
296 | - #DOC_BC: "Bon de Commande" | ||
297 | - #DOC_BL: "Bon de Livraison" | ||
298 | - #DOC_FACTURE: "Facture" | ||
299 | - | ||
300 | - | ||
301 | - # ******* END OF MANDATORY_FIELDS_LOT1 ******** | ||
302 | - | ||
303 | - | ||
304 | -# Liste des champs NON MODIFIABLES APRÈS la demande d'ACHAT (c'est à dire APRÈS avoir fait la "COMMANDE") | ||
305 | -# Attention, les champs UNEDITABLE_FIELDS_XXX définis plus haut sont aussi pris en compte (donc, inutile de les répéter) | ||
306 | -# - Aucun champ | ||
307 | -#UNEDITABLE_FIELDS_AFTER_LOT1: [] | ||
308 | -# - Au moins un champ | ||
309 | -UNEDITABLE_FIELDS_AFTER_LOT1: | ||
310 | - | ||
311 | - # #### CHAMPS GÉNÉRAUX #### | ||
312 | - | ||
313 | - #- designation | ||
314 | - | ||
315 | - #- will_stay | ||
316 | - | ||
317 | - #- description | ||
318 | - | ||
319 | - #- hors_service | ||
320 | - | ||
321 | - # On ne devrait pas pouvoir changer la NATURE du bien | ||
322 | - # Domaine & Catégorie | ||
323 | - - sur_categorie_id (sauf Administration) # Domaine | ||
324 | - - categorie_id (sauf Administration) # Catégorie | ||
325 | - #- sous_categorie_id | ||
326 | - | ||
327 | - #- groupes_thematique_id | ||
328 | - | ||
329 | - #- groupes_metier_id | ||
330 | - | ||
331 | - #- projet_id | ||
332 | - | ||
333 | - #- materiel_technique | ||
334 | - #- materiel_administratif | ||
335 | - | ||
336 | - #- metrologie | ||
337 | - | ||
338 | - #- etiquette | ||
339 | - | ||
340 | - #- site_id | ||
341 | - | ||
342 | - #- lieu_detail | ||
343 | - | ||
344 | - #- date_acquisition | ||
345 | - | ||
346 | - #- date_reception | ||
347 | - | ||
348 | - # Garantie | ||
349 | - #- duree_garantie | ||
350 | - #- unite_duree_garantie | ||
351 | - #- date_fin_garantie | ||
352 | - | ||
353 | - # Super Administrateur only | ||
354 | - #- status | ||
355 | - | ||
356 | - #- numero_serie | ||
357 | - | ||
358 | - # Utilisateur du materiel (destinataire du bien) | ||
359 | - #- nom_user | ||
360 | - | ||
361 | - # - Acheteur (le Créateur de la fiche) - Un role "Utilisateur" ne peut pas changer ça, c'est par défaut lui-même | ||
362 | - #- nom_responsable (sauf Responsable, Administration) | ||
363 | - | ||
364 | - #- nom_ancien_responsable | ||
365 | - | ||
366 | - # (par défaut = acheteur) | ||
367 | - - resp_credit (sauf Administration) | ||
368 | - | ||
369 | - - gestionnaire_id (sauf Administration) | ||
370 | - | ||
371 | - # Fournisseur | ||
372 | - - fournisseur_id (sauf Administration) | ||
373 | - | ||
374 | - - organisme_id (sauf Administration) | ||
375 | - | ||
376 | - - prix_ht (sauf Administration) | ||
377 | - | ||
378 | - # Utilisé par la Gestion pour remplir le champ eotp | ||
379 | - - budgets (sauf Administration) | ||
380 | - | ||
381 | - | ||
382 | - # #### CHAMPS VIRTUELS : doc attachés #### | ||
383 | - # Ces champs virtuels n'existent pas physiquement (sauf dans la table Documents) | ||
384 | - # On indique ici les documents attachés à la fiche matériel, qui ne peuvent plus être ni modifiés ni supprimés | ||
385 | - # - Devis | ||
386 | - # Le devis attaché au matériel commandé n'est ni modifiable ni supprimable | ||
387 | - - DOC_DEVIS | ||
388 | - # - Bon de Commande (si un BC a été joint à la fiche, on ne peut plus le modifier ni le supprimer) | ||
389 | - - DOC_BC (sauf Administration) | ||
390 | - # - Bon de Livraison | ||
391 | - #- DOC_BL | ||
392 | - # - Facture | ||
393 | - #- DOC_FACTURE | ||
394 | - | ||
395 | - | ||
396 | - # #### CHAMPS ADMINISTRATIFS : #### | ||
397 | - #- eotp (sauf Administration) | ||
398 | - #- numero_commande (sauf Administration) | ||
399 | - #- numero_laboratoire # READONLY toujours car généré automatiquement | ||
400 | - #- numero_inventaire_organisme (sauf Administration) | ||
401 | - #- numero_inventaire_old (sauf Administration) | ||
402 | - | ||
403 | - | ||
404 | - | ||
405 | -# Champs NON OBLIGATOIRES MAIS FORTEMENT RECOMMANDÉS APRÈS COMMANDE | ||
406 | -# Ces champs ne seront pas demandés à la saisie, mais un simple rappel sera affiché sur la vue détaillée du matériel (tant que ces éléments sont absents) | ||
407 | -# Attention, les champs RECOMMENDED_FIELDS_XXX définis plus haut sont aussi pris en compte (donc, inutile de les répéter) | ||
408 | -# - Aucun champ | ||
409 | -RECOMMENDED_FIELDS_AFTER_LOT1: [] | ||
410 | -#RECOMMENDED_FIELDS_AFTER_LOT1: | ||
411 | - # - Etiquette posée sur le matériel | ||
412 | - #etiquette: "d'imprimer l'étiquette associée et de la coller sur le matériel" | ||
413 | - | ||
414 | - | ||
415 | - | ||
416 | - | ||
417 | - | ||
418 | - | ||
419 | - | ||
420 | - | ||
421 | -# *************************************************************************** | ||
422 | -# ************** LOT 2 - VALIDATION (matériel livré et payé) **************** | ||
423 | -# *************************************************************************** | ||
424 | - | ||
425 | -# Champs OBLIGATOIRES POUR VALIDER la livraison | ||
426 | -# Attention, les champs MANDATORY_FIELDS_XXX définis plus haut sont aussi pris en compte (donc, inutile de les répéter) | ||
427 | -# - Aucun champ | ||
428 | -#MANDATORY_FIELDS_FOR_LOT2: [] | ||
429 | -# - Au moins un champ | ||
430 | -MANDATORY_FIELDS_FOR_LOT2: | ||
431 | - | ||
432 | - #//'fournisseur_id' => 'Fournisseur', | ||
433 | - #//'fournisseur' => 'Fournisseur', | ||
434 | - | ||
435 | - date_acquisition: "Date d'achat" | ||
436 | - | ||
437 | - date_reception: 'Date de livraison' | ||
438 | - | ||
439 | - site_id: 'Site' | ||
440 | - | ||
441 | - #TODO: seulement si prix > 10K€ | ||
442 | - lieu_detail: 'Lieu de stockage' | ||
443 | - #numero_serie: 'S/N' | ||
444 | - | ||
445 | - #// INFOS ADMINISTRATIVES : | ||
446 | - | ||
447 | - #// La Gestion doit remplir ce champ a partir des infos qui sont dans le champ "budget" (rempli par acheteur) | ||
448 | - #// ligne budgétaire (sur quel(s) budget(s)) ou entité(s) dépensière(s) | ||
449 | - eotp: 'Entité(s) dépensière(s) (budget(s))' | ||
450 | - | ||
451 | - numero_commande: 'Num. BC' | ||
452 | - | ||
453 | - # Docs attachés obligatoires pour valider | ||
454 | - DOC_DEVIS: 'Devis' | ||
455 | - #DOC_BC: "Bon de Commande" | ||
456 | - #DOC_BL: "Bon de Livraison" | ||
457 | - #DOC_FACTURE: "Facture" | ||
458 | - | ||
459 | - | ||
460 | - # ******* END OF $MANDATORY_FIELDS_LOT2 ******** | ||
461 | - | ||
462 | - | ||
463 | - | ||
464 | - | ||
465 | -# Champs NON OBLIGATOIRES MAIS FORTEMENT RECOMMANDÉS APRÈS VALIDATION de la livraison | ||
466 | -# Ces champs ne seront pas demandés à la saisie, mais un simple rappel sera affiché sur la vue détaillée du matériel (tant que ces éléments sont absents) | ||
467 | -# Attention, les champs RECOMMENDED_FIELDS_XXX définis plus haut sont aussi pris en compte (donc, inutile de les répéter) | ||
468 | -# - Aucun champ | ||
469 | -#RECOMMENDED_FIELDS_AFTER_LOT2: [] | ||
470 | -# - Au moins un champ | ||
471 | -RECOMMENDED_FIELDS_AFTER_LOT2: | ||
472 | - | ||
473 | - | ||
474 | - # - Etiquette posée sur le matériel | ||
475 | - etiquette: "d'imprimer l'étiquette associée et de la coller sur le matériel" | ||
476 | - | ||
477 | - # - Numéro inventaire tutelles | ||
478 | - # On aurait pu rendre cet élément obligatoire mais on ne peut pas l'exiger au moment de la livraison | ||
479 | - # car le gestionnaire n'a cette info que lorsque "Service fait CNRS" (il récupère alors le n° inventaire "Tutelle" sur GESLAB) | ||
480 | - numero_inventaire_organisme: "de renseigner le champ 'N° inventaire comptable/tutelles (Organisme)'" | ||
481 | - | ||
482 | - | ||
483 | - # DOCS ATTACHÉS recommandés après validation | ||
484 | - #DOC_DEVIS: "d'ajouter un Devis" | ||
485 | - DOC_BC: "d'ajouter le Bon de Commande" | ||
486 | - DOC_BL: "d'ajouter le Bon de Livraison" | ||
487 | - DOC_FACTURE: "d'ajouter la Facture" | ||
488 | - | ||
489 | - | ||
490 | - | ||
491 | - | ||
492 | - | ||
493 | -# Liste des champs qui sont NON MODIFIABLES APRÈS la VALIDATION (livraison) | ||
494 | -# Attention, les champs UNEDITABLE_FIELDS_XXX définis plus haut sont aussi pris en compte | ||
495 | -# - Aucun champ | ||
496 | -#UNEDITABLE_FIELDS_AFTER_LOT2: [] | ||
497 | -# - Au moins un champ | ||
498 | -UNEDITABLE_FIELDS_AFTER_LOT2: | ||
499 | - | ||
500 | - # #### CHAMPS GÉNÉRAUX #### | ||
501 | - | ||
502 | - #- designation | ||
503 | - | ||
504 | - #- will_stay | ||
505 | - | ||
506 | - #- description | ||
507 | - | ||
508 | - #- hors_service | ||
509 | - | ||
510 | - - sur_categorie_id | ||
511 | - - categorie_id | ||
512 | - | ||
513 | - #- sous_categorie_id | ||
514 | - | ||
515 | - #- groupes_thematique_id | ||
516 | - | ||
517 | - #- groupes_metier_id | ||
518 | - | ||
519 | - #- projet_id | ||
520 | - | ||
521 | - #- materiel_technique | ||
522 | - #- materiel_administratif | ||
523 | - | ||
524 | - #- metrologie | ||
525 | - | ||
526 | - #- etiquette | ||
527 | - | ||
528 | - #- site_id | ||
529 | - | ||
530 | - #- lieu_detail | ||
531 | - | ||
532 | - - date_acquisition | ||
533 | - - date_reception | ||
534 | - | ||
535 | - # Garantie | ||
536 | - #- duree_garantie | ||
537 | - #- unite_duree_garantie | ||
538 | - #- date_fin_garantie | ||
539 | - | ||
540 | - # Super Administrateur only | ||
541 | - #- status | ||
542 | - | ||
543 | - #- numero_serie | ||
544 | - | ||
545 | - # Utilisateur du materiel (destinataire du bien) | ||
546 | - #- nom_user | ||
547 | - | ||
548 | - # - Acheteur (le Créateur de la fiche) - Un role "Utilisateur" ne peut pas changer ça, c'est par défaut lui-même | ||
549 | - #- nom_responsable (sauf Responsable, Administration) | ||
550 | - | ||
551 | - #- nom_ancien_responsable | ||
552 | - | ||
553 | - #- resp_credit | ||
554 | - | ||
555 | - #- gestionnaire_id | ||
556 | - | ||
557 | - #- fournisseur_id | ||
558 | - | ||
559 | - #- organisme_id | ||
560 | - | ||
561 | - #- prix_ht | ||
562 | - | ||
563 | - #- budgets | ||
564 | - | ||
565 | - | ||
566 | - # #### CHAMPS ADMINISTRATIFS #### | ||
567 | - | ||
568 | - - eotp | ||
569 | - - numero_commande | ||
570 | - # READONLY toujours car généré automatiquement | ||
571 | - #- numero_laboratoire | ||
572 | - #- numero_inventaire_organisme | ||
573 | - #- numero_inventaire_old | ||
574 | - | ||
575 | - | ||
576 | - # DOCS ATTACHÉS qui ne sont plus ni supprimables ni modifiables | ||
577 | - # - Devis | ||
578 | - #- DOC_DEVIS | ||
579 | - # - Bon de Commande | ||
580 | - - DOC_BC | ||
581 | - # - Bon de Livraison | ||
582 | - - DOC_BL | ||
583 | - # - Facture | ||
584 | - - DOC_FACTURE | ||
585 | - | ||
586 | - | ||
587 | - | ||
588 | - | ||
589 | -# ****************************************************************************** | ||
590 | -# ************** LOT 3 - ARCHIVAGE (matériel à sortir ou sorti) **************** | ||
591 | -# ****************************************************************************** | ||
592 | - | ||
593 | -# (TODO) Ce 3e niveau n'est pas encore implémenté, il est pour l'instant codé en dur dans le code | ||
594 | - | ||
595 | -# - Aucun champ | ||
596 | -MANDATORY_FIELDS_FOR_LOT3: [] | ||
597 | - | ||
598 | -# - Aucun champ | ||
599 | -UNEDITABLE_FIELDS_AFTER_LOT3: [] | ||
600 | -# En fait, TOUS LES CHAMPS SONT READONLY SAUF : description, ... | ||
601 | - | ||
602 | - | ||
603 | - | ||
604 | - | ||
605 | - | ||
606 | - | ||
607 | - | ||
608 | - | ||
609 | - | ||
610 | - | ||
611 | -# Astuce utilisable : | ||
612 | -# Pour faire : MANDATORY_FIELDS_LOT2 = MANDATORY_FIELDS_LOT1 | ||
613 | -# On fait comme ceci : | ||
614 | -#MANDATORY_FIELDS_LOT1: &lot1 | ||
615 | -#MANDATORY_FIELDS_LOT2: *lot1 | ||
616 | - |
config/bootstrap.php
@@ -36,6 +36,10 @@ use Yaml\Configure\Engine\YamlConfig; | @@ -36,6 +36,10 @@ use Yaml\Configure\Engine\YamlConfig; | ||
36 | */ | 36 | */ |
37 | require __DIR__ . '/paths.php'; | 37 | require __DIR__ . '/paths.php'; |
38 | 38 | ||
39 | +/* EP 2021-11 : mes propres constantes */ | ||
40 | +define('CONFIG_MATERIEL_FIELDS_FILE_NAME', 'app_labinvent_mandatory_fields'); | ||
41 | + | ||
42 | + | ||
39 | // Use composer to load the autoloader. | 43 | // Use composer to load the autoloader. |
40 | require ROOT . DS . 'vendor' . DS . 'autoload.php'; | 44 | require ROOT . DS . 'vendor' . DS . 'autoload.php'; |
41 | 45 | ||
@@ -106,17 +110,31 @@ try { | @@ -106,17 +110,31 @@ try { | ||
106 | } | 110 | } |
107 | 111 | ||
108 | // (EP 2021 09 Ajout nouveaux fichiers config pour les champs obligatoires (et les autorisations)) | 112 | // (EP 2021 09 Ajout nouveaux fichiers config pour les champs obligatoires (et les autorisations)) |
109 | -$config_mandatory_fields_file_name = 'app_labinvent_mandatory_fields'; | 113 | +//$config_mandatory_fields_file_name = 'app_labinvent_mandatory_fields'; |
110 | // Si le fichier de conf n'existe pas, on le crée en copiant le fichier par défaut | 114 | // Si le fichier de conf n'existe pas, on le crée en copiant le fichier par défaut |
111 | -if ( !file_exists(CONFIG.DS.$config_mandatory_fields_file_name.'.yml') ) | ||
112 | - copy(CONFIG.DS.$config_mandatory_fields_file_name.'.default.yml', CONFIG.DS.$config_mandatory_fields_file_name.'.yml'); | 115 | +//if ( !file_exists(CONFIG.DS.$config_mandatory_fields_file_name.'.yml') ) |
116 | +//$config_matos_full_file_name = $config_matos_full_file_name_default = CONFIG.DS.CONFIG_MATERIEL_FIELDS_FILE_NAME; | ||
117 | +$config_matos_full_file_name = $config_matos_full_file_name_default = CONFIG_MATERIEL_FIELDS_FILE_NAME; | ||
118 | +//$config_matos_full_file_name_default = $config_matos_full_file_name; | ||
119 | +$config_matos_full_file_name .= '.yml'; | ||
120 | +$config_matos_full_file_name_default .= '.default.yml'; | ||
121 | +//if ( !file_exists($config_matos_full_file_name) ) copy($config_matos_full_file_name_default, $config_matos_full_file_name); | ||
113 | try { | 122 | try { |
114 | - Configure::config('yaml', new YamlConfig()); | ||
115 | - Configure::load($config_mandatory_fields_file_name, 'yaml'); | 123 | + Configure::config('my_yaml_engine', new YamlConfig()); |
124 | + //Configure::load($config_mandatory_fields_file_name, 'yaml', true); | ||
125 | + Configure::load(CONFIG_MATERIEL_FIELDS_FILE_NAME, 'my_yaml_engine'); | ||
116 | //Configure::load('app_labinvent_mandatory_fields_IP2I', 'yaml'); | 126 | //Configure::load('app_labinvent_mandatory_fields_IP2I', 'yaml'); |
117 | //Configure::load('app_labinvent_authorizations', 'yaml'); | 127 | //Configure::load('app_labinvent_authorizations', 'yaml'); |
118 | } catch (\Exception $e) { | 128 | } catch (\Exception $e) { |
119 | - die('config/bootstrap.php: Unable to load yaml config file'); | 129 | + echo("<br>config/bootstrap.php: Impossible de charger le fichier de configuration des champs matériels (".CONFIG.DS.CONFIG_MATERIEL_FIELDS_FILE_NAME.".yml)"); |
130 | + echo("<br>- soit ce fichier n'est pas accessible en lecture par le serveur web (attention, il faut aussi qu'il soit accessible en écriture)"); | ||
131 | + echo("<br>- soit il n'existe pas => dans ce cas, créez le en faisant une copie du fichier de configuration par défaut :"); | ||
132 | + echo("<br> cd ".CONFIG); | ||
133 | + echo("<br> cp $config_matos_full_file_name_default $config_matos_full_file_name"); | ||
134 | + echo("<br> chown webserver_user_name $config_matos_full_file_name"); | ||
135 | + echo("<br> chmod 600 $config_matos_full_file_name"); | ||
136 | + echo("<br> (si vous ne voulez pas faire le chown, faite plutot un chmod 666, moins propre, mais marche aussi)"); | ||
137 | + die(); | ||
120 | } | 138 | } |
121 | 139 | ||
122 | // Load an environment local configuration file. | 140 | // Load an environment local configuration file. |
@@ -0,0 +1,308 @@ | @@ -0,0 +1,308 @@ | ||
1 | +<?php | ||
2 | +namespace App\Controller; | ||
3 | + | ||
4 | +use App\Controller\AppController; | ||
5 | +use App\Form\ConfigurationFieldsForm; | ||
6 | +use Cake\Core\Configure; | ||
7 | + | ||
8 | +use Symfony\Component\Yaml\Yaml; | ||
9 | + | ||
10 | + | ||
11 | +// modelless form : voir https://book.cakephp.org/3/en/core-libraries/form.html | ||
12 | +class ConfigurationFieldsController extends AppController | ||
13 | +{ | ||
14 | + | ||
15 | + /* | ||
16 | + * @Override | ||
17 | + * | ||
18 | + * Initialisation des autorisations pour les actions spécifiques à ce controleur | ||
19 | + * | ||
20 | + */ | ||
21 | + protected function setAuthorizations() { | ||
22 | + | ||
23 | + // On supprime les autres actions par défaut (add, view, index, find) | ||
24 | + //foreach (array_keys($this->is_authorized_action[]) as $a) if ($a != 'display') unset($this->is_authorized_action[$a]); | ||
25 | + $this->is_authorized_action = []; | ||
26 | + | ||
27 | + // admin (+) only | ||
28 | + $this->setAuthorizationsForAction('index', -1, ['admin'=>0, 'super'=>0]); | ||
29 | + $this->setAuthorizationsForAction('view', -1, ['admin'=>0, 'super'=>0]); | ||
30 | + $this->setAuthorizationsForAction('edit', -1, ['admin'=>0, 'super'=>0]); | ||
31 | + $this->setAuthorizationsForAction('resetToDefault', -1, ['admin'=>0, 'super'=>0]); | ||
32 | + // tous | ||
33 | + //$this->setAuthorizationsForAction('index', 0); | ||
34 | + // Superadmin only : | ||
35 | + //$this->setAuthorizationsForAction('index', -1, ['super'=>0]); | ||
36 | + | ||
37 | + } | ||
38 | + | ||
39 | + public function index() { | ||
40 | + $this->view(); | ||
41 | + } | ||
42 | + | ||
43 | + public function view() { | ||
44 | + | ||
45 | + $this->edit(true); | ||
46 | + // Lecteurs configurés : 'default', 'yaml' | ||
47 | + //debug(Configure::configured()); | ||
48 | + | ||
49 | + //$fields = Configure::readOrFail('MANDATORY_FIELDS_FOR_LOT'.$lot_num); | ||
50 | + /* | ||
51 | + $fields = Configure::readOrFail('MANDATORY_AND_READONLY_FIELDS'); | ||
52 | + $this->set(compact('fields')); | ||
53 | + */ | ||
54 | + } | ||
55 | + | ||
56 | + public function resetToDefault() { | ||
57 | + $config_mandatory_fields_file_name = CONFIG.DS.CONFIG_MATERIEL_FIELDS_FILE_NAME.'.yml'; | ||
58 | + $config_mandatory_fields_file_name_default = CONFIG.DS.CONFIG_MATERIEL_FIELDS_FILE_NAME.'.default.yml'; | ||
59 | + | ||
60 | + $config_default = Yaml::parse(file_get_contents($config_mandatory_fields_file_name_default)); //parse le fichier | ||
61 | + $config_default_as_yaml = Yaml::dump($config_default); //remet en yaml | ||
62 | + if (! file_put_contents($config_mandatory_fields_file_name, $config_default_as_yaml) ) | ||
63 | + throw new \ErrorException("Impossible de remettre la configuration des champs de matériel aux valeurs par défaut - le fichier de config $config_mandatory_fields_file_name n'est pas accessible en écriture"); | ||
64 | + | ||
65 | + $this->Flash->success("La configuration des champs de matériel a bien été réinitialisée aux valeurs par défaut"); | ||
66 | + return $this->redirect(['action' => 'view']); | ||
67 | + } | ||
68 | + | ||
69 | + | ||
70 | + public function edit($READONLY=false) { | ||
71 | + | ||
72 | + $contact = new ConfigurationFieldsForm(); | ||
73 | + //debug($contact); | ||
74 | + | ||
75 | + // - En mode POST | ||
76 | + if ($this->request->is('post')) { | ||
77 | + /* | ||
78 | + * We use the execute() method to run our form’s _execute() method only when the data is valid, | ||
79 | + * and set flash messages accordingly. | ||
80 | + * We could have also used the validate() method to only validate the request data: | ||
81 | + * $isValid = $form->validate($this->request->getData()); | ||
82 | + */ | ||
83 | + //debug($this->request->getData()); | ||
84 | + | ||
85 | + // - OK | ||
86 | + if ($contact->execute($this->request->getData())) { | ||
87 | + $fieldsets = $this->request->getData(); | ||
88 | + //debug($data); | ||
89 | + $contact->setData($fieldsets); | ||
90 | + | ||
91 | + // On sauvegarde le contenu de $fieldsets dans le fichier de config (array => yaml) | ||
92 | + | ||
93 | + //debug($contact); | ||
94 | + // See : https://book.cakephp.org/3/en/development/configuration.html#writing-configuration-data | ||
95 | + /* | ||
96 | + Configure::write('Company.name','Pizza, Inc.'); | ||
97 | + Configure::write('Company.slogan','Pizza for your body and soul'); | ||
98 | + // idem : | ||
99 | + Configure::write('Company', [ | ||
100 | + 'name' => 'Pizza, Inc.', | ||
101 | + 'slogan' => 'Pizza for your body and soul' | ||
102 | + ]); | ||
103 | + */ | ||
104 | + //$data1 = Configure::read('MANDATORY_AND_READONLY_FIELDS'); | ||
105 | + //debug($data1); | ||
106 | + /* | ||
107 | + Configure::write('MANDATORY_AND_READONLY_FIELDS',$data); | ||
108 | + $data2 = Configure::read('MANDATORY_AND_READONLY_FIELDS'); | ||
109 | + */ | ||
110 | + //debug($data2); | ||
111 | + //$name = $contact->getData('name'); | ||
112 | + /* NE MARCHE PAS, WHY ??? | ||
113 | + $config_mandatory_fields_file_name = 'app_labinvent_mandatory_fields'; | ||
114 | + if ( Configure::dump($config_mandatory_fields_file_name, 'my_yaml', ['MANDATORY_AND_READONLY_FIELDS']) ) | ||
115 | + $this->Flash->success("La configuration des champs matériels a bien été sauvegardée"); | ||
116 | + */ | ||
117 | + //$config_mandatory_fields_file_name = CONFIG.DS.'app_labinvent_mandatory_fields'.'.yml'; | ||
118 | + $config_mandatory_fields_file_name = CONFIG.DS.CONFIG_MATERIEL_FIELDS_FILE_NAME.'.yml'; | ||
119 | + // Symfony YAML component : https://symfony.com/doc/current/components/yaml.html | ||
120 | + /* | ||
121 | + $array = Yaml::parse(file_get_contents($config_mandatory_fields_file_name)); //parse le fichier | ||
122 | + debug($array); | ||
123 | + $res = Yaml::dump($array); //remet en yaml | ||
124 | + */ | ||
125 | + $fieldsets_new = []; | ||
126 | + $fieldsets_new['MANDATORY_AND_READONLY_FIELDS']=$fieldsets; | ||
127 | + //debug($fieldsets_new); | ||
128 | + | ||
129 | + $fieldsets_as_yaml = Yaml::dump($fieldsets_new); //remet en yaml | ||
130 | + //debug($res); exit; | ||
131 | + if (! file_put_contents($config_mandatory_fields_file_name, $fieldsets_as_yaml) ) | ||
132 | + throw new \ErrorException("Impossible d'enregistrer la configuration des champs de matériel - le fichier de config $config_mandatory_fields_file_name n'est pas accessible en écriture"); | ||
133 | + $this->Flash->success("La configuration des champs de matériel a bien été sauvegardée"); | ||
134 | + return $this->redirect(['action' => 'view']); | ||
135 | + } | ||
136 | + | ||
137 | + // - KO | ||
138 | + else { | ||
139 | + // Once a form has been validated you can retrieve the errors from it: | ||
140 | + $errors = $form->getErrors(); // $form->errors(); // prior to 3.7.0 | ||
141 | + debug($errors); | ||
142 | + /* $errors contains | ||
143 | + [ | ||
144 | + 'email' => ['A valid email address is required'] | ||
145 | + ] | ||
146 | + */ | ||
147 | + $this->Flash->error("La configuration n'a pas pu être enregistrée"); | ||
148 | + } | ||
149 | + } | ||
150 | + | ||
151 | + // - En mode GET (ou POST avec erreur) | ||
152 | + | ||
153 | + if ($this->request->is('get')) { | ||
154 | + /* | ||
155 | + $contact->setData([ | ||
156 | + 'name' => 'John Doe', | ||
157 | + 'email' => 'john.doe@example.com' | ||
158 | + ]); | ||
159 | + */ | ||
160 | + } | ||
161 | + | ||
162 | + $this->set('contact', $contact); | ||
163 | + | ||
164 | + $fieldsets = Configure::readOrFail('MANDATORY_AND_READONLY_FIELDS'); | ||
165 | + $this->set(compact('READONLY', 'fieldsets')); | ||
166 | + | ||
167 | + } // edit() | ||
168 | + | ||
169 | + | ||
170 | + public function OLD_edit($READONLY=false) | ||
171 | + { | ||
172 | + $contact = new ConfigurationFieldsForm(); | ||
173 | + //debug($contact); | ||
174 | + | ||
175 | + // - En mode POST | ||
176 | + if ($this->request->is('post')) { | ||
177 | + /* | ||
178 | + * We use the execute() method to run our form’s _execute() method only when the data is valid, | ||
179 | + * and set flash messages accordingly. | ||
180 | + * We could have also used the validate() method to only validate the request data: | ||
181 | + * $isValid = $form->validate($this->request->getData()); | ||
182 | + */ | ||
183 | + //debug($this->request->getData()); | ||
184 | + | ||
185 | + // - OK | ||
186 | + if ($contact->execute($this->request->getData())) { | ||
187 | + $fieldsets = $this->request->getData(); | ||
188 | + //debug($data); | ||
189 | + $contact->setData($fieldsets); | ||
190 | + | ||
191 | + /* | ||
192 | + * 1) On retouche $fieldsets pour qu'il puisse être sauvegardé au format fichier texte (yaml) : | ||
193 | + * | ||
194 | + * Ex: | ||
195 | + 'designation' => [ | ||
196 | + 'selected' => '0', | ||
197 | + 'labl' => 'commentaire', | ||
198 | + 'roles' => [ | ||
199 | + (int) 0 => 'Responsable', | ||
200 | + (int) 1 => 'Administration' | ||
201 | + ] | ||
202 | + ], | ||
203 | + * | ||
204 | + * - '.selected' : si = 0 => on préfixe le nom du champ par "OFF_" | ||
205 | + * => 'OFF_designation' | ||
206 | + * - '.labl' : on l'ajoute entre parenthèse à la suite du nom du champ | ||
207 | + * => 'OFF_designation (commentaire)' | ||
208 | + * - '.roles' : on les ajoute entre parenthèse à la fin du nom du champ => | ||
209 | + * => 'OFF_designation (commentaire) (sauf Responsable, Administration)' | ||
210 | + */ | ||
211 | + $fieldsets_new = []; | ||
212 | + $fieldsets_new['MANDATORY_AND_READONLY_FIELDS']=[]; | ||
213 | + //$fn = &$fieldsets_new['MANDATORY_AND_READONLY_FIELDS']; | ||
214 | + foreach ($fieldsets as $fieldset_name=>$fields) { | ||
215 | + $fieldsets_new['MANDATORY_AND_READONLY_FIELDS'][$fieldset_name] = []; | ||
216 | + foreach ($fields as $field_name=>$attributes) { | ||
217 | + $field_name_new = $field_name; | ||
218 | + // - selected | ||
219 | + if (! $attributes['selected'] ) | ||
220 | + $field_name_new = 'OFF_'.$field_name_new; | ||
221 | + // - labl | ||
222 | + if ($attributes['labl']) | ||
223 | + $field_name_new .= ' ('. $attributes['labl'] .')'; | ||
224 | + // - roles | ||
225 | + if (isset($attributes['except_roles']) && $attributes['except_roles']) | ||
226 | + $field_name_new .= ' (sauf '. implode(',',$attributes['except_roles']) .')'; | ||
227 | + //debug($field_name_new); | ||
228 | + $fieldsets_new['MANDATORY_AND_READONLY_FIELDS'][$fieldset_name][] = $field_name_new; | ||
229 | + } | ||
230 | + } | ||
231 | + //debug($fieldsets_new); exit; | ||
232 | + | ||
233 | + // 2) On sauvegarde le contenu de $fieldsets dans le fichier de config (array => yaml) | ||
234 | + | ||
235 | + //debug($contact); | ||
236 | + // See : https://book.cakephp.org/3/en/development/configuration.html#writing-configuration-data | ||
237 | + /* | ||
238 | + Configure::write('Company.name','Pizza, Inc.'); | ||
239 | + Configure::write('Company.slogan','Pizza for your body and soul'); | ||
240 | + // idem : | ||
241 | + Configure::write('Company', [ | ||
242 | + 'name' => 'Pizza, Inc.', | ||
243 | + 'slogan' => 'Pizza for your body and soul' | ||
244 | + ]); | ||
245 | + */ | ||
246 | + //$data1 = Configure::read('MANDATORY_AND_READONLY_FIELDS'); | ||
247 | + //debug($data1); | ||
248 | + /* | ||
249 | + Configure::write('MANDATORY_AND_READONLY_FIELDS',$data); | ||
250 | + $data2 = Configure::read('MANDATORY_AND_READONLY_FIELDS'); | ||
251 | + */ | ||
252 | + //debug($data2); | ||
253 | + //$name = $contact->getData('name'); | ||
254 | + /* NE MARCHE PAS, WHY ??? | ||
255 | + $config_mandatory_fields_file_name = 'app_labinvent_mandatory_fields'; | ||
256 | + if ( Configure::dump($config_mandatory_fields_file_name, 'my_yaml', ['MANDATORY_AND_READONLY_FIELDS']) ) | ||
257 | + $this->Flash->success("La configuration des champs matériels a bien été sauvegardée"); | ||
258 | + */ | ||
259 | + //$config_mandatory_fields_file_name = CONFIG.DS.'app_labinvent_mandatory_fields'.'.yml'; | ||
260 | + $config_mandatory_fields_file_name = CONFIG.DS.CONFIG_MATERIEL_FIELDS_FILE_NAME.'.yml'; | ||
261 | + // Symfony YAML component : https://symfony.com/doc/current/components/yaml.html | ||
262 | + /* | ||
263 | + $array = Yaml::parse(file_get_contents($config_mandatory_fields_file_name)); //parse le fichier | ||
264 | + debug($array); | ||
265 | + $res = Yaml::dump($array); //remet en yaml | ||
266 | + */ | ||
267 | + $fieldsets_new_as_yaml = Yaml::dump($fieldsets_new); //remet en yaml | ||
268 | + //debug($res); exit; | ||
269 | + if ( file_put_contents($config_mandatory_fields_file_name, $fieldsets_new_as_yaml) ) | ||
270 | + $this->Flash->success("La configuration des champs matériels a bien été sauvegardée"); | ||
271 | + return $this->redirect(['action' => 'view']); | ||
272 | + } | ||
273 | + | ||
274 | + // - KO | ||
275 | + else { | ||
276 | + // Once a form has been validated you can retrieve the errors from it: | ||
277 | + $errors = $form->getErrors(); // $form->errors(); // prior to 3.7.0 | ||
278 | + debug($errors); | ||
279 | + /* $errors contains | ||
280 | + [ | ||
281 | + 'email' => ['A valid email address is required'] | ||
282 | + ] | ||
283 | + */ | ||
284 | + $this->Flash->error("La configuration n'a pas pu être enregistrée"); | ||
285 | + } | ||
286 | + } | ||
287 | + | ||
288 | + // - En mode GET (ou POST avec erreur) | ||
289 | + | ||
290 | + if ($this->request->is('get')) { | ||
291 | + /* | ||
292 | + $contact->setData([ | ||
293 | + 'name' => 'John Doe', | ||
294 | + 'email' => 'john.doe@example.com' | ||
295 | + ]); | ||
296 | + */ | ||
297 | + } | ||
298 | + | ||
299 | + $this->set('contact', $contact); | ||
300 | + | ||
301 | + $fieldsets = Configure::readOrFail('MANDATORY_AND_READONLY_FIELDS'); | ||
302 | + $this->set(compact('READONLY', 'fieldsets')); | ||
303 | + | ||
304 | + } // edit() | ||
305 | + | ||
306 | + | ||
307 | + | ||
308 | +} // end of class | ||
0 | \ No newline at end of file | 309 | \ No newline at end of file |
src/Controller/MaterielsController.php
@@ -1913,8 +1913,40 @@ class MaterielsController extends AppController { | @@ -1913,8 +1913,40 @@ class MaterielsController extends AppController { | ||
1913 | } | 1913 | } |
1914 | */ | 1914 | */ |
1915 | $recommended_fields = $this->Materiels->getRecommendedFieldsForMaterielStatus($materiel->status); | 1915 | $recommended_fields = $this->Materiels->getRecommendedFieldsForMaterielStatus($materiel->status); |
1916 | - foreach ($recommended_fields as $fname => $msg) { | ||
1917 | - | 1916 | + //debug($recommended_fields); |
1917 | + /* | ||
1918 | + * Ex : | ||
1919 | + [ | ||
1920 | + 'etiquette' => [ | ||
1921 | + 'selected' => '1', | ||
1922 | + 'comment' => 'd'imprimer l'étiquette associée et de la coller sur le matériel', | ||
1923 | + 'roles' => '' | ||
1924 | + ], | ||
1925 | + 'numero_inventaire_organisme' => [ | ||
1926 | + 'selected' => '1', | ||
1927 | + 'comment' => 'de renseigner le champ 'N° inventaire comptable/tutelles _Organisme_'', | ||
1928 | + 'roles' => '' | ||
1929 | + ], | ||
1930 | + 'DOC_BC' => [ | ||
1931 | + 'selected' => '1', | ||
1932 | + 'comment' => 'd'ajouter le Bon de Commande', | ||
1933 | + 'roles' => '' | ||
1934 | + ], | ||
1935 | + 'DOC_BL' => [ | ||
1936 | + 'selected' => '1', | ||
1937 | + 'comment' => 'd'ajouter le Bon de Livraison', | ||
1938 | + 'roles' => '' | ||
1939 | + ], | ||
1940 | + 'DOC_FACTURE' => [ | ||
1941 | + 'selected' => '1', | ||
1942 | + 'comment' => 'd'ajouter la Facture', | ||
1943 | + 'roles' => '' | ||
1944 | + ] | ||
1945 | + */ | ||
1946 | + //foreach ($recommended_fields as $fname => $msg) { | ||
1947 | + //foreach ($recommended_fields as $fname => $attributes) { | ||
1948 | + foreach ( array_keys($recommended_fields) as $fname ) { | ||
1949 | + | ||
1918 | //debug($fname); | 1950 | //debug($fname); |
1919 | // - Documents attachés (champs virtuels) | 1951 | // - Documents attachés (champs virtuels) |
1920 | // DOC_DEVIS, DOC_BC, ... | 1952 | // DOC_DEVIS, DOC_BC, ... |
@@ -1937,8 +1969,8 @@ class MaterielsController extends AppController { | @@ -1937,8 +1969,8 @@ class MaterielsController extends AppController { | ||
1937 | 1969 | ||
1938 | } | 1970 | } |
1939 | // Les champs restants sont les champs manquants => message flash de rappel | 1971 | // Les champs restants sont les champs manquants => message flash de rappel |
1940 | - foreach ($recommended_fields as $fname => $reminder_msg) | ||
1941 | - $this->Flash->set("Ce matériel est '".$entity->getNiceStatus()."' mais n'oubliez pas $reminder_msg"); | 1972 | + foreach ($recommended_fields as $fname => $attributes) |
1973 | + $this->Flash->set("Ce matériel est '".$entity->getNiceStatus()."' mais n'oubliez pas ".$attributes['comment']); | ||
1942 | 1974 | ||
1943 | 1975 | ||
1944 | } // view | 1976 | } // view |
@@ -1974,7 +2006,6 @@ class MaterielsController extends AppController { | @@ -1974,7 +2006,6 @@ class MaterielsController extends AppController { | ||
1974 | // uniquement à cause de parent::add_or_edit() : | 2006 | // uniquement à cause de parent::add_or_edit() : |
1975 | $entity_name=null, array $associated_entities=[], $with_parent=false) { | 2007 | $entity_name=null, array $associated_entities=[], $with_parent=false) { |
1976 | 2008 | ||
1977 | - //debug("ici"); exit; | ||
1978 | $this->myDebug("step 3: MaterielsController.add_or_edit()"); | 2009 | $this->myDebug("step 3: MaterielsController.add_or_edit()"); |
1979 | $IS_EDIT = !$IS_ADD; | 2010 | $IS_EDIT = !$IS_ADD; |
1980 | 2011 | ||
@@ -2080,72 +2111,11 @@ class MaterielsController extends AppController { | @@ -2080,72 +2111,11 @@ class MaterielsController extends AppController { | ||
2080 | $materiel->numero_laboratoire = null; | 2111 | $materiel->numero_laboratoire = null; |
2081 | } | 2112 | } |
2082 | } | 2113 | } |
2083 | - //debug($materiel); exit; | ||
2084 | - /* | ||
2085 | - // ADD | ||
2086 | - if ($IS_ADD) { | ||
2087 | - // 1) on crée un materiel vide | ||
2088 | - $materiel = $this->Materiels->newEntity(); | ||
2089 | - // - add_by_copy : COPIE de materiel (on a cliqué sur "Copier ce materiel") => id passé en argument | ||
2090 | - if (isset($this->request->getAttribute('params')['pass'][0])) { | ||
2091 | - // On récupère le materiel à copier et on le copie dans $materiel | ||
2092 | - /S | ||
2093 | - $materiel_to_copy = $this->Materiels->get($this->request->getAttribute('params')['pass'][0]); | ||
2094 | - $materiel_to_copy = $materiel_to_copy->toArray(); | ||
2095 | - S/ | ||
2096 | - $materiel_to_copy = $this->e->toArray(); | ||
2097 | - //var_dump($materiel_to_copy); | ||
2098 | - ///foreach ($materiel_to_copy as $key=>$value) $materiel->$key = $value; | ||
2099 | - // IMPORTANT: validate=False car sinon, les données sont validées avant la copie, | ||
2100 | - // et le numero_laboratoire est vu comme invalide car déjà utilisé et doit etre unique !!! | ||
2101 | - // et on a pour résultat : "le matériel n'a pas pu être ajouté" (sans savoir pourquoi !!!) | ||
2102 | - $materiel = $this->Materiels->patchEntity($materiel, $materiel_to_copy, ['validate' => false]); | ||
2103 | - //TODO: On pourrait traiter les erreurs de validation déjà ici | ||
2104 | - if ($materiel->errors()) { | ||
2105 | - // traitement | ||
2106 | - } | ||
2107 | - // Du coup, on supprime le champ numero_laboratoire car il va être généré automatiquement | ||
2108 | - unset($materiel->numero_laboratoire); | ||
2109 | - // IMPORTANT: on ne doit pas laisser l'id égal à celui du matériel copié !!! il en faut un nouveau | ||
2110 | - $materiel->id = NULL; | ||
2111 | - //$materiel->id = False; | ||
2112 | - //unset($materiel->id); | ||
2113 | - | ||
2114 | - /S | ||
2115 | - $attribute="[original]"; | ||
2116 | - $materiel->$attribute = []; | ||
2117 | - S/ | ||
2118 | - //$materiel->id = FALSE; | ||
2119 | - //$materiel->'[new]' => true, | ||
2120 | - } | ||
2121 | - // - NOUVEAU materiel (on a cliqué sur "Nouveau materiel") | ||
2122 | - else { | ||
2123 | - //$materiel = $this->Materiels->newEntity(); | ||
2124 | - /S (EP 20200505 plus nécessaire car on utilise désormais NULL) | ||
2125 | - // Set default values : "N/A" | ||
2126 | - $materiel->groupes_thematique_id = 1; | ||
2127 | - $materiel->groupes_metier_id = 1; | ||
2128 | - $materiel->site_id = 9; | ||
2129 | - S/ | ||
2130 | - } | ||
2131 | - } | ||
2132 | - // EDIT | ||
2133 | - else { | ||
2134 | - /S | ||
2135 | - $this->log("Edit a doc1 !", 'debug'); | ||
2136 | - Log::write('debug',"Edit a doc2 !"); | ||
2137 | - $this->dlog("Edit a doc1 !"); | ||
2138 | - S/ | ||
2139 | - $materiel = $this->Materiels->get($id, [ | ||
2140 | - 'contain' => [] // load associated entities | ||
2141 | - ]); | ||
2142 | - //$this->myDebug($materiel); | ||
2143 | - //debug($materiel); | ||
2144 | - } | ||
2145 | - */ | ||
2146 | 2114 | ||
2147 | 2115 | ||
2148 | - /* SI POST... | 2116 | + /* |
2117 | + * SI POST... | ||
2118 | + * | ||
2149 | * Les données ont été saisies et postées | 2119 | * Les données ont été saisies et postées |
2150 | * On va donc les sauvegarder (si ok) | 2120 | * On va donc les sauvegarder (si ok) |
2151 | */ | 2121 | */ |
@@ -2154,123 +2124,32 @@ class MaterielsController extends AppController { | @@ -2154,123 +2124,32 @@ class MaterielsController extends AppController { | ||
2154 | $authorized_actions = $IS_ADD ? ['post'] : ['post','patch','put']; | 2124 | $authorized_actions = $IS_ADD ? ['post'] : ['post','patch','put']; |
2155 | if ( $this->request->is($authorized_actions) ) { | 2125 | if ( $this->request->is($authorized_actions) ) { |
2156 | 2126 | ||
2157 | - //debug($this->request->getData()); | ||
2158 | - //exit; | ||
2159 | - | ||
2160 | - /* | ||
2161 | - // ADD | ||
2162 | - // Nouveau materiel saisi et posted | ||
2163 | - ($is_add && $this->request->is('post')) | ||
2164 | - | ||
2165 | - || | ||
2166 | - | ||
2167 | - // EDIT | ||
2168 | - // materiel modifié et posted | ||
2169 | - ( (!$is_add) && $this->request->is(['patch','post','put']) ) | ||
2170 | - */ | 2127 | + //debug($this->request->getData()); exit; |
2171 | 2128 | ||
2172 | // (1) On remplit $materiel avec les données de ce materiel | 2129 | // (1) On remplit $materiel avec les données de ce materiel |
2173 | $materiel = $this->Materiels->patchEntity($materiel, $this->request->getData()); | 2130 | $materiel = $this->Materiels->patchEntity($materiel, $this->request->getData()); |
2174 | - | ||
2175 | - /* | ||
2176 | - // AVIRER | ||
2177 | - // BUGFIX temporaire pour php5 !!! | ||
2178 | - if ($this->isLabinventDebugMode()) { | ||
2179 | - $d2 = $materiel->date_reception; | ||
2180 | - $d1 = $materiel->date_acquisition; | ||
2181 | - debug("d1 achat avant:"); debug($d1); | ||
2182 | - debug("d2 recep avant:"); debug($d2); | ||
2183 | - /S | ||
2184 | - $tz = new \DateTimeZone('Europe/Paris'); | ||
2185 | - $d1 = new \DateTime(strtr($d1,'/','-'),$tz); | ||
2186 | - $d2 = new \DateTime(strtr($d2,'/','-'),$tz); | ||
2187 | - debug("d1 achat après:"); debug($d1); | ||
2188 | - debug("d2 recep après:"); debug($d2); | ||
2189 | - S/ | ||
2190 | - if ($d2 < $d1) debug("d2 < d1 !!!"); | ||
2191 | - // $d2 > $d1 oui mais pas trop... | ||
2192 | - $diff = $d2->diff($d1); | ||
2193 | - //debug($diff->y); | ||
2194 | - debug("diff:"); debug($diff); | ||
2195 | - debug("diff->y:"); debug($diff->y); | ||
2196 | - debug("diff->days:"); debug($diff->days); | ||
2197 | - exit; | ||
2198 | - } | ||
2199 | - // FIN BUGFIX | ||
2200 | - */ | ||
2201 | - | ||
2202 | - // ADD : Set the user_id from the session. | ||
2203 | - //$materiel->user_id = $this->Auth->user('id'); | ||
2204 | - // EDIT : Added: Disable modification of user_id. | ||
2205 | - //'accessibleFields' => ['user_id' => false] | ||
2206 | - | ||
2207 | - /* (EP 7/12/20 : déjà fait dans la vue, donc inutile !!!) | ||
2208 | - // (2) Si l'utilisateur courant est un "administratif" => le mettre comme gestionnaire du materiel | ||
2209 | - // (tout ça pour ça !!! Faudra réduire ce bazar !) | ||
2210 | - $current_user_name = $_SESSION['Auth']['User']['sn'][0]; | ||
2211 | - if (in_array( | ||
2212 | - $current_user_name, | ||
2213 | - $usersTable | ||
2214 | - ->find('list', [ | ||
2215 | - 'keyField' => 'id', | ||
2216 | - 'valueField' => 'nom' | ||
2217 | - ]) | ||
2218 | - ->where([ | ||
2219 | - 'role =' => 'Administration' | ||
2220 | - ]) | ||
2221 | - ->toArray() | ||
2222 | - )) { | ||
2223 | - $materiel->gestionnaire_id = $usersTable | ||
2224 | - ->find() | ||
2225 | - ->where([ | ||
2226 | - 'nom' => $current_user_name | ||
2227 | - ]) | ||
2228 | - ->first()->id; | ||
2229 | - } | ||
2230 | - */ | ||
2231 | - | ||
2232 | - | 2131 | + //debug($materiel); |
2132 | + | ||
2233 | /* | 2133 | /* |
2234 | * \AV1 : Attributs OBLIGATOIRES | 2134 | * \AV1 : Attributs OBLIGATOIRES |
2235 | * On définit les infos obligatoires et on vérifie qu'elles sont bien présentes dans le POST | 2135 | * On définit les infos obligatoires et on vérifie qu'elles sont bien présentes dans le POST |
2236 | */ | 2136 | */ |
2237 | 2137 | ||
2238 | - /* | ||
2239 | - // Attributs obligatoires pour la phase COMMANDE | ||
2240 | - //$LOT1 = $this->Materiels->MANDATORY_FIELDS_FOR_LOT1; | ||
2241 | - $LOT1 = $this->Materiels->getMandatoryFieldsForLot(1); | ||
2242 | - | ||
2243 | - // Attributs obligatoires pour la phase VALIDATION (livré et payé) | ||
2244 | - //$LOT2 = $this->Materiels->MANDATORY_FIELDS_FOR_LOT2; | ||
2245 | - $LOT2 = $this->Materiels->getMandatoryFieldsForLot(2); | ||
2246 | - | ||
2247 | - //TODO 202109 | ||
2248 | - // Seulement si prix > 10K€ : exiger la facture jointe et le n° série | ||
2249 | - if ($materiel->prix_ht > 10000) { | ||
2250 | - //$LOT2[] = 'facture jointe'; | ||
2251 | - $LOT2['numero_serie'] = 'S/N'; | ||
2252 | - } | ||
2253 | - // LOT2 = LOT1 + LOT2; | ||
2254 | - ////$LOT2 = array_merge($LOT1, $LOT2); | ||
2255 | - //debug($LOT2);exit; | ||
2256 | - // Champs obligatoires = LOT1 si CREATED, LOT2 sinon (>CREATED, c'est à dire VALIDATED ou plus) | ||
2257 | - $mandatory_fields = ($materiel->status == 'CREATED') ? $LOT1 : $LOT2; | ||
2258 | - //debug($mandatory_fields); exit; | ||
2259 | - */ | ||
2260 | //$mandatory_fields = MaterielsTable::getMandatoryFieldsForMaterielStatus($materiel->status); | 2138 | //$mandatory_fields = MaterielsTable::getMandatoryFieldsForMaterielStatus($materiel->status); |
2261 | $mandatory_fields = $this->Materiels->getMandatoryFieldsForMateriel($materiel); | 2139 | $mandatory_fields = $this->Materiels->getMandatoryFieldsForMateriel($materiel); |
2140 | + //debug($mandatory_fields); | ||
2262 | //$mandatory_fields = $this->Materiels->getMandatoryFieldsForMaterielStatus($materiel->status); | 2141 | //$mandatory_fields = $this->Materiels->getMandatoryFieldsForMaterielStatus($materiel->status); |
2263 | - //debug($mandatory_fields); exit; | ||
2264 | 2142 | ||
2265 | $verb = $IS_ADD ? "ajouté" : "modifié"; | 2143 | $verb = $IS_ADD ? "ajouté" : "modifié"; |
2266 | 2144 | ||
2267 | // On vérifie que les infos obligatoires sont présentes | 2145 | // On vérifie que les infos obligatoires sont présentes |
2268 | // Si au moins un champ obligatoire est nul ou vide => ERROR | 2146 | // Si au moins un champ obligatoire est nul ou vide => ERROR |
2269 | - $ALL_MANDATORY_FIELDS_FOR_GIVEN = true; | 2147 | + $ALL_MANDATORY_FIELDS_GIVEN = true; |
2270 | //foreach ($mandatory_fields as $fname => $fval) { | 2148 | //foreach ($mandatory_fields as $fname => $fval) { |
2271 | //print_r($materiel); | 2149 | //print_r($materiel); |
2272 | - foreach ($mandatory_fields as $fname=>$fname_nice) { | ||
2273 | - | 2150 | + //foreach ($mandatory_fields as $fname=>$fname_nice) { |
2151 | + foreach ($mandatory_fields as $fname=>$attributes) { | ||
2152 | + | ||
2274 | /* | 2153 | /* |
2275 | * Champs obligatoires à ignorer : | 2154 | * Champs obligatoires à ignorer : |
2276 | * - champs virtuels (n'existent pas physiquement) => DOC_XXX (DOC_DEVIS, DOC_BC, ...) | 2155 | * - champs virtuels (n'existent pas physiquement) => DOC_XXX (DOC_DEVIS, DOC_BC, ...) |
@@ -2282,7 +2161,7 @@ class MaterielsController extends AppController { | @@ -2282,7 +2161,7 @@ class MaterielsController extends AppController { | ||
2282 | //if ( in_array($fname, ['DOC_DEVIS', 'fournisseur_id', 'etiquette', 'numero_inventaire_organisme']) ) continue; | 2161 | //if ( in_array($fname, ['DOC_DEVIS', 'fournisseur_id', 'etiquette', 'numero_inventaire_organisme']) ) continue; |
2283 | 2162 | ||
2284 | if ($materiel->$fname === null || $materiel->$fname == '') { | 2163 | if ($materiel->$fname === null || $materiel->$fname == '') { |
2285 | - $ALL_MANDATORY_FIELDS_FOR_GIVEN = false; | 2164 | + $ALL_MANDATORY_FIELDS_GIVEN = false; |
2286 | /* (EP 2020 03) | 2165 | /* (EP 2020 03) |
2287 | * Ce genre de ligne ($this->Flash->...) affichant un message flash en haut de page, | 2166 | * Ce genre de ligne ($this->Flash->...) affichant un message flash en haut de page, |
2288 | * ne fonctionnait plus à cause de bootstrap (css). | 2167 | * ne fonctionnait plus à cause de bootstrap (css). |
@@ -2292,7 +2171,8 @@ class MaterielsController extends AppController { | @@ -2292,7 +2171,8 @@ class MaterielsController extends AppController { | ||
2292 | * de bootstrap, ou bootsrap-ui, ou cakephp..., à surveiller donc) | 2171 | * de bootstrap, ou bootsrap-ui, ou cakephp..., à surveiller donc) |
2293 | */ | 2172 | */ |
2294 | //$msgError1 = "Le champ suivant est obligatoire : ".$fname_nice.' du matériel'; | 2173 | //$msgError1 = "Le champ suivant est obligatoire : ".$fname_nice.' du matériel'; |
2295 | - $error_msg = "Le champ suivant est obligatoire : ".$fname_nice; | 2174 | + //$error_msg = "Le champ suivant est obligatoire : ".$fname_nice; |
2175 | + $error_msg = "Le champ suivant est obligatoire : ".$attributes['comment']; | ||
2296 | /////debug($msgError1); | 2176 | /////debug($msgError1); |
2297 | $this->Flash->error($error_msg); | 2177 | $this->Flash->error($error_msg); |
2298 | /* MARCHE PAS POURQUOI ? | 2178 | /* MARCHE PAS POURQUOI ? |
@@ -2307,10 +2187,11 @@ class MaterielsController extends AppController { | @@ -2307,10 +2187,11 @@ class MaterielsController extends AppController { | ||
2307 | ///////////////$this->Flash->error(__("Le matériel n'a pas pu être $verb")); | 2187 | ///////////////$this->Flash->error(__("Le matériel n'a pas pu être $verb")); |
2308 | //return false; | 2188 | //return false; |
2309 | break; | 2189 | break; |
2310 | - } | ||
2311 | - } | 2190 | + } // si champ obligatoire pas rempli |
2191 | + | ||
2192 | + } // foreach $mandatory_fields | ||
2312 | 2193 | ||
2313 | - if ($ALL_MANDATORY_FIELDS_FOR_GIVEN) { | 2194 | + if ($ALL_MANDATORY_FIELDS_GIVEN) { |
2314 | 2195 | ||
2315 | // (3) On l'ajoute en BD, on envoie un email, et on affiche ok sur page accueil | 2196 | // (3) On l'ajoute en BD, on envoie un email, et on affiche ok sur page accueil |
2316 | //$verb = $IS_ADD ? "ajouté" : "modifié"; | 2197 | //$verb = $IS_ADD ? "ajouté" : "modifié"; |
@@ -2342,7 +2223,8 @@ class MaterielsController extends AppController { | @@ -2342,7 +2223,8 @@ class MaterielsController extends AppController { | ||
2342 | foreach ($materiel->getErrors() as $f=>$e) | 2223 | foreach ($materiel->getErrors() as $f=>$e) |
2343 | foreach($e as $k=>$v) $this->Flash->error(__($v.' : '.$f)); | 2224 | foreach($e as $k=>$v) $this->Flash->error(__($v.' : '.$f)); |
2344 | 2225 | ||
2345 | - } | 2226 | + } // save KO |
2227 | + | ||
2346 | else { | 2228 | else { |
2347 | //debug($this->getCurrentEntity()); exit; | 2229 | //debug($this->getCurrentEntity()); exit; |
2348 | //debug($this->Materiels->current_entity); exit; | 2230 | //debug($this->Materiels->current_entity); exit; |
@@ -2380,7 +2262,7 @@ class MaterielsController extends AppController { | @@ -2380,7 +2262,7 @@ class MaterielsController extends AppController { | ||
2380 | 'action' => 'view', | 2262 | 'action' => 'view', |
2381 | $id | 2263 | $id |
2382 | ]); | 2264 | ]); |
2383 | - } | 2265 | + } // save KO |
2384 | 2266 | ||
2385 | } // $ALL_MANDATORY_FIELDS_FOR_GIVEN | 2267 | } // $ALL_MANDATORY_FIELDS_FOR_GIVEN |
2386 | 2268 | ||
@@ -2388,11 +2270,12 @@ class MaterielsController extends AppController { | @@ -2388,11 +2270,12 @@ class MaterielsController extends AppController { | ||
2388 | 2270 | ||
2389 | 2271 | ||
2390 | 2272 | ||
2391 | - | ||
2392 | - /* SINON (PAS POST) | 2273 | + /* SINON (GET, PAS POST) |
2393 | * C'est la première fois qu'on vient sur cette vue, | 2274 | * C'est la première fois qu'on vient sur cette vue, |
2394 | * donc on va préparer le formulaire de saisie) | 2275 | * donc on va préparer le formulaire de saisie) |
2395 | */ | 2276 | */ |
2277 | + //debug($materiel); exit; | ||
2278 | + | ||
2396 | 2279 | ||
2397 | 2280 | ||
2398 | /* | 2281 | /* |
@@ -2709,6 +2592,7 @@ class MaterielsController extends AppController { | @@ -2709,6 +2592,7 @@ class MaterielsController extends AppController { | ||
2709 | 'ARCHIVED' => 'ARCHIVED' | 2592 | 'ARCHIVED' => 'ARCHIVED' |
2710 | ]; | 2593 | ]; |
2711 | $entity = $materiel; | 2594 | $entity = $materiel; |
2595 | + //debug($entity); | ||
2712 | $this->set(compact( | 2596 | $this->set(compact( |
2713 | 'IS_ADD', | 2597 | 'IS_ADD', |
2714 | 'mail_responsable', | 2598 | 'mail_responsable', |
@@ -2738,8 +2622,10 @@ class MaterielsController extends AppController { | @@ -2738,8 +2622,10 @@ class MaterielsController extends AppController { | ||
2738 | 'gestionnaires' | 2622 | 'gestionnaires' |
2739 | )); | 2623 | )); |
2740 | 2624 | ||
2741 | - | ||
2742 | - $this->set('readonlyFields', $this->getUneditableFieldsForMaterielStatus($materiel->status)); | 2625 | + $readonlyFields = $this->getUneditableFieldsForMaterielStatus($materiel->status); |
2626 | + $this->set(compact('readonlyFields')); | ||
2627 | + //debug($materiel->status); | ||
2628 | + //debug($readonlyFields); | ||
2743 | //$this->set('readonlyFields', $IS_ADD ? [] : $this->getUneditableFieldsForMaterielStatus($materiel->status)); | 2629 | //$this->set('readonlyFields', $IS_ADD ? [] : $this->getUneditableFieldsForMaterielStatus($materiel->status)); |
2744 | //debug($this->Materiels->getUneditableFieldsForMaterielStatus($status)); exit; | 2630 | //debug($this->Materiels->getUneditableFieldsForMaterielStatus($status)); exit; |
2745 | //$this->set('readonlyFields', $IS_ADD ? [] : $this->Materiels->getUneditableFieldsForMaterielStatus($materiel->status)); | 2631 | //$this->set('readonlyFields', $IS_ADD ? [] : $this->Materiels->getUneditableFieldsForMaterielStatus($materiel->status)); |
@@ -2767,11 +2653,12 @@ class MaterielsController extends AppController { | @@ -2767,11 +2653,12 @@ class MaterielsController extends AppController { | ||
2767 | if ($this->USER_IS_SUPERADMIN()) return []; | 2653 | if ($this->USER_IS_SUPERADMIN()) return []; |
2768 | 2654 | ||
2769 | $uneditable_fields = $this->Materiels->getUneditableFieldsForMaterielStatus($materiel_status); | 2655 | $uneditable_fields = $this->Materiels->getUneditableFieldsForMaterielStatus($materiel_status); |
2770 | - foreach ($uneditable_fields as $fname=>$except_list) { | 2656 | + //foreach ($uneditable_fields as $fname=>$except_list) { |
2657 | + foreach ($uneditable_fields as $fname=>$attributes) { | ||
2771 | // S'il y a une exception, voir si elle concerne le USER courant, sinon supprimer ce champ $fname | 2658 | // S'il y a une exception, voir si elle concerne le USER courant, sinon supprimer ce champ $fname |
2772 | - if ($except_list) { | 2659 | + if ($attributes['except_roles']) { |
2773 | //debug($except_list); | 2660 | //debug($except_list); |
2774 | - if ($this->currentUserRoleInList($except_list)) unset($uneditable_fields[$fname]); | 2661 | + if ($this->currentUserRoleInList($attributes['except_roles'])) unset($uneditable_fields[$fname]); |
2775 | //debug("remove $fname"); | 2662 | //debug("remove $fname"); |
2776 | } | 2663 | } |
2777 | } | 2664 | } |
@@ -3051,10 +2938,11 @@ class MaterielsController extends AppController { | @@ -3051,10 +2938,11 @@ class MaterielsController extends AppController { | ||
3051 | 2938 | ||
3052 | // Attributs obligatoires pour la phase COMMANDE (LOT1) | 2939 | // Attributs obligatoires pour la phase COMMANDE (LOT1) |
3053 | $mandatoryFields = $this->Materiels->getMandatoryFieldsForLot(1); | 2940 | $mandatoryFields = $this->Materiels->getMandatoryFieldsForLot(1); |
2941 | + //debug($mandatoryFields); | ||
3054 | $ACTION = 'ordonner la commande de'; | 2942 | $ACTION = 'ordonner la commande de'; |
3055 | 2943 | ||
3056 | // Si au moins un champ obligatoire est nul ou vide => ERROR | 2944 | // Si au moins un champ obligatoire est nul ou vide => ERROR |
3057 | - foreach ($mandatoryFields as $fname => $fnicename) { | 2945 | + foreach ($mandatoryFields as $fname => $attributes) { |
3058 | 2946 | ||
3059 | // Doc attaché obligatoire ? (champ virtuel) | 2947 | // Doc attaché obligatoire ? (champ virtuel) |
3060 | //if (strtoupper($fname) == 'DOC_DEVIS') { | 2948 | //if (strtoupper($fname) == 'DOC_DEVIS') { |
@@ -3085,7 +2973,7 @@ class MaterielsController extends AppController { | @@ -3085,7 +2973,7 @@ class MaterielsController extends AppController { | ||
3085 | $fval = $materiel->$fname; | 2973 | $fval = $materiel->$fname; |
3086 | if ($fval === null || $fval == '') { | 2974 | if ($fval === null || $fval == '') { |
3087 | //$msgError1 = "Pour $ACTION ce matériel, le champ suivant ne doit pas être vide : ".$fnicename.' du matériel'; | 2975 | //$msgError1 = "Pour $ACTION ce matériel, le champ suivant ne doit pas être vide : ".$fnicename.' du matériel'; |
3088 | - $error_msg = sprintf($ERROR_MSG_EMPTY_FIELD, $ACTION, $fnicename); | 2976 | + $error_msg = sprintf($ERROR_MSG_EMPTY_FIELD, $ACTION, $attributes['comment']); |
3089 | $this->Flash->error($error_msg); | 2977 | $this->Flash->error($error_msg); |
3090 | // Utile ??? (plante les tests) | 2978 | // Utile ??? (plante les tests) |
3091 | ////$this->e->setError($fname, 'Ce champ ne doit pas être vide'); | 2979 | ////$this->e->setError($fname, 'Ce champ ne doit pas être vide'); |
@@ -3108,6 +2996,7 @@ class MaterielsController extends AppController { | @@ -3108,6 +2996,7 @@ class MaterielsController extends AppController { | ||
3108 | if ($newStatus == 'VALIDATED') { | 2996 | if ($newStatus == 'VALIDATED') { |
3109 | // Attributs obligatoires pour la phase VALIDATION (livré et payé) (LOT2) | 2997 | // Attributs obligatoires pour la phase VALIDATION (livré et payé) (LOT2) |
3110 | $mandatoryFields = $this->Materiels->getMandatoryFieldsForLot(2); | 2998 | $mandatoryFields = $this->Materiels->getMandatoryFieldsForLot(2); |
2999 | + //$mandatoryFields = $this->Materiels->getCategoryFieldsForLot('MANDATORY_FIELDS_FOR_LOT', 2) | ||
3111 | //$mandatoryFields = $this->Materiels->MANDATORY_FIELDS_FOR_LOT2; | 3000 | //$mandatoryFields = $this->Materiels->MANDATORY_FIELDS_FOR_LOT2; |
3112 | //debug($mandatoryFields);exit; | 3001 | //debug($mandatoryFields);exit; |
3113 | /* | 3002 | /* |
@@ -3142,7 +3031,7 @@ class MaterielsController extends AppController { | @@ -3142,7 +3031,7 @@ class MaterielsController extends AppController { | ||
3142 | */ | 3031 | */ |
3143 | 3032 | ||
3144 | // Si au moins un champ obligatoire est nul ou vide => ERROR | 3033 | // Si au moins un champ obligatoire est nul ou vide => ERROR |
3145 | - foreach ($mandatoryFields as $fname => $fnicename) { | 3034 | + foreach ($mandatoryFields as $fname => $attributes) { |
3146 | 3035 | ||
3147 | $ACTION = 'valider'; | 3036 | $ACTION = 'valider'; |
3148 | 3037 | ||
@@ -3184,7 +3073,8 @@ class MaterielsController extends AppController { | @@ -3184,7 +3073,8 @@ class MaterielsController extends AppController { | ||
3184 | * de bootstrap, ou bootsrap-ui, ou cakephp..., à surveiller donc) | 3073 | * de bootstrap, ou bootsrap-ui, ou cakephp..., à surveiller donc) |
3185 | */ | 3074 | */ |
3186 | //$msgError1 = "Pour $ACTION ce matériel, le champ suivant ne doit pas être vide : ".$fnicename.' du matériel'; | 3075 | //$msgError1 = "Pour $ACTION ce matériel, le champ suivant ne doit pas être vide : ".$fnicename.' du matériel'; |
3187 | - $error_msg = sprintf($ERROR_MSG_EMPTY_FIELD, $ACTION, $fnicename); | 3076 | + //debug($fname); |
3077 | + $error_msg = sprintf($ERROR_MSG_EMPTY_FIELD, $ACTION, $attributes['comment']); | ||
3188 | $this->Flash->error($error_msg); | 3078 | $this->Flash->error($error_msg); |
3189 | //debug($error_msg); | 3079 | //debug($error_msg); |
3190 | 3080 |
src/Controller/PagesController.php
@@ -70,6 +70,7 @@ class PagesController extends AppController | @@ -70,6 +70,7 @@ class PagesController extends AppController | ||
70 | { | 70 | { |
71 | $this->myDebug("step 0A (specific): PagesController.initialize()"); | 71 | $this->myDebug("step 0A (specific): PagesController.initialize()"); |
72 | parent::initialize(); | 72 | parent::initialize(); |
73 | + $this->modelClass = false; | ||
73 | // On autorise l'action add SANS authentification (unauthenticated) | 74 | // On autorise l'action add SANS authentification (unauthenticated) |
74 | //$this->Auth->allow(['add']); | 75 | //$this->Auth->allow(['add']); |
75 | //$this->LdapAuth->allow(['display']); | 76 | //$this->LdapAuth->allow(['display']); |
src/Controller/StatsController.php
@@ -61,7 +61,7 @@ class StatsController extends AppController | @@ -61,7 +61,7 @@ class StatsController extends AppController | ||
61 | 'nice_name'=>"Temps connexion cumulé (h)", 'f'=>'getHourMnSecForDuration'], | 61 | 'nice_name'=>"Temps connexion cumulé (h)", 'f'=>'getHourMnSecForDuration'], |
62 | 'connex_nb'=>['nice_name'=>"Nb connexions"], | 62 | 'connex_nb'=>['nice_name'=>"Nb connexions"], |
63 | 'connexDurAvg'=>[ | 63 | 'connexDurAvg'=>[ |
64 | - 'nice_name'=>"Durée connexion moyenne (sur année)", 'f'=>'getHourMnSecForDuration'] | 64 | + 'nice_name'=>"Durée connexion moyenne (sur 1 an)", 'f'=>'getHourMnSecForDuration'] |
65 | ], | 65 | ], |
66 | ['Users'], | 66 | ['Users'], |
67 | false, false, | 67 | false, false, |
src/Controller/SurCategoriesController.php
@@ -256,6 +256,8 @@ class SurCategoriesController extends AppController | @@ -256,6 +256,8 @@ class SurCategoriesController extends AppController | ||
256 | $surCategory = $this->SurCategories->get($id, [ | 256 | $surCategory = $this->SurCategories->get($id, [ |
257 | 'contain' => [] | 257 | 'contain' => [] |
258 | ]); | 258 | ]); |
259 | + | ||
260 | + // En mode POST | ||
259 | if ($this->request->is([ | 261 | if ($this->request->is([ |
260 | 'patch', | 262 | 'patch', |
261 | 'post', | 263 | 'post', |
@@ -274,10 +276,14 @@ class SurCategoriesController extends AppController | @@ -274,10 +276,14 @@ class SurCategoriesController extends AppController | ||
274 | $this->Flash->error(__('Le domaine n\'a pas pu être édité.')); | 276 | $this->Flash->error(__('Le domaine n\'a pas pu être édité.')); |
275 | } | 277 | } |
276 | } | 278 | } |
279 | + | ||
280 | + // En mode GET (ou alors POST après une erreur) | ||
277 | $this->set(compact('surCategory')); | 281 | $this->set(compact('surCategory')); |
282 | + /* (EP) inutile sauf si json | ||
278 | $this->set('_serialize', [ | 283 | $this->set('_serialize', [ |
279 | 'surCategory' | 284 | 'surCategory' |
280 | ]); | 285 | ]); |
286 | + */ | ||
281 | } | 287 | } |
282 | 288 | ||
283 | /** | 289 | /** |
@@ -0,0 +1,47 @@ | @@ -0,0 +1,47 @@ | ||
1 | +<?php | ||
2 | +// in src/Form/ContactForm.php | ||
3 | +namespace App\Form; | ||
4 | + | ||
5 | +use Cake\Form\Form; | ||
6 | +use Cake\Form\Schema; | ||
7 | +use Cake\Validation\Validator; | ||
8 | +use Cake\Core\Configure; | ||
9 | + | ||
10 | +// modelless form : voir https://book.cakephp.org/3/en/core-libraries/form.html | ||
11 | +class ConfigurationFieldsForm extends Form | ||
12 | +{ | ||
13 | + /* | ||
14 | + protected function _buildSchema(Schema $schema) | ||
15 | + { | ||
16 | + //$fields = Configure::readOrFail('MANDATORY_AND_READONLY_FIELDS'); | ||
17 | + //debug($fields); | ||
18 | + //foreach ($fields as $fname=>$val) debug($fname); | ||
19 | + | ||
20 | + return $schema | ||
21 | + ->addField('name', 'string') | ||
22 | + ->addField('email', ['type' => 'string']) | ||
23 | + ->addField('body', ['type' => 'text']); | ||
24 | + } | ||
25 | + */ | ||
26 | + | ||
27 | + /* | ||
28 | + public function validationDefault(Validator $validator) | ||
29 | + { | ||
30 | + $validator->add('name', 'length', [ | ||
31 | + 'rule' => ['minLength', 5], | ||
32 | + 'message' => 'A name is required' | ||
33 | + ])->add('email', 'format', [ | ||
34 | + 'rule' => 'email', | ||
35 | + 'message' => 'A valid email address is required', | ||
36 | + ]); | ||
37 | + | ||
38 | + return $validator; | ||
39 | + } | ||
40 | + */ | ||
41 | + | ||
42 | + protected function _execute(array $data) | ||
43 | + { | ||
44 | + // Send an email. | ||
45 | + return true; | ||
46 | + } | ||
47 | +} | ||
0 | \ No newline at end of file | 48 | \ No newline at end of file |
src/Model/Table/MaterielsTable.php
@@ -252,60 +252,84 @@ class MaterielsTable extends AppTable | @@ -252,60 +252,84 @@ class MaterielsTable extends AppTable | ||
252 | * - LOT0 total = [] + LOT0 | 252 | * - LOT0 total = [] + LOT0 |
253 | * - LOT1 total = LOT0 + LOT1 | 253 | * - LOT1 total = LOT0 + LOT1 |
254 | * - LOT2 total = LOT1 + LOT2 | 254 | * - LOT2 total = LOT1 + LOT2 |
255 | + * | ||
256 | + * Algo RECURSIF | ||
255 | */ | 257 | */ |
258 | + public static function getCategoryFieldsForLot($categ, $lot_num, $categ_initial=null) { | ||
259 | + //debug($lot_num); | ||
260 | + // ex: $categ = RECOMMENDED_FIELDS_AFTER_LOT | ||
261 | + //if ($lot_num < 0) return $categ_initial ? Configure::readOrFail('UNEDITABLE_FIELDS') : []; | ||
262 | + if ($lot_num < 0) return $categ_initial ? Configure::readOrFail("MANDATORY_AND_READONLY_FIELDS.$categ_initial") : []; | ||
263 | + | ||
264 | + // Recursive call | ||
265 | + $base_fields = self::getCategoryFieldsForLot($categ, $lot_num-1, $categ_initial); | ||
266 | + $base_fields = self::removeUnselectedFieldsFrom($base_fields); | ||
267 | + //debug($base_fields); | ||
268 | + | ||
269 | + //$new_fields = Configure::readOrFail('MANDATORY_AND_READONLY_FIELDS.RECOMMENDED_FIELDS_AFTER_LOT'.$lot_num); | ||
270 | + $new_fields = Configure::readOrFail("MANDATORY_AND_READONLY_FIELDS.$categ".$lot_num); | ||
271 | + $new_fields = self::removeUnselectedFieldsFrom($new_fields); | ||
272 | + //debug($new_fields); | ||
273 | + | ||
274 | + //debug($new_fields); | ||
275 | + return array_merge($base_fields, $new_fields); | ||
276 | + } | ||
277 | + | ||
278 | + | ||
279 | + | ||
280 | + public static function removeUnselectedFieldsFrom($fields) { | ||
281 | + /* | ||
282 | + * Exemple : | ||
283 | + Before remove : | ||
284 | + { | ||
285 | + designation: { selected: '0', comment: commentaire, roles: '' }, | ||
286 | + description: { selected: '0', comment: autre, roles: '' }, | ||
287 | + nom_responsable: { selected: '1', comment: 'nom du responsable', | ||
288 | + } | ||
289 | + After remove : | ||
290 | + { | ||
291 | + nom_responsable: { selected: '1', comment: 'nom du responsable', | ||
292 | + } | ||
293 | + */ | ||
294 | + //$fields_selected = []; | ||
295 | + foreach ($fields as $field_name => $attributes) { | ||
296 | + if ( $field_name=='fieldset_comment' || !$attributes['selected'] ) unset($fields[$field_name]); | ||
297 | + } | ||
298 | + return $fields; | ||
299 | + } | ||
300 | + | ||
256 | public static function getMandatoryFieldsForLot($lot_num) { | 301 | public static function getMandatoryFieldsForLot($lot_num) { |
302 | + return self::getCategoryFieldsForLot('MANDATORY_FIELDS_FOR_LOT', $lot_num); | ||
257 | /* | 303 | /* |
258 | $specific_constant_name = "MANDATORY_FIELDS_FOR_LOT1_".self::getLabName(); | 304 | $specific_constant_name = "MANDATORY_FIELDS_FOR_LOT1_".self::getLabName(); |
259 | $mandatory_fields_lot1 = defined($specific_constant_name) ? constant($specific_constant_name) : MANDATORY_FIELDS_FOR_LOT1; | 305 | $mandatory_fields_lot1 = defined($specific_constant_name) ? constant($specific_constant_name) : MANDATORY_FIELDS_FOR_LOT1; |
260 | return $mandatory_fields_lot1; | 306 | return $mandatory_fields_lot1; |
261 | */ | 307 | */ |
308 | + /* | ||
262 | if ($lot_num < 0) return []; | 309 | if ($lot_num < 0) return []; |
263 | $base_fields = self::getMandatoryFieldsForLot($lot_num-1); | 310 | $base_fields = self::getMandatoryFieldsForLot($lot_num-1); |
264 | $new_fields = Configure::readOrFail('MANDATORY_FIELDS_FOR_LOT'.$lot_num); | 311 | $new_fields = Configure::readOrFail('MANDATORY_FIELDS_FOR_LOT'.$lot_num); |
265 | //debug($new_fields); | 312 | //debug($new_fields); |
266 | return array_merge($base_fields, $new_fields); | 313 | return array_merge($base_fields, $new_fields); |
314 | + */ | ||
267 | } | 315 | } |
316 | + // RECURSIF | ||
268 | public static function getRecommendedFieldsForLot($lot_num) { | 317 | public static function getRecommendedFieldsForLot($lot_num) { |
318 | + return self::getCategoryFieldsForLot('RECOMMENDED_FIELDS_AFTER_LOT', $lot_num); | ||
319 | + /* | ||
269 | if ($lot_num < 0) return []; | 320 | if ($lot_num < 0) return []; |
270 | $base_fields = self::getRecommendedFieldsForLot($lot_num-1); | 321 | $base_fields = self::getRecommendedFieldsForLot($lot_num-1); |
271 | - $new_fields = Configure::readOrFail('RECOMMENDED_FIELDS_AFTER_LOT'.$lot_num); | 322 | + $new_fields = Configure::readOrFail('MANDATORY_AND_READONLY_FIELDS.RECOMMENDED_FIELDS_AFTER_LOT'.$lot_num); |
272 | //debug($new_fields); | 323 | //debug($new_fields); |
273 | return array_merge($base_fields, $new_fields); | 324 | return array_merge($base_fields, $new_fields); |
325 | + */ | ||
274 | } | 326 | } |
275 | - | ||
276 | - // (EP 2021 10) | ||
277 | - public static function list_to_dict($uneditable_fields) { | ||
278 | - $dict = []; | ||
279 | - foreach ($uneditable_fields as $f) { | ||
280 | - $except_roles = []; | ||
281 | - $except_str = '(sauf'; | ||
282 | - $pos0 = strpos($f, '('); | ||
283 | - $pos = strpos($f, $except_str); | ||
284 | - // Si le nom du champ $f fini par "(sauf ...)", on récupère cette chaine except (sans le mot 'sauf' ni la parenthèse finale) dans $except | ||
285 | - if ($pos0 !== false) { | ||
286 | - $error_msg = "Erreur dans le fichier de configuration des champs non modifiables"; | ||
287 | - // EXCEPTION si parenthèse début mais pas suivie du mot-clé 'sauf' | ||
288 | - if ($pos === false) | ||
289 | - throw new \Exception("$error_msg : une parenthèse doit toujours être suivie du mot-clé 'sauf', ce qui n'est pas le cas de la ligne '$f'"); | ||
290 | - // EXCEPTION si pas de parenthèse finale, ou role mal orthographié | ||
291 | - //$except_list = trim( substr($f, $pos + strlen($except_str), -1) ); | ||
292 | - if ( substr($f, -1) != ')' ) | ||
293 | - throw new \Exception("$error_msg : il manque une parenthèse à la fin de la ligne '$f'"); | ||
294 | - $except_roles = str_replace(" ", "", substr($f, $pos + strlen($except_str), -1) ); | ||
295 | - $except_roles = explode(',', $except_roles); | ||
296 | - foreach ($except_roles as $role) if (! self::isValidRole($role)) | ||
297 | - throw new \Exception("$error_msg : le role '$role' est mal orthographié dans la ligne '$f'"); | ||
298 | - $f = trim( substr($f,0,$pos) ); | ||
299 | - } | ||
300 | - $dict[$f] = $except_roles; | ||
301 | - } | ||
302 | - return $dict; | ||
303 | - } | ||
304 | - | ||
305 | // (EP 2021 09) fonction récursive : | 327 | // (EP 2021 09) fonction récursive : |
306 | // => champs readonly pour le lot N = champs readonly pour le lot N-1 + champs readonly pour le lot N : | 328 | // => champs readonly pour le lot N = champs readonly pour le lot N-1 + champs readonly pour le lot N : |
307 | public static function getUneditableFieldsForLot($lot_num) { | 329 | public static function getUneditableFieldsForLot($lot_num) { |
308 | - | 330 | + return self::getCategoryFieldsForLot('UNEDITABLE_FIELDS_AFTER_LOT', $lot_num, 'UNEDITABLE_FIELDS'); |
331 | + /* | ||
332 | + | ||
309 | // Si N = -1 => on retourne la liste initiale de champs readonly (fin de la récursivité) | 333 | // Si N = -1 => on retourne la liste initiale de champs readonly (fin de la récursivité) |
310 | //if ($lot_num < 0) return []; | 334 | //if ($lot_num < 0) return []; |
311 | if ($lot_num < 0) return self::list_to_dict( Configure::readOrFail('UNEDITABLE_FIELDS') ); | 335 | if ($lot_num < 0) return self::list_to_dict( Configure::readOrFail('UNEDITABLE_FIELDS') ); |
@@ -323,10 +347,57 @@ class MaterielsTable extends AppTable | @@ -323,10 +347,57 @@ class MaterielsTable extends AppTable | ||
323 | // => Somme des 2 (champs readonly pour le lot N-1 + champs readonly pour le lot N) | 347 | // => Somme des 2 (champs readonly pour le lot N-1 + champs readonly pour le lot N) |
324 | //return array_unique(array_merge($base_uneditable_fields, $new_uneditable_fields)); | 348 | //return array_unique(array_merge($base_uneditable_fields, $new_uneditable_fields)); |
325 | return array_merge($base_uneditable_fields, $new_uneditable_fields); | 349 | return array_merge($base_uneditable_fields, $new_uneditable_fields); |
350 | + */ | ||
326 | 351 | ||
327 | } | 352 | } |
328 | 353 | ||
329 | 354 | ||
355 | + public static function separateFieldNameAndExceptedRoles($f) { | ||
356 | + $except_roles = []; | ||
357 | + $except_str = '(sauf'; | ||
358 | + $pos0 = strpos($f, '('); | ||
359 | + $pos = strpos($f, $except_str); | ||
360 | + // Si le nom du champ $f fini par "(sauf ...)", on récupère cette chaine except (sans le mot 'sauf' ni la parenthèse finale) dans $except | ||
361 | + if ($pos0 !== false) { | ||
362 | + $error_msg = "Erreur dans le fichier de configuration des champs non modifiables"; | ||
363 | + | ||
364 | + // EXCEPTION si parenthèse début mais pas suivie du mot-clé 'sauf' | ||
365 | + /* | ||
366 | + if ($pos === false) | ||
367 | + throw new \Exception("$error_msg : une parenthèse doit toujours être suivie du mot-clé 'sauf', ce qui n'est pas le cas de la ligne '$f'"); | ||
368 | + */ | ||
369 | + if ($pos !== false) { | ||
370 | + | ||
371 | + // EXCEPTION si pas de parenthèse finale, ou role mal orthographié | ||
372 | + //$except_list = trim( substr($f, $pos + strlen($except_str), -1) ); | ||
373 | + if ( substr($f, -1) != ')' ) | ||
374 | + throw new \Exception("$error_msg : il manque une parenthèse à la fin de la ligne '$f'"); | ||
375 | + | ||
376 | + $except_roles = str_replace(" ", "", substr($f, $pos + strlen($except_str), -1) ); | ||
377 | + $except_roles = explode(',', $except_roles); | ||
378 | + foreach ($except_roles as $role) if (! self::isValidRole($role)) | ||
379 | + throw new \Exception("$error_msg : le role '$role' est mal orthographié dans la ligne '$f'"); | ||
380 | + | ||
381 | + $f = trim( substr($f,0,$pos) ); | ||
382 | + } | ||
383 | + } | ||
384 | + //return [$f=>$except_roles]; | ||
385 | + return ['name'=>$f, 'roles'=>$except_roles]; | ||
386 | + } | ||
387 | + | ||
388 | + // (EP 2021 10) | ||
389 | + public static function list_to_dict($uneditable_fields) { | ||
390 | + $dict = []; | ||
391 | + foreach ($uneditable_fields as $f) { | ||
392 | + //$dict[$f] = $except_roles; | ||
393 | + $fieldNameAndExceptedRoles = self::separateFieldNameAndExceptedRoles($f); | ||
394 | + $dict[$fieldNameAndExceptedRoles['name']] = $fieldNameAndExceptedRoles['except_roles']; | ||
395 | + } | ||
396 | + return $dict; | ||
397 | + } | ||
398 | + | ||
399 | + | ||
400 | + | ||
330 | /* | 401 | /* |
331 | public static function getMandatoryFieldsLot1() { | 402 | public static function getMandatoryFieldsLot1() { |
332 | /S | 403 | /S |
@@ -353,7 +424,13 @@ class MaterielsTable extends AppTable | @@ -353,7 +424,13 @@ class MaterielsTable extends AppTable | ||
353 | $fields = self::getMandatoryFieldsForMaterielStatus($status); | 424 | $fields = self::getMandatoryFieldsForMaterielStatus($status); |
354 | // Seulement si prix > 10K€ : exiger la facture jointe et le n° série et lieu de stockage précis | 425 | // Seulement si prix > 10K€ : exiger la facture jointe et le n° série et lieu de stockage précis |
355 | if ($status == 'VALIDATED' && $mat->prix_ht && $mat->prix_ht > 10000) { | 426 | if ($status == 'VALIDATED' && $mat->prix_ht && $mat->prix_ht > 10000) { |
356 | - $fields['numero_serie'] = 'S/N'; | 427 | + //$fields['numero_serie'] = 'S/N'; |
428 | + /* | ||
429 | + $fields['numero_serie'] = [ | ||
430 | + //'selected'=>'1', | ||
431 | + 'comment'=>'S/N' | ||
432 | + ]; | ||
433 | + */ | ||
357 | //TODO 202109 | 434 | //TODO 202109 |
358 | //$fields[] = 'lieu stockage'; | 435 | //$fields[] = 'lieu stockage'; |
359 | //$fields[] = 'facture jointe'; | 436 | //$fields[] = 'facture jointe'; |
@@ -361,7 +438,9 @@ class MaterielsTable extends AppTable | @@ -361,7 +438,9 @@ class MaterielsTable extends AppTable | ||
361 | return $fields; | 438 | return $fields; |
362 | } | 439 | } |
363 | public static function getMandatoryFieldsForMaterielStatus($status) { | 440 | public static function getMandatoryFieldsForMaterielStatus($status) { |
364 | - | 441 | + //return self::getCategoryFieldsForMaterielStatus('MANDATORY_FIELDS_FOR_LOT', $status); |
442 | + return self::getCategoryFieldsForMaterielStatus('MANDATORY', $status); | ||
443 | + /* | ||
365 | if (is_null($status)) $status='CREATED'; | 444 | if (is_null($status)) $status='CREATED'; |
366 | // On recup le LOT qui convient au status courant du matos | 445 | // On recup le LOT qui convient au status courant du matos |
367 | //$fields = ($status == 'CREATED') ? self::getMandatoryFieldsForLot(1) : self::getMandatoryFieldsForLot(2); | 446 | //$fields = ($status == 'CREATED') ? self::getMandatoryFieldsForLot(1) : self::getMandatoryFieldsForLot(2); |
@@ -375,9 +454,12 @@ class MaterielsTable extends AppTable | @@ -375,9 +454,12 @@ class MaterielsTable extends AppTable | ||
375 | //debug($fields); | 454 | //debug($fields); |
376 | 455 | ||
377 | return $fields; | 456 | return $fields; |
457 | + */ | ||
378 | } | 458 | } |
379 | public static function getUneditableFieldsForMaterielStatus($status) { | 459 | public static function getUneditableFieldsForMaterielStatus($status) { |
380 | - | 460 | + //return self::getCategoryFieldsForMaterielStatus('UNEDITABLE_FIELDS_AFTER_LOT', $status); |
461 | + return self::getCategoryFieldsForMaterielStatus('UNEDITABLE', $status); | ||
462 | + /* | ||
381 | if (is_null($status)) $status='CREATED'; | 463 | if (is_null($status)) $status='CREATED'; |
382 | // On recup le LOT qui convient au status courant du matos | 464 | // On recup le LOT qui convient au status courant du matos |
383 | //$fields = ($status == 'CREATED') ? self::getMandatoryFieldsForLot(1) : self::getMandatoryFieldsForLot(2); | 465 | //$fields = ($status == 'CREATED') ? self::getMandatoryFieldsForLot(1) : self::getMandatoryFieldsForLot(2); |
@@ -390,12 +472,19 @@ class MaterielsTable extends AppTable | @@ -390,12 +472,19 @@ class MaterielsTable extends AppTable | ||
390 | $fields = self::getUneditableFieldsForLot($lot_num); | 472 | $fields = self::getUneditableFieldsForLot($lot_num); |
391 | 473 | ||
392 | return $fields; | 474 | return $fields; |
475 | + */ | ||
393 | } | 476 | } |
394 | public static function getRecommendedFieldsForMaterielStatus($status) { | 477 | public static function getRecommendedFieldsForMaterielStatus($status) { |
395 | - return self::getFieldsCategoryForMaterielStatus('RECOMMENDED', $status); | 478 | + //return self::getCategoryFieldsForMaterielStatus('RECOMMENDED', $status); |
479 | + //return self::getCategoryFieldsForMaterielStatus('RECOMMENDED_FIELDS_AFTER_LOT', $status); | ||
480 | + return self::getCategoryFieldsForMaterielStatus('RECOMMENDED', $status); | ||
396 | } | 481 | } |
397 | - public static function getFieldsCategoryForMaterielStatus($fields_categ, $status) { | ||
398 | - $func_name = "get".ucfirst($fields_categ)."FieldsForLot"; // getUneditableFieldsForLot() | 482 | + |
483 | + public static function getCategoryFieldsForMaterielStatus($categ, $status) { | ||
484 | + //$func_name = "get".ucfirst($fields_categ)."FieldsForLot"; // getUneditableFieldsForLot() | ||
485 | + //$func_name = "getCategoryFieldsForLot"; // getUneditableFieldsForLot() | ||
486 | + $func_name = "get".ucfirst($categ)."FieldsForLot"; // getUneditableFieldsForLot() | ||
487 | + | ||
399 | if (is_null($status)) $status='CREATED'; | 488 | if (is_null($status)) $status='CREATED'; |
400 | // On recup le LOT qui convient au status courant du matos | 489 | // On recup le LOT qui convient au status courant du matos |
401 | //$fields = ($status == 'CREATED') ? self::getMandatoryFieldsForLot(1) : self::getMandatoryFieldsForLot(2); | 490 | //$fields = ($status == 'CREATED') ? self::getMandatoryFieldsForLot(1) : self::getMandatoryFieldsForLot(2); |
@@ -1560,6 +1649,9 @@ class MaterielsTable extends AppTable | @@ -1560,6 +1649,9 @@ class MaterielsTable extends AppTable | ||
1560 | $fournisseur_asis = $entity->fournisseur ? $entity->fournisseur['name'] : ''; | 1649 | $fournisseur_asis = $entity->fournisseur ? $entity->fournisseur['name'] : ''; |
1561 | // Enlever les espaces superflus | 1650 | // Enlever les espaces superflus |
1562 | $fournisseur = trim($fournisseur_asis); | 1651 | $fournisseur = trim($fournisseur_asis); |
1652 | + //debug($fournisseur); | ||
1653 | + //debug($entity); | ||
1654 | + | ||
1563 | 1655 | ||
1564 | // Si champ fournisseur obligatoire, vérification qu'il est bien rempli (ou emission d'une erreur) | 1656 | // Si champ fournisseur obligatoire, vérification qu'il est bien rempli (ou emission d'une erreur) |
1565 | //if (IP2I && $entity->fournisseur && $fournisseur == '') { | 1657 | //if (IP2I && $entity->fournisseur && $fournisseur == '') { |
@@ -1688,6 +1780,7 @@ class MaterielsTable extends AppTable | @@ -1688,6 +1780,7 @@ class MaterielsTable extends AppTable | ||
1688 | } // ssi changement | 1780 | } // ssi changement |
1689 | // Finalement, on supprime les champs 'fournisseur' car sinon erreur de sauvegarde, | 1781 | // Finalement, on supprime les champs 'fournisseur' car sinon erreur de sauvegarde, |
1690 | // (normal ces champs n'existent pas dans materiel) | 1782 | // (normal ces champs n'existent pas dans materiel) |
1783 | + //debug($entity); exit; | ||
1691 | unset($entity->fournisseur_orig); | 1784 | unset($entity->fournisseur_orig); |
1692 | unset($entity->fournisseur); | 1785 | unset($entity->fournisseur); |
1693 | //debug($entity); exit; | 1786 | //debug($entity); exit; |
@@ -0,0 +1,149 @@ | @@ -0,0 +1,149 @@ | ||
1 | +<?php | ||
2 | + | ||
3 | +use App\Model\Table\MaterielsTable; | ||
4 | + | ||
5 | +$DEBUG = false; | ||
6 | +//$DEBUG = true; | ||
7 | + | ||
8 | + | ||
9 | +// Variables générales cakephp | ||
10 | +$_REQUEST = $_REQUEST; | ||
11 | +$_COOKIE = $_COOKIE; | ||
12 | +$_ENV = $_ENV; | ||
13 | +//debug($_COOKIE); | ||
14 | +/* | ||
15 | +[ | ||
16 | + 'CAKEPHP' => 'hiraigc02eb46spa06iiog6tvh' | ||
17 | +] | ||
18 | +*/ | ||
19 | +//debug($_ENV); | ||
20 | +//debug($_REQUEST); | ||
21 | + | ||
22 | +// Variables passées par le controleur | ||
23 | +$CAN_EDIT = true; | ||
24 | +$CAN_EDIT = $CAN_EDIT; | ||
25 | +$READONLY = $READONLY; | ||
26 | +$contact = $contact; | ||
27 | +$fieldsets = $fieldsets; | ||
28 | +//debug($fieldsets); | ||
29 | + | ||
30 | +$icon = $READONLY ? '' : "<i class='icon-edit'></i>"; | ||
31 | +//$icon = $READONLY ? '' : "<i class='icon-pencil'></i>"; | ||
32 | +//$end = $READONLY ? "(Visualisation)" : "(Modification)"; | ||
33 | +//$title = "Configuration des champs obligatoires ou non modifiables de la fiche Matériel $end"; | ||
34 | +$title = "Configuration des champs obligatoires ou non modifiables de la fiche Matériel"; | ||
35 | +echo "<br><h2>$icon $title</h2><br><br>"; | ||
36 | +/* | ||
37 | + Autres icones possibles : | ||
38 | +echo "<br><h2><i class='icon-edit'></i> $title</h2><br><br>"; | ||
39 | +echo "<br><h2><i class='icon-list'></i> $title</h2><br><br>"; | ||
40 | +echo "<br><h2><i class='icon-plus'></i> $title</h2><br><br>"; | ||
41 | +echo "<br><h2><i class='icon-pencil'></i> $title</h2><br><br>"; | ||
42 | +echo "<br><h2><i class='icon-trash'></i> $title</h2><br><br>"; | ||
43 | +*/ | ||
44 | + | ||
45 | +if ($READONLY && $CAN_EDIT) $this->MyHelper->echoEditButton(); | ||
46 | +if ($READONLY && $CAN_EDIT) $this->MyHelper->echoButtonForAction('icon-trash', 'reset-to-default', 'Remettre les valeurs par défaut', 'Remettre les valeurs par défaut', true); | ||
47 | + | ||
48 | +//echo $this->Html->icon('pencil'); | ||
49 | + | ||
50 | +echo $this->Form->create($contact); | ||
51 | + | ||
52 | + if (!$READONLY) { | ||
53 | + echo $this->Form->button('Enregistrer', ['class'=>'btn btn-outline-success', 'type'=>'submit']); | ||
54 | + //echo $this->Form->button('Submit'); | ||
55 | + echo '<br><br>'; | ||
56 | + } | ||
57 | + | ||
58 | + //echo $this->Form->button($this->Html->icon('pencil'), ['escape' => false]); | ||
59 | + // ...can be easily rewritten as: | ||
60 | + //echo $this->Form->button('i:pencil'); | ||
61 | + | ||
62 | + foreach ($fieldsets as $fieldset_name => $fields) { | ||
63 | + $controls = []; | ||
64 | + | ||
65 | + //foreach ($fields as $field) { | ||
66 | + foreach ($fields as $field_name => $attributes) { | ||
67 | + | ||
68 | + if ($field_name=='fieldset_comment') continue; | ||
69 | + | ||
70 | + // champ activé ou désactivé | ||
71 | + $checked = $attributes['selected']; | ||
72 | + $comment = $attributes['comment']; | ||
73 | + $except_roles = isset($attributes['except_roles']) ? $attributes['except_roles'] : []; | ||
74 | + | ||
75 | + $name = "$fieldset_name.$field_name"; | ||
76 | + | ||
77 | + // - CHAMP de la table materiel : Checkbox pour le dé/sélectionner | ||
78 | + $label = $field_name; | ||
79 | + if ($READONLY) { | ||
80 | + if ($comment) $label .= ' ('.$comment.')'; | ||
81 | + if ($except_roles) $label .= ' (sauf '.implode(', ',$except_roles).')'; | ||
82 | + } | ||
83 | + $controls["$name.selected"] = [ | ||
84 | + 'type' => 'checkbox', | ||
85 | + //'hiddenField' => true, | ||
86 | + 'label' => $label, | ||
87 | + 'checked' => $checked, | ||
88 | + 'disabled' => $READONLY, | ||
89 | + //'readonly' =>$READONLY, | ||
90 | + //'readonly' => 'readonly', | ||
91 | + ]; | ||
92 | + | ||
93 | + // (EDIT ONLY) | ||
94 | + // - Label associé au champ (entre parenthèses) doit pouvoir être modifié | ||
95 | + if (!$READONLY) $controls["$name.comment"] = [ | ||
96 | + //'type' => 'input', | ||
97 | + 'label' => false, | ||
98 | + 'val' => $comment, | ||
99 | + //'size' => 20, | ||
100 | + //'disabled' => $READONLY, | ||
101 | + //'readonly' => $READONLY, | ||
102 | + ]; | ||
103 | + | ||
104 | + // (EDIT ONLY) | ||
105 | + $fieldsets_with_roles = ['UNEDITABLE_FIELDS','UNEDITABLE_FIELDS_AFTER_LOT0', 'UNEDITABLE_FIELDS_AFTER_LOT1', 'UNEDITABLE_FIELDS_AFTER_LOT2']; | ||
106 | + // - ROLES exceptés (select multiple list) | ||
107 | + //if (!$READONLY && $field_name!='HAS_ORDER_BUTTON') | ||
108 | + if ( !$READONLY && in_array($fieldset_name, $fieldsets_with_roles) ) $controls["$name.except_roles"] = [ | ||
109 | + 'type' => 'select', | ||
110 | + 'label' => '(excepté pour les rôles)', | ||
111 | + //'options' => ['<aucune exception>', 'user', 'admin', 'resp'], | ||
112 | + //'options' => ['Utilisateur', 'Responsable', 'Administration'], | ||
113 | + 'options' => [ | ||
114 | + ['text' => 'Utilisateur', 'value' => 'Utilisateur'], | ||
115 | + ['text' => 'Responsable', 'value' => 'Responsable'], | ||
116 | + ['text' => 'Administration', 'value' => 'Administration'], | ||
117 | + ], | ||
118 | + //'val' => ['Responsable', 'Utilisateur'], | ||
119 | + 'val' => $except_roles, | ||
120 | + 'multiple' => 'checkbox', | ||
121 | + //'size' => 20, | ||
122 | + 'disabled' => $READONLY, | ||
123 | + ]; | ||
124 | + | ||
125 | + } // foreach $fields | ||
126 | + | ||
127 | + // https://api.cakephp.org/3.5/class-Cake.View.Helper.FormHelper.html#_controls | ||
128 | + $DEBUG && debug($controls); | ||
129 | + $fieldset_name_with_comment = $fieldset_name; | ||
130 | + if ( isset($fields['fieldset_comment']) ) $fieldset_name_with_comment .= ' ('. $fields['fieldset_comment'] .')'; | ||
131 | + echo $this->Form->controls($controls, ['legend' => $fieldset_name_with_comment.' :']); | ||
132 | + | ||
133 | + } // foreach $fieldsets | ||
134 | + | ||
135 | + /* | ||
136 | + echo $this->Form->control('name'); | ||
137 | + echo $this->Form->control('email'); | ||
138 | + echo $this->Form->control('body'); | ||
139 | + */ | ||
140 | + | ||
141 | + if (!$READONLY) | ||
142 | + echo $this->Form->button('Enregistrer', ['class'=>'btn btn-outline-success', 'type'=>'submit']); | ||
143 | + //echo $this->Form->button('Submit'); | ||
144 | + | ||
145 | + | ||
146 | +echo $this->Form->end(); | ||
147 | + | ||
148 | +if ($READONLY && $CAN_EDIT) $this->MyHelper->echoEditButton(); | ||
149 | + |
src/Template/Materiels/index.ctp
@@ -525,7 +525,7 @@ $displayLegend = function() { | @@ -525,7 +525,7 @@ $displayLegend = function() { | ||
525 | <i style='color:black'>noir=livré (validé)</i> ;" | 525 | <i style='color:black'>noir=livré (validé)</i> ;" |
526 | //<i style='color:red'>rouge=à sortir</i> ; | 526 | //<i style='color:red'>rouge=à sortir</i> ; |
527 | ." <i style='color:blue'>bleu=archivé</i> ; | 527 | ." <i style='color:blue'>bleu=archivé</i> ; |
528 | - (couleur date : <i style='color:red'>rouge=fin garantie</i>, <i style='color:orange'>orange=< 1 an</i>) | 528 | + (couleur date : <i style='color:red'>rouge=fin garantie</i>, <i style='color:orange'>orange=<1 an</i>) |
529 | </i></p>"; | 529 | </i></p>"; |
530 | }; | 530 | }; |
531 | 531 |
src/Template/Pages/about.ctp
1 | <div class="index col-lg-12"> | 1 | <div class="index col-lg-12"> |
2 | + | ||
2 | <?php | 3 | <?php |
3 | $softwareName = "LABINVENT"; | 4 | $softwareName = "LABINVENT"; |
4 | 5 | ||
6 | +echo '<br/>'; | ||
5 | echo '<h2><i class="icon-idea"></i> A PROPOS DU LOGICIEL ' . $softwareName . '</h2>'; | 7 | echo '<h2><i class="icon-idea"></i> A PROPOS DU LOGICIEL ' . $softwareName . '</h2>'; |
6 | 8 | ||
9 | +echo '<br/>'; | ||
10 | +echo '<a href="/pages/changes">Changements faits sur le logiciel (nouveautés et historique)</a>'; | ||
11 | + | ||
12 | +echo '<br/><br/>'; | ||
13 | +echo '<a href="https://tinyurl.com/labinvent">Documentation générale</a>'; | ||
14 | + | ||
15 | +echo '<br/><br/>'; | ||
16 | +echo '<a href="' . $this->request->webroot . 'doc/userguide/labinvent2_userguide.pdf">Guide utilisateur</a>'; | ||
17 | +echo '<br/><br/>'; | ||
18 | + | ||
19 | + | ||
20 | + | ||
7 | /* | 21 | /* |
8 | echo <<<"EOD" | 22 | echo <<<"EOD" |
9 | <section id="cadre" class="col-lg-12"> | 23 | <section id="cadre" class="col-lg-12"> |
@@ -34,8 +48,12 @@ Licence GPL (http://www.gnu.org/copyleft/gpl.html)<br><br> | @@ -34,8 +48,12 @@ Licence GPL (http://www.gnu.org/copyleft/gpl.html)<br><br> | ||
34 | EOD; | 48 | EOD; |
35 | */ | 49 | */ |
36 | 50 | ||
51 | +?> | ||
37 | 52 | ||
38 | -echo '<section id="cadre" class="col-lg-12">'; | 53 | + |
54 | +<section id="cadre" class="col-lg-12"> | ||
55 | + | ||
56 | +<?php | ||
39 | 57 | ||
40 | // On lit le fichier /WWWROOT/../LICENSE | 58 | // On lit le fichier /WWWROOT/../LICENSE |
41 | $wwwroot_dir = new Cake\Filesystem\Folder(WWW_ROOT); | 59 | $wwwroot_dir = new Cake\Filesystem\Folder(WWW_ROOT); |
@@ -75,7 +93,7 @@ $lines = new LimitIterator($f, $line_num_from); | @@ -75,7 +93,7 @@ $lines = new LimitIterator($f, $line_num_from); | ||
75 | //$lines_reversed = array_reverse(iterator_to_array($lines)); | 93 | //$lines_reversed = array_reverse(iterator_to_array($lines)); |
76 | $lines = iterator_to_array($lines); | 94 | $lines = iterator_to_array($lines); |
77 | foreach ($lines as $line) { | 95 | foreach ($lines as $line) { |
78 | - echo $line.'<br><br>'; | 96 | + echo $line.'<br>'; |
79 | //if (mb_strpos($line, "$level: ") !== FALSE) echo $line.'<br><br>'; | 97 | //if (mb_strpos($line, "$level: ") !== FALSE) echo $line.'<br><br>'; |
80 | //if (mb_strpos($line, 'Info: ') !== FALSE) echo $line.'<br><br>'; | 98 | //if (mb_strpos($line, 'Info: ') !== FALSE) echo $line.'<br><br>'; |
81 | //if (mb_strpos($line, '/materiels/edit/') !== FALSE) echo $line.'<br><br>'; | 99 | //if (mb_strpos($line, '/materiels/edit/') !== FALSE) echo $line.'<br><br>'; |
@@ -84,18 +102,10 @@ foreach ($lines as $line) { | @@ -84,18 +102,10 @@ foreach ($lines as $line) { | ||
84 | // Close file | 102 | // Close file |
85 | $f=null; | 103 | $f=null; |
86 | 104 | ||
87 | -echo '</section>'; | ||
88 | - | ||
89 | - | ||
90 | -echo '<br/>'; | ||
91 | -echo '<a href="/pages/changes">Changements faits sur le logiciel (nouveautés et historique)</a>'; | 105 | +?> |
92 | 106 | ||
93 | -echo '<br/><br/>'; | ||
94 | -echo '<a href="https://tinyurl.com/labinvent">Documentation générale</a>'; | 107 | +</section> |
95 | 108 | ||
96 | -echo '<br/><br/>'; | ||
97 | -echo '<a href="' . $this->request->webroot . 'doc/userguide/labinvent2_userguide.pdf">Guide utilisateur</a>'; | ||
98 | -?> | ||
99 | </div> | 109 | </div> |
100 | 110 | ||
101 | <!-- | 111 | <!-- |
src/Template/Pages/home_app.ctp
@@ -4,6 +4,7 @@ | @@ -4,6 +4,7 @@ | ||
4 | //debug($this->viewVars); | 4 | //debug($this->viewVars); |
5 | $configuration = $configuration; | 5 | $configuration = $configuration; |
6 | $USER_IS_RESPONSABLE = $USER_IS_RESPONSABLE; | 6 | $USER_IS_RESPONSABLE = $USER_IS_RESPONSABLE; |
7 | +$USER_IS_SUPERADMIN = $USER_IS_SUPERADMIN; | ||
7 | $HAS_ORDER_BUTTON = $HAS_ORDER_BUTTON; | 8 | $HAS_ORDER_BUTTON = $HAS_ORDER_BUTTON; |
8 | 9 | ||
9 | 10 | ||
@@ -123,6 +124,12 @@ echo $SEP; | @@ -123,6 +124,12 @@ echo $SEP; | ||
123 | echo '<a href="/pages/stats">Statistiques sur les matériels</a>'; | 124 | echo '<a href="/pages/stats">Statistiques sur les matériels</a>'; |
124 | echo '</td></tr>'; | 125 | echo '</td></tr>'; |
125 | 126 | ||
127 | + if ($USER_IS_SUPERADMIN) { | ||
128 | + echo '<tr><td>'; | ||
129 | + echo '<a href="/stats">Statistiques sur les connexions utilisateurs</a>'; | ||
130 | + echo '</td></tr>'; | ||
131 | + } | ||
132 | + | ||
126 | echo $TABLE_END; | 133 | echo $TABLE_END; |
127 | 134 | ||
128 | 135 |
src/Template/Pages/tools.ctp
@@ -52,7 +52,7 @@ $no_limit_mode = $no_limit_mode; | @@ -52,7 +52,7 @@ $no_limit_mode = $no_limit_mode; | ||
52 | 52 | ||
53 | 53 | ||
54 | 54 | ||
55 | - // - Page configuration | 55 | + // - Page configuration Générale |
56 | //if ($role == 'Super Administrateur') : | 56 | //if ($role == 'Super Administrateur') : |
57 | if ($USER_IS_SUPERADMIN) | 57 | if ($USER_IS_SUPERADMIN) |
58 | $this->MyHelper->echoMenuItemWithIcon("config.png", "Configuration générale", 'configurations','view'); | 58 | $this->MyHelper->echoMenuItemWithIcon("config.png", "Configuration générale", 'configurations','view'); |
@@ -66,7 +66,13 @@ $no_limit_mode = $no_limit_mode; | @@ -66,7 +66,13 @@ $no_limit_mode = $no_limit_mode; | ||
66 | echo '</td></tr>'; | 66 | echo '</td></tr>'; |
67 | */ | 67 | */ |
68 | //endif; | 68 | //endif; |
69 | - | 69 | + |
70 | + // - Page configuration des champs obligatoires et readonly | ||
71 | + if ($USER_IS_ADMIN_OR_MORE) | ||
72 | + $this->MyHelper->echoMenuItemWithIcon("config.png", "Configuration des champs obligatoires et readonly", 'configuration-fields','index'); | ||
73 | + | ||
74 | + | ||
75 | + // Configuration des listes | ||
70 | if ($USER_IS_ADMIN_OR_MORE) | 76 | if ($USER_IS_ADMIN_OR_MORE) |
71 | $this->MyHelper->echoMenuItemWithIcon("config2.png", "Gérer le contenu variable de l'application", 'pages','tools_sm'); | 77 | $this->MyHelper->echoMenuItemWithIcon("config2.png", "Gérer le contenu variable de l'application", 'pages','tools_sm'); |
72 | 78 |
src/View/Helper/MyHelperHelper.php
@@ -203,7 +203,9 @@ class MyHelperHelper extends Helper { | @@ -203,7 +203,9 @@ class MyHelperHelper extends Helper { | ||
203 | public function echoActionButton ( | 203 | public function echoActionButton ( |
204 | $icon_class, $buttonStyle, $title, | 204 | $icon_class, $buttonStyle, $title, |
205 | $action, $id, $controller=null, // si controleur null =>controleur par défaut | 205 | $action, $id, $controller=null, // si controleur null =>controleur par défaut |
206 | - $other_args=[], $tip='', $confirmMessage='', $moreButtonStyle='' | 206 | + $other_args=[], $tip='', |
207 | + $confirmMessage='', $moreButtonStyle='', | ||
208 | + $with_confirm=false | ||
207 | ) { | 209 | ) { |
208 | 210 | ||
209 | //if ($controller=='') $controller='materiels'; | 211 | //if ($controller=='') $controller='materiels'; |
@@ -212,28 +214,67 @@ class MyHelperHelper extends Helper { | @@ -212,28 +214,67 @@ class MyHelperHelper extends Helper { | ||
212 | $controllerArgs['action'] = $action; | 214 | $controllerArgs['action'] = $action; |
213 | $controllerArgs[] = $id; | 215 | $controllerArgs[] = $id; |
214 | foreach ($other_args as $other_arg) $controllerArgs[] = $other_arg; | 216 | foreach ($other_args as $other_arg) $controllerArgs[] = $other_arg; |
215 | - echo $this->Html->link( | ||
216 | - __("<i class=$icon_class></i>$title"), | ||
217 | - $controllerArgs, | ||
218 | - /* | ||
219 | - [ | ||
220 | - 'controller' => $controller, | ||
221 | - 'action' => $action, | ||
222 | - $id, | ||
223 | - $other_args | ||
224 | - ], | ||
225 | - */ | ||
226 | - [ | ||
227 | - 'title' => $tip, | ||
228 | - 'escape' => false, | ||
229 | - 'onclick' => 'return true;', | ||
230 | - //'style' => 'margin-right: 10px'.$moreButtonStyle, | ||
231 | - 'style' => $buttonStyle, | ||
232 | - 'confirm' => $confirmMessage | ||
233 | - ] | 217 | + |
218 | + // Avec confirmation (avant de déclencher l'action) | ||
219 | + if ($with_confirm) { | ||
220 | + if (!$confirmMessage) $confirmMessage = __("Êtes-vous sur de vouloir $title cette entité ?"); | ||
221 | + echo $this->Form->postLink(__("<i class='$icon_class'></i>$title"), | ||
222 | + $controllerArgs, | ||
223 | + [ | ||
224 | + 'title' => $title, | ||
225 | + //'style' => $buttonStyle, | ||
226 | + 'style' => 'margin-left: 10px', | ||
227 | + 'escape' => false, | ||
228 | + 'confirm' => $confirmMessage, | ||
229 | + //'confirm' => $confirmMessage | ||
230 | + //'confirm' => __("Êtes-vous sur de vouloir $title cette entité ?"), | ||
231 | + //'confirm' => __('Êtes-vous sur de vouloir supprimer # {0}?', $suivi->id) | ||
232 | + ]); | ||
233 | + } | ||
234 | + | ||
235 | + // Sans confirmation (action directe) | ||
236 | + else { | ||
237 | + echo $this->Html->link( | ||
238 | + __("<i class=$icon_class></i>$title"), | ||
239 | + $controllerArgs, | ||
240 | + /* | ||
241 | + [ | ||
242 | + 'controller' => $controller, | ||
243 | + 'action' => $action, | ||
244 | + $id, | ||
245 | + $other_args | ||
246 | + ], | ||
247 | + */ | ||
248 | + [ | ||
249 | + 'title' => $tip, | ||
250 | + 'escape' => false, | ||
251 | + 'onclick' => 'return true;', | ||
252 | + //'style' => 'margin-right: 10px'.$moreButtonStyle, | ||
253 | + 'style' => $buttonStyle, | ||
254 | + //'confirm' => $confirmMessage ? $confirmMessage : $tip, | ||
255 | + ] | ||
256 | + ); | ||
257 | + } | ||
258 | + | ||
259 | + } | ||
260 | + | ||
261 | + | ||
262 | + public function echoEditButton () { $this->echoButtonForAction('icon-pencil', 'edit', 'Editer', 'Modifier'); } | ||
263 | + | ||
264 | + public function echoButtonForAction ($icon_class, $action, $label, $tooltip, $with_confirm=false) { | ||
265 | + //$icon_class = 'icon-pencil'; | ||
266 | + $buttonStyle = 'margin-right: 10px'; | ||
267 | + echo '<div id="boutons" class="actions" style="margin-bottom:20px; width:100%; float:none; padding:5px 0;">'; | ||
268 | + $this->echoActionButton($icon_class, $buttonStyle, | ||
269 | + " $label", $action, null, null, [], $tooltip, | ||
270 | + '', '', | ||
271 | + $with_confirm | ||
234 | ); | 272 | ); |
273 | + echo "</div>"; | ||
235 | } | 274 | } |
236 | 275 | ||
276 | + | ||
277 | + | ||
237 | public function echoDeleteButton ( | 278 | public function echoDeleteButton ( |
238 | $title, | 279 | $title, |
239 | $id, $controller=null, // si controleur null =>controleur par défaut | 280 | $id, $controller=null, // si controleur null =>controleur par défaut |