Commit 997b1d412d96597b784a63809bfdf472aea47102
1 parent
42151650
Exists in
master
and in
1 other branch
/pages/stats migré dans /materiels/stats et transformé en simple alias
- et aussi bugfix pour IRAP seulement (vieux mysql et vieux php5 !) v5.4.1-3.7.9
Showing
4 changed files
with
450 additions
and
53 deletions
Show diff stats
CHANGELOG
@@ -13,6 +13,12 @@ CHANGEMENTS | @@ -13,6 +13,12 @@ CHANGEMENTS | ||
13 | 13 | ||
14 | 14 | ||
15 | ------- | 15 | ------- |
16 | +29/11/2021 NEWS#7 (v5.4) : | ||
17 | + | ||
18 | +- Partitionnement possible des matériels par site | ||
19 | + | ||
20 | + | ||
21 | +------- | ||
16 | 22/11/2021 NEWS#6 (v5.3.4) : | 22 | 22/11/2021 NEWS#6 (v5.3.4) : |
17 | 23 | ||
18 | - Champs obligatoires, modifiables, et readonly, désormais configurables via page web | 24 | - Champs obligatoires, modifiables, et readonly, désormais configurables via page web |
@@ -367,8 +373,6 @@ Commencer à implémenter le nouveau workflow v5 : | @@ -367,8 +373,6 @@ Commencer à implémenter le nouveau workflow v5 : | ||
367 | *) | 373 | *) |
368 | Relance auto lors de suivis périodiques | 374 | Relance auto lors de suivis périodiques |
369 | 375 | ||
370 | - *) Validation multiple ne marche plus | ||
371 | - | ||
372 | *) DOMPDF : pb Qrcode absent sur fiche pdf (mais présent sur page web), alors que le QrCode est bien généré et que le chemin dans le pdf est OK !!! | 376 | *) DOMPDF : pb Qrcode absent sur fiche pdf (mais présent sur page web), alors que le QrCode est bien généré et que le chemin dans le pdf est OK !!! |
373 | Par contre, ok avec FPDF | 377 | Par contre, ok avec FPDF |
374 | 378 | ||
@@ -503,26 +507,10 @@ Warning (2): Cannot modify header information - headers already sent by (output | @@ -503,26 +507,10 @@ Warning (2): Cannot modify header information - headers already sent by (output | ||
503 | TODO : | 507 | TODO : |
504 | 508 | ||
505 | - besoin IP2I/LMA : | 509 | - besoin IP2I/LMA : |
506 | -=> restreindre l’accès de certains équipements du LMA aux utilisateurs du LMA seulement et qu'ils ne soient pas visibles ou consultables par tous les utilisateurs IP2I | ||
507 | -=> Implémentation possible : | ||
508 | -2 possibilités : | ||
509 | - - Définir LMA dans la liste des "Sites" => mais ça correspond pas vraiment à la notion de site (lieu géographique) | ||
510 | - - Ajouter une nouvelle notion de "Département" | ||
511 | -- Associer les matériels sensibles à ce Site (ou Dépt), et cocher la case "materiel sensible" | ||
512 | -- Associer les utilisateurs du LMA à ce Site (ou Dépt) | ||
513 | -=> Régle : les matériels sensibles ne sont vus que par les utilisateurs du même Site (ou Dépt) (ici LMA) : | ||
514 | - pour materiels/view(/edit/delete) => le user courant ne peut pas voir un materiel "sensible" qui n'est pas du même Site (Dépt) que lui | 510 | - pour materiels/view(/edit/delete) => le user courant ne peut pas voir un materiel "sensible" qui n'est pas du même Site (Dépt) que lui |
515 | - pour materiels/index et /find et /export => il faut exclure les matos "sensibles" qui ne sont pas du même site que le user courant | 511 | - pour materiels/index et /find et /export => il faut exclure les matos "sensibles" qui ne sont pas du même site que le user courant |
516 | - materiels/index : on peut ajouter un filtre "Site" (et Dépt), et un filtre "tous/matos sensible/matos non sensible" | 512 | - materiels/index : on peut ajouter un filtre "Site" (et Dépt), et un filtre "tous/matos sensible/matos non sensible" |
517 | 513 | ||
518 | -- add_or_edit() générique | ||
519 | - | ||
520 | -- fusionner elem/button_add_edit et MyHelper echoActionButton... | ||
521 | -(ne garder que elem/) | ||
522 | -- séparer elem/button_add, button_edit, button_delete, et button_tout_court (générique) | ||
523 | - | ||
524 | -- short_role AppController ligne 819 => généraliser | ||
525 | - | ||
526 | - prévoir une alerte quand on save un champ qui n'est pas dans la BD (genre resp_credit...) | 514 | - prévoir une alerte quand on save un champ qui n'est pas dans la BD (genre resp_credit...) |
527 | 515 | ||
528 | - gérer les liens url automatiquement dans champ description (rendre cliquable) | 516 | - gérer les liens url automatiquement dans champ description (rendre cliquable) |
@@ -535,26 +523,30 @@ TODO : | @@ -535,26 +523,30 @@ TODO : | ||
535 | 523 | ||
536 | 524 | ||
537 | 525 | ||
526 | +- GENERICITÉ & REFACTORISATION : | ||
538 | 527 | ||
528 | + - add_or_edit() générique | ||
529 | + | ||
530 | + - fusionner elem/button_add_edit et MyHelper echoActionButton... | ||
531 | + (ne garder que elem/) | ||
532 | + - séparer elem/button_add, button_edit, button_delete, et button_tout_court (générique) | ||
539 | 533 | ||
534 | + - short_role AppController ligne 819 => généraliser | ||
540 | 535 | ||
536 | + - emprunts/index generique | ||
537 | + - documents/index generique | ||
541 | 538 | ||
539 | + - ProjetsController minimaliste, doit juste étendre AppController avec un minimum de changement | ||
542 | 540 | ||
541 | + - fusionner groupe thematique et metier (et projet ?) : | ||
542 | + => faire hériter les Controller et les Table d'une meme superclasse GroupController et GroupTable | ||
543 | + => avoir un seul template | ||
544 | + => c'est vraiment stupide d'avoir 2 classes qui font la meme chose... | ||
543 | 545 | ||
544 | -- emprunts/index generique | ||
545 | -- documents/index generique | ||
546 | - | ||
547 | -- ProjetsController minimaliste, doit juste étendre AppController avec un minimum de changement | ||
548 | - | ||
549 | -- add_edit generic | 546 | + - 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) | ||
550 | 548 | ||
551 | -- fusionner groupe thematique et metier (et projet ?) : | ||
552 | - => faire hériter les Controller et les Table d'une meme superclasse GroupController et GroupTable | ||
553 | - => avoir un seul template | ||
554 | - => c'est vraiment stupide d'avoir 2 classes qui font la meme chose... | ||
555 | 549 | ||
556 | -- Utiliser les vues "index" des entités associées pour la vue "view" de materiel (et suivi) : | ||
557 | - => éviter la redondance, le contenu est pratiquement le meme (???, sauf que les colonnes ne sont pas triables) | ||
558 | 550 | ||
559 | - Bien préciser quels sont les champs obligatoires avec une asterisque (et pour chaque LOT) | 551 | - Bien préciser quels sont les champs obligatoires avec une asterisque (et pour chaque LOT) |
560 | 552 | ||
@@ -578,13 +570,6 @@ Vues génériques (index et view) : | @@ -578,13 +570,6 @@ Vues génériques (index et view) : | ||
578 | - Suivis.statut => "en cours" ou "à terminer" => à calculer auto | 570 | - Suivis.statut => "en cours" ou "à terminer" => à calculer auto |
579 | 571 | ||
580 | 572 | ||
581 | - *) | ||
582 | - Rendre modifiable la config via page web "Gérer les champs obligatoires" | ||
583 | - - OFF_nom_du_champ : 'libellé' | ||
584 | - - Restaurer la config par défaut | ||
585 | - - Réactiver une variable : OFF_nom_du_champ => nom_du_champ | ||
586 | - | ||
587 | - | ||
588 | saisir les personnes du gt2i et de tous les groupes... | 573 | saisir les personnes du gt2i et de tous les groupes... |
589 | 574 | ||
590 | groupe.users associés : ajouter "(responsable)" when relevant | 575 | groupe.users associés : ajouter "(responsable)" when relevant |
@@ -593,21 +578,12 @@ comment faire un tri sur la dernière colonne des stats (connexDurAvg) ? | @@ -593,21 +578,12 @@ comment faire un tri sur la dernière colonne des stats (connexDurAvg) ? | ||
593 | 578 | ||
594 | erreur download depuis page documents/ (ou depuis vue du matériel) sur inventirap : erreur 404 (action impossible) | 579 | erreur download depuis page documents/ (ou depuis vue du matériel) sur inventirap : erreur 404 (action impossible) |
595 | 580 | ||
596 | -TODO config fields : | ||
597 | -- réadapter lecture config à new file format | ||
598 | -- compléter le fichier config avec tous les champs possibles à chaque lot !!! | ||
599 | -- fichier read-write par web server | ||
600 | -- ./UPDATE cral et ip2i + new config file | ||
601 | -- pub | ||
602 | -- soigner la présentation du form (peu lisible now) | ||
603 | - | ||
604 | 581 | ||
605 | - - (b) Bugfix fournisseur perdu (et champ vide qui n'est plus modifiable !) après validation du matos | 582 | +- (b) Bugfix fournisseur perdu (et champ vide qui n'est plus modifiable !) après validation du matos |
606 | (quand il manque un champ pour valider), et pourtant bien enregistré dans listes des fournisseurs | 583 | (quand il manque un champ pour valider), et pourtant bien enregistré dans listes des fournisseurs |
607 | 584 | ||
608 | 585 | ||
609 | 586 | ||
610 | -config + jolie : fieldset dépliable et joli (voir echoSectionStart() de MyHelperHelper) | ||
611 | 587 | ||
612 | Utiliser les champs 'comment' de la config pour les labels des champs dans materiels/view et /add_edit | 588 | Utiliser les champs 'comment' de la config pour les labels des champs dans materiels/view et /add_edit |
613 | 589 | ||
@@ -619,9 +595,16 @@ Ne pas autoriser la commande via url si le bouton order est désactivé dans la | @@ -619,9 +595,16 @@ Ne pas autoriser la commande via url si le bouton order est désactivé dans la | ||
619 | ... | 595 | ... |
620 | 596 | ||
621 | 597 | ||
598 | +- Quelle est cette action ? le mail est un peu court... (ajout par copie ?) | ||
599 | +Titre "Ajout de matériel(s)" | ||
600 | +Nathalie Oziol a ajouté des matériels (action 'add') | ||
601 | +Vous recevez ce message car vous êtes concerné(e) par cette action effectuée sur l'inventaire des matériels du laboratoire | ||
602 | +(vous êtes l'utilisateur du matériel, ou bien le gestionnaire, ou encore le responsable thématique, métier ou projet) | ||
603 | +(ou alors, vous êtes dans la liste mail spécifique gérée via la page de configuration du logiciel LabInvent). | ||
604 | + | ||
605 | + | ||
622 | 606 | ||
623 | Gestion multi-sites : | 607 | Gestion multi-sites : |
624 | -- matos.index : doit enlever les matos "sensibles" et qui ont un site différent du user | ||
625 | - matos.view : interdit si matos "sensible" a un site différent du user | 608 | - matos.view : interdit si matos "sensible" a un site différent du user |
626 | - find() : par défaut, enlever les matos "sensibles" et qui ont un site différent du user | 609 | - find() : par défaut, enlever les matos "sensibles" et qui ont un site différent du user |
627 | - gestionnaires (admin) (et superadmin) continuent d'avoir accès à tout | 610 | - gestionnaires (admin) (et superadmin) continuent d'avoir accès à tout |
@@ -630,6 +613,11 @@ Gestion multi-sites : | @@ -630,6 +613,11 @@ Gestion multi-sites : | ||
630 | ======= CHANGES ======= | 613 | ======= CHANGES ======= |
631 | 614 | ||
632 | ------- | 615 | ------- |
616 | +29/11/2021 v5.4.1-3.7.9 | ||
617 | + - (i) /pages/stats migré dans /materiels/stats et transformé en simple alias | ||
618 | + - (b) bugfix pour IRAP seulement (vieux mysql pourri et vieux php5 pourri !!!) | ||
619 | + | ||
620 | +------- | ||
633 | 29/11/2021 v5.4.0-3.7.9 | 621 | 29/11/2021 v5.4.0-3.7.9 |
634 | - (e) Partitionnement des matériels par site opérationnel (multi-sites) => liste des matériels filtrée | 622 | - (e) Partitionnement des matériels par site opérationnel (multi-sites) => liste des matériels filtrée |
635 | - (b) Bugfix action sur plusieurs matos : | 623 | - (b) Bugfix action sur plusieurs matos : |
README.md
@@ -53,7 +53,7 @@ Logiciel testé et validé sur les configurations suivantes : | @@ -53,7 +53,7 @@ Logiciel testé et validé sur les configurations suivantes : | ||
53 | -------------------------------------------------------------------------------------------- | 53 | -------------------------------------------------------------------------------------------- |
54 | 54 | ||
55 | Date: 29/11/2021 | 55 | Date: 29/11/2021 |
56 | -Version: v5.4.0-3.7.9 | 56 | +Version: v5.4.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) |
src/Controller/MaterielsController.php
@@ -457,6 +457,9 @@ class MaterielsController extends AppController { | @@ -457,6 +457,9 @@ class MaterielsController extends AppController { | ||
457 | * | 457 | * |
458 | */ | 458 | */ |
459 | 459 | ||
460 | + // - Action 'stats' (bugfix) => autorisée à tous | ||
461 | + $this->setAuthorizationsForAction('stats', 0); | ||
462 | + | ||
460 | // - Action 'execSqlRequestForBugfix' (bugfix) => autorisé seulement à superadmin | 463 | // - Action 'execSqlRequestForBugfix' (bugfix) => autorisé seulement à superadmin |
461 | $this->setAuthorizationsForAction('execSqlRequestForBugfix (bugfix)', -1, [ | 464 | $this->setAuthorizationsForAction('execSqlRequestForBugfix (bugfix)', -1, [ |
462 | 'super' => 0, | 465 | 'super' => 0, |
@@ -1413,7 +1416,11 @@ class MaterielsController extends AppController { | @@ -1413,7 +1416,11 @@ class MaterielsController extends AppController { | ||
1413 | //debug($current_user->nom); | 1416 | //debug($current_user->nom); |
1414 | //debug($current_user->site_id); | 1417 | //debug($current_user->site_id); |
1415 | //debug($materiels); exit; | 1418 | //debug($materiels); exit; |
1416 | - $materiels = $materiels->find('filteredForUserSite', ['user_site_id' => $current_user->site_id]); | 1419 | + if ($this->confLabinvent->labNameShort) { |
1420 | + $labshortname = $this->confLabinvent->labNameShort; | ||
1421 | + if ($labshortname != 'IRAP') | ||
1422 | + $materiels = $materiels->find('filteredForUserSite', ['user_site_id' => $current_user->site_id]); | ||
1423 | + } | ||
1417 | //$materiels = $materiels->find('filteredForUserSite', ['user_site_id' => null]); | 1424 | //$materiels = $materiels->find('filteredForUserSite', ['user_site_id' => null]); |
1418 | //foreach ($materiels as $m) debug($m->id); | 1425 | //foreach ($materiels as $m) debug($m->id); |
1419 | //debug($materiels->count()); | 1426 | //debug($materiels->count()); |
@@ -3315,6 +3322,404 @@ class MaterielsController extends AppController { | @@ -3315,6 +3322,404 @@ class MaterielsController extends AppController { | ||
3315 | // $this->sendEmail($this->Materiels->get($id)); | 3322 | // $this->sendEmail($this->Materiels->get($id)); |
3316 | } | 3323 | } |
3317 | 3324 | ||
3325 | + public function stats() { | ||
3326 | + | ||
3327 | + /* | ||
3328 | + return $this->redirect([ | ||
3329 | + 'controller' => 'pages', | ||
3330 | + 'action' => 'stats', | ||
3331 | + ]); | ||
3332 | + */ | ||
3333 | + | ||
3334 | + // créer des FAKE DATA pour tester la fonctionnalité ? | ||
3335 | + $TEST = true; | ||
3336 | + $TEST = false; | ||
3337 | + | ||
3338 | + // Nb années demandées par l'utilisateur | ||
3339 | + $nbyears = $this->request->getQuery('nbyears'); | ||
3340 | + | ||
3341 | + // Initialisation des variables nécessaires | ||
3342 | + // - Données Totales (complètes) (tronquées à $nbyears) | ||
3343 | + $tot = [ | ||
3344 | + 'CREATED' => (int) 1, | ||
3345 | + 'VALIDATED' => (int) 0, | ||
3346 | + 'TOBEARCHIVED' => (int) 0, | ||
3347 | + 'ARCHIVED' => (int) 0, | ||
3348 | + 'suivis' => (int) 0, | ||
3349 | + 'prets' => (int) 0 | ||
3350 | + ]; | ||
3351 | + // - Donées Moyennes | ||
3352 | + $avg = [ | ||
3353 | + 'CREATED' => (int) 1, | ||
3354 | + 'VALIDATED' => (int) 0, | ||
3355 | + 'TOBEARCHIVED' => (int) 0, | ||
3356 | + 'ARCHIVED' => (int) 0, | ||
3357 | + 'suivis' => (int) 0, | ||
3358 | + 'prets' => (int) 0 | ||
3359 | + ]; | ||
3360 | + // - Année en cours | ||
3361 | + $now = new \DateTime('now'); | ||
3362 | + //debug($now); | ||
3363 | + // 2020 en 2020 | ||
3364 | + $current_year = (int) $now->format('Y'); | ||
3365 | + // - Données par Année | ||
3366 | + $years = | ||
3367 | + [ | ||
3368 | + $current_year => [ | ||
3369 | + 'CREATED' => (int) 1, | ||
3370 | + 'VALIDATED' => (int) 0, | ||
3371 | + 'TOBEARCHIVED' => (int) 0, | ||
3372 | + 'ARCHIVED' => (int) 0, | ||
3373 | + 'suivis' => (int) 0, | ||
3374 | + 'prets' => (int) 0 | ||
3375 | + ] | ||
3376 | + ]; | ||
3377 | + | ||
3378 | + // Tables | ||
3379 | + $materiels = TableRegistry::getTableLocator()->get('Materiels'); | ||
3380 | + $suivis = TableRegistry::getTableLocator()->get('Suivis'); | ||
3381 | + $prets = TableRegistry::getTableLocator()->get('Emprunts'); | ||
3382 | + $associated_entities = ['suivis','prets']; | ||
3383 | + $fk = 'materiel_id'; | ||
3384 | + | ||
3385 | + // Tous les matos qui ont une date d'achat non nulle | ||
3386 | + $all_matos = $materiels->find()->where(['year(date_acquisition) >' => 0]); | ||
3387 | + | ||
3388 | + // On ne fait pas de stats s'il n'y a aucun matériel dans la BD | ||
3389 | + if ($all_matos->count() == 0) { | ||
3390 | + $year_min = $current_year; | ||
3391 | + //$nbyears = 0; | ||
3392 | + $this->set(compact('current_year', 'year_min', 'nbyears', 'tot', 'avg', 'years')); | ||
3393 | + return; | ||
3394 | + } | ||
3395 | + | ||
3396 | + // - Année min | ||
3397 | + //$year_min = $materiels->find()->min(['year(date_acquisition)']); | ||
3398 | + //$matos_year_min = $materiels->find()->where(['year(date_acquisition) >' => 0]) | ||
3399 | + $matos_year_min = $all_matos->cleanCopy()->min(function($matos) { | ||
3400 | + return $matos->date_acquisition->format('Y'); | ||
3401 | + }); | ||
3402 | + $year_min = (int) $matos_year_min->date_acquisition->format('Y'); | ||
3403 | + | ||
3404 | + // - Nb années au total : au moins 1 | ||
3405 | + $nbyears_max = $current_year - $year_min + 1; | ||
3406 | + | ||
3407 | + // $nbyears demandé par l'utilisateur, par défaut TOUTES | ||
3408 | + $nbyears = ( is_numeric($nbyears) && $nbyears>0 ) ? round($nbyears) : $nbyears_max; | ||
3409 | + //debug($nbyears); | ||
3410 | + | ||
3411 | + // - Nb annnées à traiter (entre 1 et $nbyears_max) | ||
3412 | + // ($nbyears=null si pas passé en paramètre) | ||
3413 | + // ($nbyears='' si passé en paramètre mais sans valeur '?nbyears=') | ||
3414 | + //$nbyears = $nbyears ? abs((int)$nbyears) : $nbyears_max; | ||
3415 | + //debug($nbyears); | ||
3416 | + $nbyears = min($nbyears,$nbyears_max); | ||
3417 | + //debug($nbyears); | ||
3418 | + //debug($nbyears); | ||
3419 | + // Si on est au max (avec max>2), on enlève la 1ère et la dernière années (car a priori incomplètes) | ||
3420 | + //sif ($nbyears==$nbyears_max && $nbyears>2) $nbyears -= 2; | ||
3421 | + // Nouvelle année min | ||
3422 | + $year_min = $current_year-$nbyears + 1; | ||
3423 | + | ||
3424 | + // Nouveau $all_matos, en tronquant à $nbyears | ||
3425 | + $all_matos = $materiels->find() | ||
3426 | + ->where(['year(date_acquisition) <=' => $current_year]) | ||
3427 | + ->where(['year(date_acquisition) >=' => $year_min]); | ||
3428 | + $all_matos_ids = $all_matos->cleanCopy()->select(['id']); | ||
3429 | + | ||
3430 | + /* | ||
3431 | + $statuses = [ | ||
3432 | + 'CREATED' => 'created', | ||
3433 | + 'VALIDATED' => 'date_validated', | ||
3434 | + 'ARCHIVED' => 'date_archived' | ||
3435 | + ]; | ||
3436 | + */ | ||
3437 | + $statuses = [ 'CREATED', 'VALIDATED', 'TOBEARCHIVED', 'ARCHIVED' ]; | ||
3438 | + | ||
3439 | + // - tot : Données Totales (complètes) (tronquées à $nbyears) | ||
3440 | + foreach ($statuses as $status) { | ||
3441 | + $all_matos_copy = $all_matos->cleanCopy(); | ||
3442 | + // Tous les matos qui ont une date d'achat non nulle | ||
3443 | + if ($status != 'CREATED') $all_matos_copy->where(['status' => $status]); | ||
3444 | + $tot[$status] = $all_matos_copy->count(); | ||
3445 | + } | ||
3446 | + // Suivis et Prets | ||
3447 | + // Nb materiels qui ont des suivis (i.e. qui ont au moins 1 suivi) | ||
3448 | + foreach ($associated_entities as $e) { | ||
3449 | + //$nb_matos_suivis = $suivis->find() | ||
3450 | + $tot[$e] = $$e->find() | ||
3451 | + // materiel_id not null | ||
3452 | + ->where(["$fk >" => 0]) | ||
3453 | + ->select([$fk]) | ||
3454 | + ->distinct([$fk]) | ||
3455 | + ->where(["$fk IN" => $all_matos_ids]) | ||
3456 | + ->count(); | ||
3457 | + } | ||
3458 | + | ||
3459 | + /* | ||
3460 | + // - tot2 : Données Totales Partielles (= tot sauf 1ère et dernière années) | ||
3461 | + $all_matos2 = $materiels | ||
3462 | + ->find() | ||
3463 | + ->where(['year(date_acquisition) <' => $current_year]) | ||
3464 | + ->where(['year(date_acquisition) >' => $current_year-$nbyears]); | ||
3465 | + $all_matos_ids2 = $all_matos2->cleanCopy()->select(['id']); | ||
3466 | + | ||
3467 | + $tot2 = []; | ||
3468 | + foreach ($statuses as $status) { | ||
3469 | + $all_matos_copy = $all_matos2->cleanCopy(); | ||
3470 | + // Tous les matos qui ont une date d'achat non nulle | ||
3471 | + if ($status != 'CREATED') $all_matos_copy->where(['status' => $status]); | ||
3472 | + $tot2[$status] = $all_matos_copy->count(); | ||
3473 | + } | ||
3474 | + // Suivis et Prets | ||
3475 | + // Nb materiels qui sont suivis (i.e. qui ont au moins 1 suivi) | ||
3476 | + foreach ($associated_entities as $e) { | ||
3477 | + //$nb_matos_suivis = $suivis->find() | ||
3478 | + $tot2[$e] = $$e->find() | ||
3479 | + // materiel_id not null | ||
3480 | + ->where(["$fk >" => 0]) | ||
3481 | + ->select([$fk]) | ||
3482 | + ->distinct([$fk]) | ||
3483 | + ->where(["$fk IN" => $all_matos_ids2]) | ||
3484 | + ->count(); | ||
3485 | + } | ||
3486 | + */ | ||
3487 | + | ||
3488 | + // - Donées Moyennes (avg) | ||
3489 | + /* | ||
3490 | + $avg['CREATED'] = 10; | ||
3491 | + $avg['VALIDATED'] = 7; | ||
3492 | + $avg['TOBEARCHIVED'] = 1; | ||
3493 | + $avg['ARCHIVED'] = 1; | ||
3494 | + */ | ||
3495 | + foreach ($statuses as $status) { | ||
3496 | + $avg[$status] = round($tot[$status]/$nbyears, 1); | ||
3497 | + /* | ||
3498 | + * (EP) | ||
3499 | + * J'obtiens pas le meme resultat avec cette methode... | ||
3500 | + * Peut-être que ca compte pas les années où il n'y a rien (0) | ||
3501 | + */ | ||
3502 | + /* | ||
3503 | + //$all_matos = $materiels->find(); | ||
3504 | + //$all_matos = $materiels->find()->where(['year(date_acquisition) >' => 0]); | ||
3505 | + //->groupBy('year(date_acquisition)'); | ||
3506 | + $all_matos_copy = $all_matos->cleanCopy(); | ||
3507 | + if ($status != 'CREATED') $all_matos_copy->where(['status' => $status]); | ||
3508 | + $avg[$status] = $all_matos_copy | ||
3509 | + //->groupBy('year(date_acquisition)'); | ||
3510 | + ->countBy(function($matos) { | ||
3511 | + return $matos->date_acquisition->format('Y'); | ||
3512 | + }) | ||
3513 | + ->avg(); | ||
3514 | + //->toList(); | ||
3515 | + //->toArray(); | ||
3516 | + //->count(); | ||
3517 | + $avg[$status] = round($avg[$status]); | ||
3518 | + */ | ||
3519 | + } | ||
3520 | + // Suivis et Prets | ||
3521 | + // Nb materiels qui sont suivis (i.e. qui ont au moins 1 suivi) | ||
3522 | + foreach ($associated_entities as $e) { | ||
3523 | + $avg[$e] = round($tot[$e]/$nbyears, 1); | ||
3524 | + /* | ||
3525 | + $nb_matos_having_entity = $$e->find() | ||
3526 | + // materiel_id not null | ||
3527 | + ->where(["$fk >" => 0]) | ||
3528 | + ->select([ | ||
3529 | + 'year' => 'YEAR(created)' | ||
3530 | + ]) | ||
3531 | + ->group('year') | ||
3532 | + ->toArray(); | ||
3533 | + | ||
3534 | + //->groupBy(function($entity) { | ||
3535 | + ->group(function($entity) { | ||
3536 | + return $entity->created->format('Y'); | ||
3537 | + }) | ||
3538 | + ->distinct([$fk]) | ||
3539 | + ->count() | ||
3540 | + ->avg(); | ||
3541 | + $avg[$e] = $nb_matos_having_entity; | ||
3542 | + */ | ||
3543 | + //debug($nb_matos_having_entity); | ||
3544 | + } | ||
3545 | + | ||
3546 | + | ||
3547 | + // - Données par Année | ||
3548 | + $all_matos = $materiels->find(); | ||
3549 | + for ($y=$current_year ; $y>=$year_min ; $y--) { | ||
3550 | + ////debug($y); | ||
3551 | + $all_matos_for_year = $all_matos->cleanCopy()->where(['year(date_acquisition)' => $y]); | ||
3552 | + ////debug($all_matos_for_year->count()); | ||
3553 | + // - statut par année | ||
3554 | + try { | ||
3555 | + foreach ($statuses as $status) { | ||
3556 | + /* | ||
3557 | + $all_matos_for_year = $materiels->find(); | ||
3558 | + ->where(['year(date_acquisition)' => $y]); | ||
3559 | + $all_matos_for_year = $all_matos->cleanCopy()->where(['year(date_acquisition)' => $y]); | ||
3560 | + */ | ||
3561 | + $all_matos_for_year_and_status = $all_matos_for_year->cleanCopy(); | ||
3562 | + if ($status != 'CREATED') $all_matos_for_year_and_status->where(['status' => $status]); | ||
3563 | + $years[$y][$status] = $all_matos_for_year_and_status->count(); | ||
3564 | + } | ||
3565 | + } catch (\PDOException $e) { | ||
3566 | + debug("Mauvais format de requete SQL (PagesController/stats statuses), Exception PDO générée !"); | ||
3567 | + exit; | ||
3568 | + } | ||
3569 | + ////debug($years); | ||
3570 | + // Suivis et Prets, par année | ||
3571 | + $all_matos_suivis_for_year = $all_matos_for_year->cleanCopy(); | ||
3572 | + foreach ($associated_entities as $e) | ||
3573 | + try { | ||
3574 | + ////debug($e); | ||
3575 | + //debug($$e->find()->count()); | ||
3576 | + /* | ||
3577 | + * SQL equivalent : à tester... | ||
3578 | + * | ||
3579 | + * SELECT COUNT(DISTINCT(suivis.materiel_id)) FROM suivis LEFT JOIN materiels | ||
3580 | + * ON suivis.materiel_id = materiels.id | ||
3581 | + * WHERE YEAR(materiels.date_acquisition) = $y | ||
3582 | + * | ||
3583 | + * $years[$y]['suivis'] = $suivis->find()... | ||
3584 | + * puis | ||
3585 | + * $years[$y]['prets'] = $prets->find()... | ||
3586 | + */ | ||
3587 | + $years[$y][$e] = $$e | ||
3588 | + // Tous les suivis/emprunts... | ||
3589 | + ->find() | ||
3590 | + // ... et leur materiel associé... | ||
3591 | + ->leftJoinWith('Materiels') | ||
3592 | + // ... LEFT JOIN ON (suivis.materiel_id = materiels.id) ... // ou emprunts.materiel_id | ||
3593 | + //->enableAutoFields(true) | ||
3594 | + // ... (uniquement les materiels de l'année $y) ... | ||
3595 | + ->where(['year(date_acquisition)' => $y]) | ||
3596 | + // ... en ne gardant qu'1 seul suivi/emprunt par materiel (meme si ce materiel en a plusieurs) ... | ||
3597 | + ->distinct(['materiel_id']) | ||
3598 | + // ... et enfin, on compte le nombre de suivis/emprunts (total pour l'année $y) | ||
3599 | + ->count(); | ||
3600 | + //->toArray(); | ||
3601 | + //$all_matos_for_year | ||
3602 | + //->contain(['Suivis']) | ||
3603 | + //->select(['id', 'count_suivis => count(suivis)']) | ||
3604 | + //->where(['count_suivis >' => 0]) | ||
3605 | + //->count(); | ||
3606 | + } catch (\PDOException $ex) { | ||
3607 | + debug("Mauvais format de requete SQL (PagesController/stats suivis/prets), Exception PDO générée !"); | ||
3608 | + debug($ex); | ||
3609 | + exit; | ||
3610 | + } | ||
3611 | + //debug($years[$y]['suivis']); | ||
3612 | + //$years[$y]['suivis'] = 3; | ||
3613 | + //$years[$y]['prets'] = 4; | ||
3614 | + } // foreach year | ||
3615 | + //debug($years); | ||
3616 | + | ||
3617 | + // Set all variables pour la vue | ||
3618 | + //$this->set(compact('current_year', 'year_min', 'tot', 'avg', 'years', 'suivis', 'prets')); | ||
3619 | + //$this->set(compact('current_year', 'year_min', 'nbyears', 'tot', 'tot2', 'avg', 'years')); | ||
3620 | + | ||
3621 | + // FAKE DATA POUR TEST LOCAL | ||
3622 | + if ($TEST) { | ||
3623 | + | ||
3624 | + $current_year = 2021; | ||
3625 | + | ||
3626 | + $test_nb_years = 0; | ||
3627 | + $test_nb_years = 1; | ||
3628 | + $test_nb_years = 2; | ||
3629 | + $test_nb_years = 3; | ||
3630 | + | ||
3631 | + $i_year = $current_year; | ||
3632 | + $i_nbyears = 0; | ||
3633 | + | ||
3634 | + $years = []; | ||
3635 | + /* | ||
3636 | + $years[2019] = [ | ||
3637 | + 'CREATED' => (int) 27, | ||
3638 | + 'VALIDATED' => (int) 8, | ||
3639 | + 'TOBEARCHIVED' => (int) 1, | ||
3640 | + 'ARCHIVED' => (int) 1, | ||
3641 | + 'suivis' => (int) 2, | ||
3642 | + 'prets' => (int) 2 | ||
3643 | + ]; | ||
3644 | + */ | ||
3645 | + // 1 year | ||
3646 | + if ($test_nb_years > $i_nbyears) | ||
3647 | + $years[$i_year] = [ | ||
3648 | + 'CREATED' => (int) 27, | ||
3649 | + 'VALIDATED' => (int) 8, | ||
3650 | + 'TOBEARCHIVED' => (int) 1, | ||
3651 | + 'ARCHIVED' => (int) 1, | ||
3652 | + 'suivis' => (int) 2, | ||
3653 | + 'prets' => (int) 2 | ||
3654 | + ]; | ||
3655 | + // 2 years | ||
3656 | + if ($test_nb_years > $i_nbyears++) | ||
3657 | + $years[--$i_year] = [ | ||
3658 | + 'CREATED' => (int) 0, | ||
3659 | + 'VALIDATED' => (int) 0, | ||
3660 | + 'TOBEARCHIVED' => (int) 0, | ||
3661 | + 'ARCHIVED' => (int) 0, | ||
3662 | + 'suivis' => (int) 0, | ||
3663 | + 'prets' => (int) 0 | ||
3664 | + ]; | ||
3665 | + // 3 years | ||
3666 | + if ($test_nb_years > $i_nbyears++) | ||
3667 | + $years[--$i_year] = [ | ||
3668 | + 'CREATED' => (int) 27, | ||
3669 | + 'VALIDATED' => (int) 8, | ||
3670 | + 'TOBEARCHIVED' => (int) 1, | ||
3671 | + 'ARCHIVED' => (int) 1, | ||
3672 | + 'suivis' => (int) 2, | ||
3673 | + 'prets' => (int) 2 | ||
3674 | + ]; | ||
3675 | + if ($test_nb_years > $i_nbyears++) | ||
3676 | + $years[--$i_year] = [ | ||
3677 | + 'CREATED' => (int) 27, | ||
3678 | + 'VALIDATED' => (int) 8, | ||
3679 | + 'TOBEARCHIVED' => (int) 1, | ||
3680 | + 'ARCHIVED' => (int) 1, | ||
3681 | + 'suivis' => (int) 2, | ||
3682 | + 'prets' => (int) 2 | ||
3683 | + ]; | ||
3684 | + | ||
3685 | + $nbyears = count($years); | ||
3686 | + $year_min = $nbyears>0 ? min(array_keys($years)) : $current_year; | ||
3687 | + | ||
3688 | + $tot = [ | ||
3689 | + 'CREATED' => (int) 27, | ||
3690 | + 'VALIDATED' => (int) 8, | ||
3691 | + 'TOBEARCHIVED' => (int) 1, | ||
3692 | + 'ARCHIVED' => (int) 1, | ||
3693 | + 'suivis' => (int) 2, | ||
3694 | + 'prets' => (int) 2 | ||
3695 | + ]; | ||
3696 | + $avg = [ | ||
3697 | + 'CREATED' => (float) 27, | ||
3698 | + 'VALIDATED' => (float) 8, | ||
3699 | + 'TOBEARCHIVED' => (float) 1, | ||
3700 | + 'ARCHIVED' => (float) 1, | ||
3701 | + 'suivis' => (float) 2, | ||
3702 | + 'prets' => (float) 2 | ||
3703 | + ]; | ||
3704 | + | ||
3705 | + debug($current_year); | ||
3706 | + debug($year_min); | ||
3707 | + debug($years); | ||
3708 | + } // TEST DATA | ||
3709 | + | ||
3710 | + $this->set(compact('current_year', 'year_min', 'nbyears', 'tot', 'avg', 'years')); | ||
3711 | + /* | ||
3712 | + debug($tot); | ||
3713 | + //echo json_encode($avg); | ||
3714 | + debug($avg); | ||
3715 | + debug($years); | ||
3716 | + */ | ||
3717 | + | ||
3718 | + } // stats() | ||
3719 | + | ||
3720 | + | ||
3721 | + | ||
3722 | + | ||
3318 | /** | 3723 | /** |
3319 | * StatusArchived method | 3724 | * StatusArchived method |
3320 | * | 3725 | * |
src/Controller/PagesController.php
@@ -306,8 +306,12 @@ class PagesController extends AppController | @@ -306,8 +306,12 @@ class PagesController extends AppController | ||
306 | 306 | ||
307 | 307 | ||
308 | // - Page des STATISTIQUES | 308 | // - Page des STATISTIQUES |
309 | - if ($this->page=='stats') $this->page_stats_set_variables(); | ||
310 | - | 309 | + //if ($this->page=='stats') $this->page_stats_set_variables(); |
310 | + if ($this->page=='stats') return $this->redirect([ | ||
311 | + 'controller' => 'materiels', | ||
312 | + 'action' => 'stats', | ||
313 | + ]); | ||
314 | + | ||
311 | 315 | ||
312 | // - Page des OUTILS | 316 | // - Page des OUTILS |
313 | if ($this->page=='tools') { | 317 | if ($this->page=='tools') { |
@@ -333,7 +337,7 @@ class PagesController extends AppController | @@ -333,7 +337,7 @@ class PagesController extends AppController | ||
333 | 337 | ||
334 | 338 | ||
335 | 339 | ||
336 | - private function page_stats_set_variables() { | 340 | + private function OLD_page_stats_set_variables() { |
337 | 341 | ||
338 | // créer des FAKE DATA pour tester la fonctionnalité ? | 342 | // créer des FAKE DATA pour tester la fonctionnalité ? |
339 | $TEST = true; | 343 | $TEST = true; |