From 0ed158cdfff612801ae135ae62e7afaad767b6d5 Mon Sep 17 00:00:00 2001
From: Etienne Pallier
Date: Tue, 28 Jul 2020 08:06:20 +0200
Subject: [PATCH] Page "Statistiques" améliorée (menu Outils, /pages/stats) (v3.7.9.76)
---
CHANGES.txt | 8 +++++++-
README.md | 4 ++--
src/Controller/MaterielsController.php | 11 ++++-------
src/Controller/PagesController.php | 343 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------
src/Template/Emprunts/index.ctp | 17 ++++++++++++++---
src/Template/Pages/stats.ctp | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
6 files changed, 373 insertions(+), 128 deletions(-)
diff --git a/CHANGES.txt b/CHANGES.txt
index daf3ba6..0469cb3 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -15,7 +15,7 @@ CHANGEMENTS
-------
25/07/2020 NEWS#2 :
-- Nouvelle page "Statistiques" depuis le menu Outils : nombre de matériels créés, validés, archivés, en moyenne, au total, et par année
+- Nouvelle page "Statistiques" depuis le menu Outils : nombre de matériels créés, validés, archivés, suivis, et prêtés (en moyenne, au total, et par année)
- Améliorations de la page qui liste les matériels (/materiels/index) :
=> nouveaux filtres "age" et "domaine" pour afficher les matériels par domaine (informatique, électronique, ...) ou/et par tranche d'âge (par défaut "moins de 5 ans", mais aussi 5-10 ans, 10-15 ans...)
@@ -77,6 +77,12 @@ Outre ces changements, voici d'autres changements importants :
======= CHANGES =======
-------
+28/07/2020 v3.7.9.76 (EP)
+ - Page "Statistiques" améliorée (menu Outils, /pages/stats) :
+ - nombre de matériels créés, validés, archivés, suivis, et prêtés (en moyenne, au total, et par année)
+ - choix du nb de matériels à lister
+
+-------
25/07/2020 v3.7.9.72-75 (EP)
- Fiabilisation du nouveau script database/update/db-update.sh
- Try-catch avant exécution grosses requetes sql (par exemple celle pour la vue index des materiels)
diff --git a/README.md b/README.md
index 6d40952..b77000c 100644
--- a/README.md
+++ b/README.md
@@ -42,8 +42,8 @@ Logiciel testé et validé sur les configurations suivantes :
--------------------------------------------------------------------------------------------
-Date: 25/07/2020
-Version: 3.7.9.75
+Date: 28/07/2020
+Version: 3.7.9.76
HISTORIQUE DES CHANGEMENTS DE VERSION : voir le fichier CHANGES.txt (ou la page web /pages/changes)
diff --git a/src/Controller/MaterielsController.php b/src/Controller/MaterielsController.php
index 791179c..aab451d 100755
--- a/src/Controller/MaterielsController.php
+++ b/src/Controller/MaterielsController.php
@@ -766,26 +766,23 @@ class MaterielsController extends AppController {
if ($GM !== null && $GM != TableRegistry::getTableLocator()->get('GroupesMetiers')->find()
->where([
'nom =' => 'N/A'
- ])
- ->first()['id'])
+ ])->first()['id'])
$conditions = [
'Materiels.groupes_metier_id =' => $GM,
'Materiels.status !=' => 'ARCHIVED'
];
//else if ($GT !== null && $GT != TableRegistry::get('GroupesThematiques')->find()
- else if ($GT !== null && $GT != TableRegistry::getTableLocator()->get('GroupesThematiques')->find()
+ else if ($GT !== null && $GT != TableRegistry::getTableLocator()->get('GroupesThematiques')->find()
->where([
'nom =' => 'N/A'
])
- ->first()['id'])
+ ->first()['id'])
$conditions = [
'Materiels.groupes_thematique_id =' => $GT,
'Materiels.status !=' => 'ARCHIVED'
];
else
- $conditions = [
- 'Materiels.id =' => 0
- ];
+ $conditions = [ 'Materiels.id =' => 0 ];
}
$GMV = $this->request->getQuery('GMV');
diff --git a/src/Controller/PagesController.php b/src/Controller/PagesController.php
index 0a617ca..653496d 100755
--- a/src/Controller/PagesController.php
+++ b/src/Controller/PagesController.php
@@ -295,104 +295,10 @@ class PagesController extends AppController
$this->set(compact('lab_name'));
}
+
// - Page des STATISTIQUES
- if ($this->page=='stats') {
-
- // - Année en cours
- $now = new \DateTime('now');
- //debug($now);
- // 2020 en 2020
- $current_year = (int) $now->format('Y');
-
- $materiels = TableRegistry::getTableLocator()->get('Materiels');
- //debug($all_matos->count()); //3967
+ if ($this->page=='stats') $this->set_variables_for_page_stats();
- /*
- $statuses = [
- 'CREATED' => 'created',
- 'VALIDATED' => 'date_validated',
- 'ARCHIVED' => 'date_archived'
- ];
- */
- $statuses = [ 'CREATED', 'VALIDATED', 'TOBEARCHIVED', 'ARCHIVED' ];
-
- // - Donées Totales
- $tot = [];
- /*
- $tot['CREATED'] = 100;
- $tot['VALIDATED'] = 70;
- $tot['TOBEARCHIVED'] = 10;
- $tot['ARCHIVED'] = 10;
- */
- foreach ($statuses as $status) {
- //TODO: optimiser, à ne faire qu'une seule fois, et non pas à chaque tour de boucle:
- // Tous les matos qui ont une date d'achat non nulle
- $all_matos = $materiels->find()->where(['year(date_acquisition) >' => 0]);
- if ($status != 'CREATED') $all_matos->where(['status' => $status]);
- $tot[$status] = $all_matos->count();
- }
-
- // - Donées Moyennes
- $avg = [];
- /*
- $avg['CREATED'] = 10;
- $avg['VALIDATED'] = 7;
- $avg['TOBEARCHIVED'] = 1;
- $avg['ARCHIVED'] = 1;
- */
- foreach ($statuses as $status) {
- //TODO: optimiser, à ne faire qu'une seule fois, et non pas à chaque tour de boucle:
- // Tous les matos qui ont une date d'achat non nulle
- //$all_matos = $materiels->find();
- $all_matos = $materiels->find()->where(['year(date_acquisition) >' => 0]);
- //->groupBy('year(date_acquisition)');
- if ($status != 'CREATED') $all_matos->where(['status' => $status]);
- $avg[$status] = $all_matos
- //->groupBy('year(date_acquisition)');
- ->countBy(function($matos) {
- return $matos->date_acquisition->format('Y');
- })
- //->toList();
- //->toArray();
- //->count();
- ->avg();
- $avg[$status] = round($avg[$status]);
- }
- //debug($avg);
-
-
- // - Données par Année
- $years = [];
- //$year_min = $materiels->find()->min(['year(date_acquisition)']);
- $matos_year_min = $materiels->find()
- ->where(['year(date_acquisition) >' => 0])
- ->min(function($matos) {
- return $matos->date_acquisition->format('Y');
- });
- //$year_min = 2009;
- $year_min = (int) $matos_year_min->date_acquisition->format('Y');
- // TODO: Ajouter progression d'année en année (2020 = 2019 +/- 10%)
- for ($y=$current_year ; $y>=$year_min ; $y--) {
- //debug($y);
- try {
- foreach ($statuses as $status) {
- //TODO: optimiser, à ne faire qu'une seule fois, et non pas à chaque tour de boucle:
- $all_matos_for_year = $materiels
- ->find()
- ->where(['year(date_acquisition)' => $y]);
- if ($status != 'CREATED') $all_matos_for_year->where(['status' => $status]);
- $years[$y][$status] = $all_matos_for_year->count();
- }
- } catch (\PDOException $e) {
- debug("Mauvais format de requete SQL (PagesController), Exception PDO générée !");
- exit;
- }
- }
- //debug($years);
-
- // Set all variables pour la vue
- $this->set(compact('current_year', 'year_min', 'years', 'tot', 'avg'));
- }
// - Page des OUTILS
if ($this->page=='tools') {
@@ -415,5 +321,250 @@ class PagesController extends AppController
}
} // display()
+
+
+
+ private function set_variables_for_page_stats() {
+
+ // Nb années demandées par l'utilisateur
+ $nbyears = $this->request->getQuery('nbyears');
+ // Par défaut $nbyears = 1
+ $nbyears = (is_numeric($nbyears) && $nbyears>0) ? abs(round($nbyears)) : 1;
+ //debug($nbyears);
+
+ $materiels = TableRegistry::getTableLocator()->get('Materiels');
+ $suivis = TableRegistry::getTableLocator()->get('Suivis');
+ $prets = TableRegistry::getTableLocator()->get('Emprunts');
+ $associated_entities = ['suivis','prets'];
+ $fk = 'materiel_id';
+
+ // Tous les matos qui ont une date d'achat non nulle
+ $all_matos = $materiels->find()->where(['year(date_acquisition) >' => 0]);
+
+ // - Année en cours
+ $now = new \DateTime('now');
+ //debug($now);
+ // 2020 en 2020
+ $current_year = (int) $now->format('Y');
+
+ // - Année min
+ //$year_min = $materiels->find()->min(['year(date_acquisition)']);
+ //$matos_year_min = $materiels->find()->where(['year(date_acquisition) >' => 0])
+ $matos_year_min = $all_matos->cleanCopy()
+ ->min(function($matos) {
+ return $matos->date_acquisition->format('Y');
+ });
+ $year_min = (int) $matos_year_min->date_acquisition->format('Y');
+
+ // - Nb années au total : au moins 1
+ $nbyears_max = $current_year - $year_min + 1;
+
+ // - Nb annnées à traiter (entre 1 et $nbyears_max)
+ // ($nbyears=null si pas passé en paramètre)
+ // ($nbyears='' si passé en paramètre mais sans valeur '?nbyears=')
+ //$nbyears = $nbyears ? abs((int)$nbyears) : $nbyears_max;
+ //debug($nbyears);
+ $nbyears = min($nbyears,$nbyears_max);
+ //debug($nbyears);
+ //debug($nbyears);
+ // 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)
+ //sif ($nbyears==$nbyears_max && $nbyears>2) $nbyears -= 2;
+ // Nouvelle année min
+ $year_min = $current_year-$nbyears + 1;
+
+ // Nouveau $all_matos, en tronquant à $nbyears
+ $all_matos = $materiels->find()
+ ->where(['year(date_acquisition) <=' => $current_year])
+ ->where(['year(date_acquisition) >=' => $year_min]);
+ $all_matos_ids = $all_matos->cleanCopy()->select(['id']);
+
+ /*
+ $statuses = [
+ 'CREATED' => 'created',
+ 'VALIDATED' => 'date_validated',
+ 'ARCHIVED' => 'date_archived'
+ ];
+ */
+ $statuses = [ 'CREATED', 'VALIDATED', 'TOBEARCHIVED', 'ARCHIVED' ];
+
+ // - tot : Données Totales (complètes) (tronquées à $nbyears)
+ $tot = [];
+ foreach ($statuses as $status) {
+ $all_matos_copy = $all_matos->cleanCopy();
+ // Tous les matos qui ont une date d'achat non nulle
+ if ($status != 'CREATED') $all_matos_copy->where(['status' => $status]);
+ $tot[$status] = $all_matos_copy->count();
+ }
+ // Suivis et Prets
+ // Nb materiels qui ont des suivis (i.e. qui ont au moins 1 suivi)
+ foreach ($associated_entities as $e) {
+ //$nb_matos_suivis = $suivis->find()
+ $tot[$e] = $$e->find()
+ // materiel_id not null
+ ->where(["$fk >" => 0])
+ ->select([$fk])
+ ->distinct([$fk])
+ ->where(["$fk IN" => $all_matos_ids])
+ ->count();
+ }
+
+ /*
+ // - tot2 : Données Totales Partielles (= tot sauf 1ère et dernière années)
+ $all_matos2 = $materiels
+ ->find()
+ ->where(['year(date_acquisition) <' => $current_year])
+ ->where(['year(date_acquisition) >' => $current_year-$nbyears]);
+ $all_matos_ids2 = $all_matos2->cleanCopy()->select(['id']);
+
+ $tot2 = [];
+ foreach ($statuses as $status) {
+ $all_matos_copy = $all_matos2->cleanCopy();
+ // Tous les matos qui ont une date d'achat non nulle
+ if ($status != 'CREATED') $all_matos_copy->where(['status' => $status]);
+ $tot2[$status] = $all_matos_copy->count();
+ }
+ // Suivis et Prets
+ // Nb materiels qui sont suivis (i.e. qui ont au moins 1 suivi)
+ foreach ($associated_entities as $e) {
+ //$nb_matos_suivis = $suivis->find()
+ $tot2[$e] = $$e->find()
+ // materiel_id not null
+ ->where(["$fk >" => 0])
+ ->select([$fk])
+ ->distinct([$fk])
+ ->where(["$fk IN" => $all_matos_ids2])
+ ->count();
+ }
+ */
+
+ // - Donées Moyennes
+ $avg = [];
+ /*
+ $avg['CREATED'] = 10;
+ $avg['VALIDATED'] = 7;
+ $avg['TOBEARCHIVED'] = 1;
+ $avg['ARCHIVED'] = 1;
+ */
+ foreach ($statuses as $status) {
+ $avg[$status] = round($tot[$status]/$nbyears, 1);
+ /*
+ * (EP)
+ * J'obtiens pas le meme resultat avec cette methode...
+ * Peut-être que ca compte pas les années où il n'y a rien (0)
+ */
+ /*
+ //$all_matos = $materiels->find();
+ //$all_matos = $materiels->find()->where(['year(date_acquisition) >' => 0]);
+ //->groupBy('year(date_acquisition)');
+ $all_matos_copy = $all_matos->cleanCopy();
+ if ($status != 'CREATED') $all_matos_copy->where(['status' => $status]);
+ $avg[$status] = $all_matos_copy
+ //->groupBy('year(date_acquisition)');
+ ->countBy(function($matos) {
+ return $matos->date_acquisition->format('Y');
+ })
+ ->avg();
+ //->toList();
+ //->toArray();
+ //->count();
+ $avg[$status] = round($avg[$status]);
+ */
+ }
+ // Suivis et Prets
+ // Nb materiels qui sont suivis (i.e. qui ont au moins 1 suivi)
+ foreach ($associated_entities as $e) {
+ $avg[$e] = round($tot[$e]/$nbyears, 1);
+ /*
+ $nb_matos_having_entity = $$e->find()
+ // materiel_id not null
+ ->where(["$fk >" => 0])
+ ->select([
+ 'year' => 'YEAR(created)'
+ ])
+ ->group('year')
+ ->toArray();
+
+ //->groupBy(function($entity) {
+ ->group(function($entity) {
+ return $entity->created->format('Y');
+ })
+ ->distinct([$fk])
+ ->count()
+ ->avg();
+ $avg[$e] = $nb_matos_having_entity;
+ */
+ //debug($nb_matos_having_entity);
+ }
+
+
+ // - Données par Année
+ $years = [];
+ $all_matos = $materiels->find();
+ for ($y=$current_year ; $y>=$year_min ; $y--) {
+ //debug($y);
+ $all_matos_for_year = $all_matos->cleanCopy()->where(['year(date_acquisition)' => $y]);
+ // - statut par année
+ try {
+ foreach ($statuses as $status) {
+ /*
+ $all_matos_for_year = $materiels->find();
+ ->where(['year(date_acquisition)' => $y]);
+ $all_matos_for_year = $all_matos->cleanCopy()->where(['year(date_acquisition)' => $y]);
+ */
+ $all_matos_for_year_and_status = $all_matos_for_year->cleanCopy();
+ if ($status != 'CREATED') $all_matos_for_year_and_status->where(['status' => $status]);
+ $years[$y][$status] = $all_matos_for_year_and_status->count();
+ }
+ } catch (\PDOException $e) {
+ debug("Mauvais format de requete SQL (PagesController suivis), Exception PDO générée !");
+ exit;
+ }
+ // Suivis et Prets, par année
+ $all_matos_suivis_for_year = $all_matos_for_year->cleanCopy();
+ foreach ($associated_entities as $e)
+ try {
+ /*
+ * SQL equivalent : à tester...
+ *
+ * SELECT COUNT(DISTINCT(suivis.materiel_id)) FROM suivis LEFT JOIN materiels
+ * ON suivis.materiel_id = materiels.id
+ * WHERE YEAR(materiels.date_acquisition) = $y
+ */
+ //$years[$y]['suivis'] = $suivis
+ $years[$y][$e] = $$e
+ // Tous les suivis/emprunts...
+ ->find()
+ // ... et leur materiel associé...
+ ->leftJoinWith('Materiels')
+ // ... LEFT JOIN ON (suivis.materiel_id = materiels.id) ... // ou emprunts.materiel_id
+ //->enableAutoFields(true)
+ // ... (uniquement les materiels de l'année $y) ...
+ ->where(['year(date_acquisition)' => $y])
+ // ... en ne gardant qu'1 seul suivi/emprunt par materiel (meme si ce materiel en a plusieurs) ...
+ ->distinct(['materiel_id'])
+ // ... et enfin, on compte le nombre de suivis/emprunts (total pour l'année $y)
+ ->count();
+ //->toArray();
+ //$all_matos_for_year
+ //->contain(['Suivis'])
+ //->select(['id', 'count_suivis => count(suivis)'])
+ //->where(['count_suivis >' => 0])
+ //->count();
+ } catch (\PDOException $e) {
+ debug("Mauvais format de requete SQL (PagesController prets), Exception PDO générée !");
+ exit;
+ }
+ //debug($years[$y]['suivis']);
+ //$years[$y]['suivis'] = 3;
+ //$years[$y]['prets'] = 4;
+ } // foreach year
+ //debug($years);
+
+ // Set all variables pour la vue
+ //$this->set(compact('current_year', 'year_min', 'tot', 'avg', 'years', 'suivis', 'prets'));
+ //$this->set(compact('current_year', 'year_min', 'nbyears', 'tot', 'tot2', 'avg', 'years'));
+ $this->set(compact('current_year', 'year_min', 'nbyears', 'tot', 'avg', 'years'));
+
+ } // set_variables_for_page_stats()
}
diff --git a/src/Template/Emprunts/index.ctp b/src/Template/Emprunts/index.ctp
index acd754a..b27a825 100755
--- a/src/Template/Emprunts/index.ctp
+++ b/src/Template/Emprunts/index.ctp
@@ -8,7 +8,9 @@
= $this->Paginator->sort('id', 'N°') ?> |
= $this->Paginator->sort('materiel_id', 'Matériel') ?> |
- = $this->Paginator->sort('numero_laboratoire', 'N° interne (labo)') ?> |
+
= $this->Paginator->sort('emprunt_interne', 'Type') ?> |
= $this->Paginator->sort('date_emprunt' ,'Date emprunt') ?> |
= $this->Paginator->sort('date_retour_emprunt', 'Date retour') ?> |
@@ -30,12 +32,21 @@
Html->link('Emprunt '.$this->Number->format($emprunt->id), ['action' => 'view', $emprunt->id])?> |
= $emprunt->has('materiel') ? $this->Html->link($emprunt->materiel->designation, ['controller' => 'Materiels', 'action' => 'view', $emprunt->materiel->id]) : '' ?> |
- = $emprunt->has('materiel') ? h($emprunt->materiel->numero_laboratoire) : '' ?> |
+
emprunt_interne) == '1') { echo 'Interne'; } else { echo 'Externe'; } ?> |
= h($emprunt->date_emprunt) ?> |
= h($emprunt->date_retour_emprunt) ?> |
= h($emprunt->nom_emprunteur) ?> |
- emprunt_interne) == '1') { echo h($emprunt->site->nom).' - '.h($emprunt->e_lieu_detail); } else { echo h($emprunt->laboratoire); } ?> |
+
+ emprunt_interne) == '1')
+ echo h($emprunt->site->nom).' - '.h($emprunt->e_lieu_detail);
+ else
+ echo h($emprunt->laboratoire);
+ ?>
+ |
diff --git a/src/Template/Pages/stats.ctp b/src/Template/Pages/stats.ctp
index 1d03096..c123768 100644
--- a/src/Template/Pages/stats.ctp
+++ b/src/Template/Pages/stats.ctp
@@ -20,23 +20,45 @@ for ($y=$year ; $y>$year-5 ; $y--) {
$years[$y]['validated'] = 8;
$years[$y]['archived'] = 8;
}
+
+$suivis = [];
+$prets = [];
+$suivis['tot'] = 100;
+$suivis['avg'] = 10;
+for ($y=$current_year ; $y>=$year_min ; $y--) $suivis[$y] = 8;
+$prets = $suivis;
*/
+
+
// Parameters passed by controller
$current_year = $current_year;
-$years = $years;
+$year_min = $year_min;
+$nbyears = $nbyears;
$avg = $avg;
$tot = $tot;
+//$tot2 = $tot2;
+$years = $years;
+//debug($suivis);
-function echoAsBold($elem, $bold) {
- if ($bold) echo '';
- echo $elem;
- if ($bold) echo '';
+function echoAsPctAndBold($nbelem, $total=null, $is_bold=false) {
+ if ($is_bold) echo '';
+ if ($total !== null) {
+ $pct = round( ($nbelem / $total) * 100 , 1 );
+ $nbelem = "$pct% ($nbelem)";
+ //$nbelem = "$nbelem ($pct%)";
+ //$nbelem = "$pct%";
+ }
+ echo $nbelem;
+ if ($is_bold) echo '';
}
-function displayStatsLine($title, $line, $bold=false, $year_prev=null, $avg=null) {
+
+
+//function displayStatsLine($title, $line, $suivis, $prets, $bold=false, $year_prev=null, $avg=null) {
+function displayStatsLine($title, $line, $is_bold=false, $year_prev=null, $avg=null) {
?>
@@ -63,22 +85,25 @@ function displayStatsLine($title, $line, $bold=false, $year_prev=null, $avg=null
=$evol_from_avg?> |
- =echoAsBold($total, $bold)?> |
+ =echoAsPctAndBold($total, null, $is_bold)?> |
-
- =echoAsBold($line['VALIDATED']." ($pct_validated%)", $bold)?> |
+ =echoAsPctAndBold($line['VALIDATED'], $total, $is_bold)?> |
- =echoAsBold($line['TOBEARCHIVED'], $bold)?> |
-
-
+
+ =echoAsPctAndBold($line['TOBEARCHIVED'], $total, $is_bold)?> |
+
- =echoAsBold($line['ARCHIVED']." ($pct_archived%)", $bold)?> |
+ =echoAsPctAndBold($line['ARCHIVED'], $total, $is_bold)?> |
+
+
+ =echoAsPctAndBold($line['suivis'], $total, $is_bold)?> |
+
+
+ =echoAsPctAndBold($line['prets'], $total, $is_bold)?> |
STATISTIQUES SUR LES MATÉRIELS
+
+
+
+Prendre en compte les |
+
+Form->create('Statistiques', [
+ 'type' => 'get',
+ ]);
+ //echo '';
+ echo $this->Form->control('nbyears', [
+ 'id' => 'nby',
+ //'class' => 'search-input',
+ 'label' => '',
+ //'type' => 'text',
+ 'default' => $nbyears
+ ]);
+ /*
+ echo $this->Form->submit('Chercher', [
+ 'name' => 'MaterielSAll',
+ 'id' => 'MaterielSAll',
+ 'style' => 'margin: 0px;'
+ ]);
+ */
+ echo $this->Form->end();
+?>
+ |
+dernières années (=$current_year.'-'.$year_min?>) |
+
+
+
+
@@ -118,9 +175,12 @@ function displayStatsLine($title, $line, $bold=false, $year_prev=null, $avg=null
Validés |
En demande d'archivage |
Archivés |
+ Matériels suivis |
+ Matériels empruntés |
-->
+
|
Matériels acquis |
@@ -134,8 +194,13 @@ function displayStatsLine($title, $line, $bold=false, $year_prev=null, $avg=null
|
|
-->
+
+ Suivis et Emprunts |
+
+
+
|
Evol. \ N-1 |
@@ -143,16 +208,27 @@ function displayStatsLine($title, $line, $bold=false, $year_prev=null, $avg=null
Total |
Validés |
- En demande d'archivage |
+ A archiver |
Archivés |
+
+ Matériels suivis |
+ Matériels prêtés |
+
+
@@ -163,6 +239,8 @@ function displayStatsLine($title, $line, $bold=false, $year_prev=null, $avg=null
|
|
|
+ |
+ |
@@ -181,7 +259,9 @@ function displayStatsLine($title, $line, $bold=false, $year_prev=null, $avg=null
$year_prev = $y==$year_min ? null : $years[$y-1];
displayStatsLine($year_title, $val, false, $year_prev, $avg);
}
+
?>
+
--
libgit2 0.21.2