diff --git a/CHANGES.txt b/CHANGES.txt
index c08dfc9..dd95ebb 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -119,6 +119,15 @@ Outre ces changements, voici d'autres changements importants :
======= CHANGES =======
+TODO
+ => nouveau formulaire de remplacement d'un fournisseur par un autre
+
+-------
+19/10/2020 v4.105.26-3.7.9
+ - (i) Grosse mise à jour de la page "Gestion des Fournisseurs"
+ => nouvelle requete de "nettoyage automagique" de toute la liste
+ - (b) Bugfix tests => tous les tests doivent passer maintenant
+
-------
16/10/2020 v4.105.25-3.7.9 (EP)
- (i) GROS Nettoyage de la liste des fournisseurs :
diff --git a/README.md b/README.md
index 6675b95..04dcd2e 100644
--- a/README.md
+++ b/README.md
@@ -42,8 +42,8 @@ Logiciel testé et validé sur les configurations suivantes :
--------------------------------------------------------------------------------------------
-Date: 16/10/2020
-Version: 4.105.25-3.7.9
+Date: 19/10/2020
+Version: 4.105.26-3.7.9
HISTORIQUE DES CHANGEMENTS DE VERSION : voir le fichier CHANGES.txt (ou la page web /pages/changes)
diff --git a/src/Controller/FournisseursController.php b/src/Controller/FournisseursController.php
index e80effc..038f1f7 100644
--- a/src/Controller/FournisseursController.php
+++ b/src/Controller/FournisseursController.php
@@ -21,10 +21,15 @@ class FournisseursController extends AppController
protected function setAuthorizations() {
// - Action 'cleanup'
- $this->setAuthorizationsForAction('cleanup (Nettoyage)', -1, [
+ $this->setAuthorizationsForAction('cleanup (page de Nettoyage)', -1, [
+ 'admin' => 0,
'super' => 0,
]);
-
+ $this->setAuthorizationsForAction('cleanupFournisseurs (action de Nettoyage)', -1, [
+ 'admin' => 0,
+ 'super' => 0,
+ ]);
+
}
/**
@@ -91,6 +96,164 @@ class FournisseursController extends AppController
}
+ // (EP20201016) Bugfix liste fournisseurs en BD
+ public function cleanupFournisseurs() {
+
+ $DEBUG=false;
+ //$DEBUG=true;
+
+ $NL = '
';
+ $CLEAN = false;
+
+ $ftable= $this->Fournisseurs;
+ /*
+ $mtable = $this->Fournisseurs->Materiels;
+ $ms = $mtable->find();
+ debug($ms->count());
+ */
+
+ // OU ENCORE (même chose) :
+ //$ftable= $this->getTableLocator()->get('Fournisseurs');
+ // OU ENCORE (même chose) :
+ //$ftable= TableRegistry::getTableLocator()->get('Fournisseurs');
+
+ function show($entities, $AFEW=true) {
+ //foreach ($entities as $e) echo("[$e]
");
+ $nb = $entities->count();
+ $i=0;
+ foreach ($entities as $e) {
+ $i++;
+ if ($AFEW && $i==10) echo "......................
";
+ if (
+ !$AFEW
+ ||
+ ( $AFEW && ($i<10 || $i>($nb-10)) )
+ )
+ echo('['.$e->nom.']
');
+ }
+ }
+
+ function getAllFournisseursLike($fname, $table) {
+ $fournisseurs = $table
+ ->find()
+ //->where(['nom =' => $fname]);
+ // On cherche le nom du fournisseur avec ou sans espace
+ ->where( [ 'nom in' => [ $fname, trim($fname), " $fname", "$fname ", " $fname " ] ] )
+ // avec leurs materiels associés
+ ->contain(['Materiels'])
+ ;
+ return $fournisseurs;
+ }
+
+ function getFournisseurWithMaxMatos($entities) {
+ $feurs_nbmatos = [];
+ foreach ($entities as $e) $feurs_nbmatos[$e->nom] = count($e->materiels);
+ //$fdoublons_nbmatos = sort($fdoublons_nbmatos);
+ //$nbmatos_max = max($feurs_nbmatos);
+ dump($feurs_nbmatos);
+ $fname_max = array_search( max($feurs_nbmatos), $feurs_nbmatos );
+ //debug($fname_max);
+ foreach ($entities as $e)
+ if ($e->nom == $fname_max)
+ return $e;
+ }
+
+ function cleanup($f, $table, $DEBUG) {
+ $fname = trim($f->nom);
+ if ($f->nom != trim($f->nom)) {
+ $f->nom = trim($f->nom);
+ !$DEBUG && $table->save($f);
+ }
+ }
+
+ while (! $CLEAN) {
+ // On sortira (et terminera) au prochain tour, sauf si on a trouvé un doublon
+ $CLEAN = true;
+ $fournisseurs = $ftable->find();
+ $nb = $fournisseurs->count();
+ print "Liste fournisseurs AVANT cleanup ($nb) : $NL $NL";
+ show($fournisseurs, false);
+ print "$NL$NL";
+ foreach ($fournisseurs as $f) {
+ $fname = trim($f->nom);
+ echo $fname;
+ // On cherche TOUS les doublons imaginables de ce fournisseur
+ // et on les récupère AVEC leurs materiels associés
+ $fdoublons = getAllFournisseursLike($fname, $ftable);
+ // Pas de doublons => on passe au suivant
+ if ( $fdoublons->count() == 1 ) {
+ echo '
';
+ cleanup($f, $ftable, $DEBUG);
+ continue;
+ /* pour debug
+ // VIRER
+ $CLEAN = true;
+ break;
+ */
+ }
+ /* Il y a des doublons => on les supprime
+ Stratégie :
+ - on garde seulement celui qui a le plus de matériels liés (l’élu)
+ - on supprime les autres après avoir relié leurs matériels au fournisseur élu
+ */
+ echo " (doublons) :
";
+ //show($fdoublons);
+ //debug($fdoublons->toArray());
+ //dump($fdoublons->toArray());
+ // - a) on trie les fournisseurs selon leur nb de matos associés, et on élit celui qui en a le plus
+ $f_max = getFournisseurWithMaxMatos($fdoublons);
+ //debug($f_max->nom);
+ // - b) on supprime les doublons après avoir mis à jour leurs matos associés
+ foreach ($fdoublons as $fdoublon) {
+ //debug($fdoublon->nom);
+ // tous sauf f_max
+ if ($fdoublon->nom != $f_max->nom) {
+ //debug("diff");
+ // on associe les matos du doublon à f_max
+ echo( '- Relie les matos de ['.$fdoublon->nom.']('.$fdoublon->id.') à ['.$f_max->nom.']('.$f_max->id.') :'.$NL );
+ foreach ($fdoublon->materiels as $m) {
+ //debug($m);
+ echo('-- matos '.$m->id.' : f_id='.$m->fournisseur_id.', ['.$m->designation.']'.$NL);
+ $m->fournisseur_id = $f_max->id;
+ //echo($m->id.': f_id='.$m->fournisseur_id.', ['.$m->designation.']');
+ //!$DEBUG && $this->Materiels->save($m);
+ //if ( !$this->Materiels->save($m) ) {
+ if ( ! $this->Fournisseurs->Materiels->save($m) ) {
+ debug("Le matériel n'a pas pu être sauvegardé !!");
+ debug($m->getErrors());
+ $host = $this->getCurrentURL(false);
+ echo 'Voir ce materiel pour le corriger';
+ //throw new \ErrorException("Le matériel n'a pas pu être sauvegardé !!");
+ exit;
+ }
+ }
+ // maintenant, on peut supprimer le doublon
+ echo( '- Delete ['.$fdoublon->nom.']('.$fdoublon->id.')'.$NL );
+ !$DEBUG && $ftable->delete($fdoublon);
+ }
+ }
+ // On nettoie f si besoin (on peut car maintenant il est unique)
+ cleanup($f_max, $ftable, $DEBUG);
+ // On quitte la boucle en cours car on a supprimé des éléments de cette boucle => il faut donc recommencer depuis le début
+ echo '
';
+ if (!$DEBUG) {
+ $CLEAN = false;
+ break;
+ }
+ } // end foreach
+ } // end while not CLEAN
+
+ print "$NL$NL";
+ $fournisseurs = $ftable->find();
+ $nb = $fournisseurs->count();
+ print "Liste fournisseurs APRÈS cleanup ($nb) : $NL $NL";
+ show($fournisseurs);
+
+ exit;
+
+ }
+
+
/**
* Index method
*
diff --git a/src/Controller/MaterielsController.php b/src/Controller/MaterielsController.php
index 5e0c974..fd98fd7 100755
--- a/src/Controller/MaterielsController.php
+++ b/src/Controller/MaterielsController.php
@@ -1701,7 +1701,7 @@ class MaterielsController extends AppController {
public function execSqlRequestForBugfix() {
debug("START...");
- $this->execSqlRequestForBugfix_fournisseurs();
+ //$this->execSqlRequestForBugfix_fournisseurs();
debug("...STOP");
exit;
/*
@@ -1712,162 +1712,6 @@ class MaterielsController extends AppController {
*/
}
- // (EP20201016) Bugfix liste fournisseurs en BD
- private function execSqlRequestForBugfix_fournisseurs() {
-
- $DEBUG=false;
- //$DEBUG=true;
-
- $NL = '
';
- $CLEAN = false;
-
- $ftable= $this->Materiels->Fournisseurs;
- // OU ENCORE (même chose) :
- //$ftable= $this->getTableLocator()->get('Fournisseurs');
- // OU ENCORE (même chose) :
- //$ftable= TableRegistry::getTableLocator()->get('Fournisseurs');
-
- function show($entities, $AFEW=true) {
- //foreach ($entities as $e) echo("[$e]
");
- $nb = $entities->count();
- $i=0;
- foreach ($entities as $e) {
- $i++;
- if ($AFEW && $i==10) echo "......................
";
- if (
- !$AFEW
- ||
- ( $AFEW && ($i<10 || $i>($nb-10)) )
- )
- echo('['.$e->nom.']
');
- }
- }
-
- function getAllFournisseursLike($fname, $table) {
- $fournisseurs = $table
- ->find()
- //->where(['nom =' => $fname]);
- // On cherche le nom du fournisseur avec ou sans espace
- ->where( [ 'nom in' => [ $fname, trim($fname), " $fname", "$fname ", " $fname " ] ] )
- // avec leurs materiels associés
- ->contain(['Materiels'])
- ;
- return $fournisseurs;
- }
-
- function getFournisseurWithMaxMatos($entities) {
- $feurs_nbmatos = [];
- foreach ($entities as $e) $feurs_nbmatos[$e->nom] = count($e->materiels);
- //$fdoublons_nbmatos = sort($fdoublons_nbmatos);
- //$nbmatos_max = max($feurs_nbmatos);
- dump($feurs_nbmatos);
- $fname_max = array_search( max($feurs_nbmatos), $feurs_nbmatos );
- //debug($fname_max);
- foreach ($entities as $e)
- if ($e->nom == $fname_max)
- return $e;
- /*
- foreach ($entities as $e) {
- debug($e->nom);
- if ($e->nom == $fname_max) {
- debug($e->nom);
- return $e;
- }
- }
- */
- }
-
- function cleanup($f, $table, $DEBUG) {
- $fname = trim($f->nom);
- if ($f->nom != trim($f->nom)) {
- $f->nom = trim($f->nom);
- !$DEBUG && $table->save($f);
- }
- }
-
- while (! $CLEAN) {
- // On sortira (et terminera) au prochain tour, sauf si on a trouvé un doublon
- $CLEAN = true;
- $fournisseurs = $ftable->find();
- $nb = $fournisseurs->count();
- print "Liste fournisseurs AVANT cleanup ($nb) : $NL $NL";
- show($fournisseurs, false);
- print "$NL$NL";
- foreach ($fournisseurs as $f) {
- $fname = trim($f->nom);
- echo $fname;
- // On cherche TOUS les doublons imaginables de ce fournisseur
- // et on les récupère AVEC leurs materiels associés
- $fdoublons = getAllFournisseursLike($fname, $ftable);
- // Pas de doublons => on passe au suivant
- if ( $fdoublons->count() == 1 ) {
- echo '
';
- cleanup($f, $ftable, $DEBUG);
- continue;
- /* pour debug
- // VIRER
- $CLEAN = true;
- break;
- */
- }
- /* Il y a des doublons => on les supprime
- Stratégie :
- - on garde seulement celui qui a le plus de matériels liés (l’élu)
- - on supprime les autres après avoir relié leurs matériels au fournisseur élu
- */
- echo " (doublons) :
";
- //show($fdoublons);
- //debug($fdoublons->toArray());
- //dump($fdoublons->toArray());
- // - a) on trie les fournisseurs selon leur nb de matos associés, et on élit celui qui en a le plus
- $f_max = getFournisseurWithMaxMatos($fdoublons);
- //debug($f_max->nom);
- // - b) on supprime les doublons après avoir mis à jour leurs matos associés
- foreach ($fdoublons as $fdoublon) {
- //debug($fdoublon->nom);
- // tous sauf f_max
- if ($fdoublon->nom != $f_max->nom) {
- //debug("diff");
- // on associe les matos du doublon à f_max
- echo( '- Relie les matos de ['.$fdoublon->nom.']('.$fdoublon->id.') à ['.$f_max->nom.']('.$f_max->id.') :'.$NL );
- foreach ($fdoublon->materiels as $m) {
- //debug($m);
- echo('-- matos '.$m->id.' : f_id='.$m->fournisseur_id.', ['.$m->designation.']'.$NL);
- $m->fournisseur_id = $f_max->id;
- //echo($m->id.': f_id='.$m->fournisseur_id.', ['.$m->designation.']');
- //!$DEBUG && $this->Materiels->save($m);
- if ( !$this->Materiels->save($m) ) {
- debug("Le matériel n'a pas pu être sauvegardé !!");
- debug($m->getErrors());
- $host = $this->getCurrentURL(false);
- echo 'Voir ce materiel pour le corriger';
- //throw new \ErrorException("Le matériel n'a pas pu être sauvegardé !!");
- exit;
- }
- }
- // maintenant, on peut supprimer le doublon
- echo( '- Delete ['.$fdoublon->nom.']('.$fdoublon->id.')'.$NL );
- !$DEBUG && $ftable->delete($fdoublon);
- }
- }
- // On nettoie f si besoin (on peut car maintenant il est unique)
- cleanup($f_max, $ftable, $DEBUG);
- // On quitte la boucle en cours car on a supprimé des éléments de cette boucle => il faut donc recommencer depuis le début
- echo '
';
- if (!$DEBUG) {
- $CLEAN = false;
- break;
- }
- } // end foreach
- } // end while not CLEAN
-
- print "$NL$NL";
- $fournisseurs = $ftable->find();
- $nb = $fournisseurs->count();
- print "Liste fournisseurs APRÈS cleanup ($nb) : $NL $NL";
- show($fournisseurs);
-
- }
/**
* Add or Edit method (do either add() or edit())
diff --git a/src/Template/Fournisseurs/cleanup.ctp b/src/Template/Fournisseurs/cleanup.ctp
index 57ec27f..a4c4f78 100644
--- a/src/Template/Fournisseurs/cleanup.ctp
+++ b/src/Template/Fournisseurs/cleanup.ctp
@@ -1,20 +1,30 @@