Commit 2070d27c3994c03f5c9c82b7bcc432b336f884e9

Authored by Etienne Pallier
1 parent f4d2696b
Exists in master and in 1 other branch dev

GROS Nettoyage de la liste des fournisseurs

- GROSSE requete sql très compliquée de suppression des doublons (et des
espaces en trop)
- Suppression de la règle technique/inventoriable
- prix_ht désormais obligatoire

v4.105.24-3.7.9
@@ -119,8 +119,12 @@ Outre ces changements, voici d'autres changements importants : @@ -119,8 +119,12 @@ Outre ces changements, voici d'autres changements importants :
119 119
120 ======= CHANGES ======= 120 ======= CHANGES =======
121 121
122 -TODO  
123 - - (i) Nettoyage de la liste des fournisseurs : GROSSE requete sql compliquée de suppression des doublons (et des espaces en trop) 122 +-------
  123 +16/10/2020 v4.105.24-3.7.9 (EP)
  124 + - (i) GROS Nettoyage de la liste des fournisseurs :
  125 + => GROSSE requete sql très compliquée de suppression des doublons (et des espaces en trop)
  126 + - (i) Suppression de la règle technique/inventoriable
  127 + - (e) prix_ht désormais obligatoire
124 128
125 ------- 129 -------
126 15/10/2020 v4.105.24-3.7.9 (EP) 130 15/10/2020 v4.105.24-3.7.9 (EP)
src/Controller/AppController.php
@@ -3640,7 +3640,8 @@ class AppController extends Controller @@ -3640,7 +3640,8 @@ class AppController extends Controller
3640 if (!$configuration->envoi_mail && !$configuration->envoi_mail_guests) return null; 3640 if (!$configuration->envoi_mail && !$configuration->envoi_mail_guests) return null;
3641 3641
3642 // Si notification email pas demandée, on quitte 3642 // Si notification email pas demandée, on quitte
3643 - if (!$DEBUG) if (! $this->isNotifierActionSendingEmail($action) ) return null; 3643 + if (!$DEBUG)
  3644 + if (! $this->isNotifierActionSendingEmail($action) ) return null;
3644 3645
3645 /* 3646 /*
3646 * 4.A - CRÉATION DU MAIL (sujet et body) 3647 * 4.A - CRÉATION DU MAIL (sujet et body)
@@ -3757,6 +3758,9 @@ class AppController extends Controller @@ -3757,6 +3758,9 @@ class AppController extends Controller
3757 * - (TODO:) les responsables (scientifique et chef projet) du projet 3758 * - (TODO:) les responsables (scientifique et chef projet) du projet
3758 */ 3759 */
3759 3760
  3761 + // ssi Envoi général activé
  3762 + if ($configuration->envoi_mail) {
  3763 +
3760 if (!$IS_ENTITY_OTHER) { 3764 if (!$IS_ENTITY_OTHER) {
3761 3765
3762 // - (1) Ajout de l'utilisateur du matériel 3766 // - (1) Ajout de l'utilisateur du matériel
@@ -3824,6 +3828,8 @@ class AppController extends Controller @@ -3824,6 +3828,8 @@ class AppController extends Controller
3824 3828
3825 } // uniquement pour entité liée à un matériel 3829 } // uniquement pour entité liée à un matériel
3826 3830
  3831 + } // ssi envoi général activé
  3832 +
3827 3833
3828 /* 3834 /*
3829 * b) Envoi à la liste spécifique 3835 * b) Envoi à la liste spécifique
@@ -3835,7 +3841,8 @@ class AppController extends Controller @@ -3835,7 +3841,8 @@ class AppController extends Controller
3835 * systématiquement de toutes les actions 3841 * systématiquement de toutes les actions
3836 * 3842 *
3837 */ 3843 */
3838 - //$specificUsers = []; 3844 +
  3845 + // ssi envoi liste spécifique activé
3839 //if ($configuration->envoi_mail_guests && $action != 'printLabelRuban') { 3846 //if ($configuration->envoi_mail_guests && $action != 'printLabelRuban') {
3840 if ($configuration->envoi_mail_guests) { 3847 if ($configuration->envoi_mail_guests) {
3841 // mail aux adresses specifiees dans la config 3848 // mail aux adresses specifiees dans la config
@@ -3849,7 +3856,8 @@ class AppController extends Controller @@ -3849,7 +3856,8 @@ class AppController extends Controller
3849 //$specificUsers[] = $specificUser; 3856 //$specificUsers[] = $specificUser;
3850 // $mailList[sizeof($mailList)] = $configuration['emailGuest' . $i]; 3857 // $mailList[sizeof($mailList)] = $configuration['emailGuest' . $i];
3851 } 3858 }
3852 - } 3859 + } // ssi envoi liste spécifique activé
  3860 +
3853 3861
3854 /* 3862 /*
3855 * c) NETTOYAGE 3863 * c) NETTOYAGE
src/Controller/FournisseursController.php
@@ -12,6 +12,21 @@ use Cake\ORM\TableRegistry; @@ -12,6 +12,21 @@ use Cake\ORM\TableRegistry;
12 class FournisseursController extends AppController 12 class FournisseursController extends AppController
13 { 13 {
14 14
  15 + /*
  16 + * @Override
  17 + *
  18 + * Initialisation des autorisations pour les actions spécifiques à ce controleur
  19 + *
  20 + */
  21 + protected function setAuthorizations() {
  22 +
  23 + // - Action 'cleanup'
  24 + $this->setAuthorizationsForAction('cleanup (Nettoyage)', -1, [
  25 + 'super' => 0,
  26 + ]);
  27 +
  28 + }
  29 +
15 /** 30 /**
16 * Give authorization for unite 31 * Give authorization for unite
17 * 32 *
@@ -70,6 +85,12 @@ class FournisseursController extends AppController @@ -70,6 +85,12 @@ class FournisseursController extends AppController
70 } 85 }
71 */ 86 */
72 87
  88 + // Page de nettoyage de la liste des fournisseurs
  89 + public function cleanup() {
  90 +
  91 + }
  92 +
  93 +
73 /** 94 /**
74 * Index method 95 * Index method
75 * 96 *
src/Controller/MaterielsController.php
@@ -11,6 +11,7 @@ use App\Model\Entity\User; @@ -11,6 +11,7 @@ use App\Model\Entity\User;
11 use Cake\I18n\FrozenDate; 11 use Cake\I18n\FrozenDate;
12 use Cake\Database\Expression\QueryExpression; 12 use Cake\Database\Expression\QueryExpression;
13 use Cake\Database\Query; 13 use Cake\Database\Query;
  14 +use phpDocumentor\Reflection\Types\True_;
14 15
15 //use App\Controller\DocumentsController; 16 //use App\Controller\DocumentsController;
16 //App::import('Controller', 'Documents'); 17 //App::import('Controller', 'Documents');
@@ -343,10 +344,16 @@ class MaterielsController extends AppController { @@ -343,10 +344,16 @@ class MaterielsController extends AppController {
343 ]); 344 ]);
344 */ 345 */
345 346
  347 +
346 /* 348 /*
347 * c) Règles d'accès (ACLs) 349 * c) Règles d'accès (ACLs)
348 * 350 *
349 */ 351 */
  352 +
  353 + // - Action 'execSqlRequestForBugfix' (bugfix) => autorisé seulement à superadmin
  354 + $this->setAuthorizationsForAction('execSqlRequestForBugfix (bugfix)', -1, [
  355 + 'super' => 0,
  356 + ]);
350 357
351 // - Action 'add' (ajout d'un nouveau matériel) => autorisé pour tous 358 // - Action 'add' (ajout d'un nouveau matériel) => autorisé pour tous
352 //$this->setAuthorizationsForAction('add', 0); 359 //$this->setAuthorizationsForAction('add', 0);
@@ -1691,7 +1698,177 @@ class MaterielsController extends AppController { @@ -1691,7 +1698,177 @@ class MaterielsController extends AppController {
1691 1698
1692 } // view 1699 } // view
1693 1700
  1701 +
  1702 + public function execSqlRequestForBugfix() {
  1703 + debug("START...");
  1704 + $this->execSqlRequestForBugfix_fournisseurs();
  1705 + debug("...STOP");
  1706 + exit;
  1707 + /*
  1708 + return $this->redirect([
  1709 + 'controller' => 'pages',
  1710 + 'action' => 'tools',
  1711 + ]);
  1712 + */
  1713 + }
1694 1714
  1715 + // (EP20201016) Bugfix liste fournisseurs en BD
  1716 + private function execSqlRequestForBugfix_fournisseurs() {
  1717 +
  1718 + $DEBUG=false;
  1719 + //$DEBUG=true;
  1720 +
  1721 + $NL = '<br />';
  1722 + $CLEAN = false;
  1723 +
  1724 + $ftable= $this->Materiels->Fournisseurs;
  1725 + // OU ENCORE (même chose) :
  1726 + //$ftable= $this->getTableLocator()->get('Fournisseurs');
  1727 + // OU ENCORE (même chose) :
  1728 + //$ftable= TableRegistry::getTableLocator()->get('Fournisseurs');
  1729 +
  1730 + function show($entities, $AFEW=true) {
  1731 + //foreach ($entities as $e) echo("[$e] <br>");
  1732 + $nb = $entities->count();
  1733 + $i=0;
  1734 + foreach ($entities as $e) {
  1735 + $i++;
  1736 + if ($AFEW && $i==10) echo "......................<br>";
  1737 + if (
  1738 + !$AFEW
  1739 + ||
  1740 + ( $AFEW && ($i<10 || $i>($nb-10)) )
  1741 + )
  1742 + echo('['.$e->nom.'] <br/>');
  1743 + }
  1744 + }
  1745 +
  1746 + function getAllFournisseursLike($fname, $table) {
  1747 + $fournisseurs = $table
  1748 + ->find()
  1749 + //->where(['nom =' => $fname]);
  1750 + // On cherche le nom du fournisseur avec ou sans espace
  1751 + ->where( [ 'nom in' => [ $fname, trim($fname), " $fname", "$fname ", " $fname " ] ] )
  1752 + // avec leurs materiels associés
  1753 + ->contain(['Materiels'])
  1754 + ;
  1755 + return $fournisseurs;
  1756 + }
  1757 +
  1758 + function getFournisseurWithMaxMatos($entities) {
  1759 + $feurs_nbmatos = [];
  1760 + foreach ($entities as $e) $feurs_nbmatos[$e->nom] = count($e->materiels);
  1761 + //$fdoublons_nbmatos = sort($fdoublons_nbmatos);
  1762 + //$nbmatos_max = max($feurs_nbmatos);
  1763 + dump($feurs_nbmatos);
  1764 + $fname_max = array_search( max($feurs_nbmatos), $feurs_nbmatos );
  1765 + //debug($fname_max);
  1766 + foreach ($entities as $e)
  1767 + if ($e->nom == $fname_max)
  1768 + return $e;
  1769 + /*
  1770 + foreach ($entities as $e) {
  1771 + debug($e->nom);
  1772 + if ($e->nom == $fname_max) {
  1773 + debug($e->nom);
  1774 + return $e;
  1775 + }
  1776 + }
  1777 + */
  1778 + }
  1779 +
  1780 + function cleanup($f, $table, $DEBUG) {
  1781 + $fname = trim($f->nom);
  1782 + if ($f->nom != trim($f->nom)) {
  1783 + $f->nom = trim($f->nom);
  1784 + !$DEBUG && $table->save($f);
  1785 + }
  1786 + }
  1787 +
  1788 + while (! $CLEAN) {
  1789 + // On sortira (et terminera) au prochain tour, sauf si on a trouvé un doublon
  1790 + $CLEAN = true;
  1791 + $fournisseurs = $ftable->find();
  1792 + $nb = $fournisseurs->count();
  1793 + print "Liste fournisseurs AVANT cleanup ($nb) : $NL $NL";
  1794 + show($fournisseurs, false);
  1795 + print "$NL$NL";
  1796 + foreach ($fournisseurs as $f) {
  1797 + $fname = trim($f->nom);
  1798 + echo $fname;
  1799 + // On cherche TOUS les doublons imaginables de ce fournisseur
  1800 + // et on les récupère AVEC leurs materiels associés
  1801 + $fdoublons = getAllFournisseursLike($fname, $ftable);
  1802 + // Pas de doublons => on passe au suivant
  1803 + if ( $fdoublons->count() == 1 ) {
  1804 + echo '<br><br>';
  1805 + cleanup($f, $ftable, $DEBUG);
  1806 + continue;
  1807 + /* pour debug
  1808 + // VIRER
  1809 + $CLEAN = true;
  1810 + break;
  1811 + */
  1812 + }
  1813 + /* Il y a des doublons => on les supprime
  1814 + Stratégie :
  1815 + - on garde seulement celui qui a le plus de matériels liés (l’élu)
  1816 + - on supprime les autres après avoir relié leurs matériels au fournisseur élu
  1817 + */
  1818 + echo " (doublons) : <br>";
  1819 + //show($fdoublons);
  1820 + //debug($fdoublons->toArray());
  1821 + //dump($fdoublons->toArray());
  1822 + // - a) on trie les fournisseurs selon leur nb de matos associés, et on élit celui qui en a le plus
  1823 + $f_max = getFournisseurWithMaxMatos($fdoublons);
  1824 + //debug($f_max->nom);
  1825 + // - b) on supprime les doublons après avoir mis à jour leurs matos associés
  1826 + foreach ($fdoublons as $fdoublon) {
  1827 + //debug($fdoublon->nom);
  1828 + // tous sauf f_max
  1829 + if ($fdoublon->nom != $f_max->nom) {
  1830 + //debug("diff");
  1831 + // on associe les matos du doublon à f_max
  1832 + echo( '- Relie les matos de ['.$fdoublon->nom.']('.$fdoublon->id.') à ['.$f_max->nom.']('.$f_max->id.') :'.$NL );
  1833 + foreach ($fdoublon->materiels as $m) {
  1834 + //debug($m);
  1835 + echo('-- matos '.$m->id.' : f_id='.$m->fournisseur_id.', ['.$m->designation.']'.$NL);
  1836 + $m->fournisseur_id = $f_max->id;
  1837 + //echo($m->id.': f_id='.$m->fournisseur_id.', ['.$m->designation.']');
  1838 + //!$DEBUG && $this->Materiels->save($m);
  1839 + if ( !$this->Materiels->save($m) ) {
  1840 + debug("Le matériel n'a pas pu être sauvegardé !!");
  1841 + debug($m->getErrors());
  1842 + $host = $this->getCurrentURL(false);
  1843 + echo '<a href="'.$host.'/materiels/view/'.$m->id.'">Voir ce materiel pour le corriger</a>';
  1844 + //throw new \ErrorException("Le matériel n'a pas pu être sauvegardé !!");
  1845 + exit;
  1846 + }
  1847 + }
  1848 + // maintenant, on peut supprimer le doublon
  1849 + echo( '- Delete ['.$fdoublon->nom.']('.$fdoublon->id.')'.$NL );
  1850 + !$DEBUG && $ftable->delete($fdoublon);
  1851 + }
  1852 + }
  1853 + // On nettoie f si besoin (on peut car maintenant il est unique)
  1854 + cleanup($f_max, $ftable, $DEBUG);
  1855 + // On quitte la boucle en cours car on a supprimé des éléments de cette boucle => il faut donc recommencer depuis le début
  1856 + echo '<br><br>';
  1857 + if (!$DEBUG) {
  1858 + $CLEAN = false;
  1859 + break;
  1860 + }
  1861 + } // end foreach
  1862 + } // end while not CLEAN
  1863 +
  1864 + print "$NL$NL";
  1865 + $fournisseurs = $ftable->find();
  1866 + $nb = $fournisseurs->count();
  1867 + print "Liste fournisseurs APRÈS cleanup ($nb) : $NL $NL";
  1868 + show($fournisseurs);
  1869 +
  1870 + }
  1871 +
1695 /** 1872 /**
1696 * Add or Edit method (do either add() or edit()) 1873 * Add or Edit method (do either add() or edit())
1697 * => Factorisation de add() et edit() 1874 * => Factorisation de add() et edit()
src/Model/Entity/Fournisseur.php
@@ -13,6 +13,9 @@ use Cake\ORM\Entity; @@ -13,6 +13,9 @@ use Cake\ORM\Entity;
13 class Fournisseur extends Entity 13 class Fournisseur extends Entity
14 { 14 {
15 15
  16 + // Ce qui s'affiche quand on fait echo $entity
  17 + public function __toString() { return $this->nom; }
  18 +
16 /** 19 /**
17 * Fields that can be mass assigned using newEntity() or patchEntity(). 20 * Fields that can be mass assigned using newEntity() or patchEntity().
18 * 21 *
src/Model/Table/FournisseursTable.php
@@ -28,7 +28,8 @@ class FournisseursTable extends AppTable @@ -28,7 +28,8 @@ class FournisseursTable extends AppTable
28 parent::initialize($config); 28 parent::initialize($config);
29 29
30 $this->setTable('fournisseurs'); 30 $this->setTable('fournisseurs');
31 - $this->setDisplayField('id'); 31 + //$this->setDisplayField('id');
  32 + $this->setDisplayField('nom');
32 $this->setPrimaryKey('id'); 33 $this->setPrimaryKey('id');
33 34
34 $this->hasMany('Materiels', [ 35 $this->hasMany('Materiels', [
src/Model/Table/MaterielsTable.php
@@ -10,6 +10,7 @@ use Cake\I18n\Time; @@ -10,6 +10,7 @@ use Cake\I18n\Time;
10 use Cake\I18n\Date; 10 use Cake\I18n\Date;
11 use Cake\ORM\Association\BelongsTo; 11 use Cake\ORM\Association\BelongsTo;
12 use Cake\ORM\Entity; 12 use Cake\ORM\Entity;
  13 +use Cake\I18n\FrozenDate;
13 14
14 /** 15 /**
15 * Materiels Model 16 * Materiels Model
@@ -47,6 +48,12 @@ use Cake\ORM\Entity; @@ -47,6 +48,12 @@ use Cake\ORM\Entity;
47 class MaterielsTable extends AppTable 48 class MaterielsTable extends AppTable
48 { 49 {
49 50
  51 + private $PREV_SEUIL_INVENTORIABLE = 800;
  52 +
  53 + private $LAST_SEUIL_INVENTORIABLE_YEAR = 2020;
  54 + private $LAST_SEUIL_INVENTORIABLE_DATE = '03/06/2020';
  55 + private $LAST_SEUIL_INVENTORIABLE; // 1000€ pour IRAP (depuis 3/6/2020)
  56 +
50 public $ALL_STATUS = array( 57 public $ALL_STATUS = array(
51 'CREATED', 58 'CREATED',
52 'VALIDATED', 59 'VALIDATED',
@@ -409,11 +416,12 @@ class MaterielsTable extends AppTable @@ -409,11 +416,12 @@ class MaterielsTable extends AppTable
409 416
410 417
411 $validator->numeric('prix_ht') 418 $validator->numeric('prix_ht')
412 - ->allowEmpty('prix_ht') 419 + // (EP202010 prix obligatoire)
  420 + //->allowEmpty('prix_ht')
413 ->add('prix_ht', 'valid', [ 421 ->add('prix_ht', 'valid', [
414 - 'rule' => 'check_string',  
415 - 'message' => 'Ce champ contient des caractères interdits',  
416 - 'provider' => 'table' 422 + 'rule' => 'check_string',
  423 + 'message' => 'Ce champ contient des caractères interdits',
  424 + 'provider' => 'table'
417 ]); 425 ]);
418 $validator->allowEmpty('eotp')->add('eotp', 'valid', [ 426 $validator->allowEmpty('eotp')->add('eotp', 'valid', [
419 'rule' => 'check_string', 427 'rule' => 'check_string',
@@ -537,6 +545,7 @@ class MaterielsTable extends AppTable @@ -537,6 +545,7 @@ class MaterielsTable extends AppTable
537 */ 545 */
538 //$this->config = TableRegistry::getTableLocator()->get('Configurations')->get(1); 546 //$this->config = TableRegistry::getTableLocator()->get('Configurations')->get(1);
539 $this->config = TableRegistry::getTableLocator()->get('Configurations')->find()->first(); 547 $this->config = TableRegistry::getTableLocator()->get('Configurations')->find()->first();
  548 + $this->LAST_SEUIL_INVENTORIABLE = $this->config->prix_inventaire_administratif;
540 549
541 // 1) Définition de nos propres règles de gestion 550 // 1) Définition de nos propres règles de gestion
542 551
@@ -568,9 +577,14 @@ class MaterielsTable extends AppTable @@ -568,9 +577,14 @@ class MaterielsTable extends AppTable
568 // return if checked as "administratif" price MUST be set 577 // return if checked as "administratif" price MUST be set
569 $checkPriceIfIsAdministratif = function ($entity) { 578 $checkPriceIfIsAdministratif = function ($entity) {
570 //if ($entity->materiel_administratif) 579 //if ($entity->materiel_administratif)
571 - if (! $entity->materiel_technique)  
572 - return ($entity->prix_ht >= $this->config->prix_inventaire_administratif); // 1000€ pour l'IRAP 580 + if (! $entity->materiel_technique) {
  581 + //debug($entity->date_acquisition);
  582 + //debug($entity->date_acquisition->format('Y'));
  583 + $year = $entity->date_acquisition->format('Y');
  584 + $this->SEUIL_INVENTORIABLE = ($year >= $this->LAST_SEUIL_INVENTORIABLE_YEAR) ? $this->LAST_SEUIL_INVENTORIABLE : $this->PREV_SEUIL_INVENTORIABLE;
  585 + return ($entity->prix_ht >= $this->SEUIL_INVENTORIABLE); // 1000€ pour l'IRAP (depuis 2017 ?)
573 //return ($entity->prix_ht !== null); 586 //return ($entity->prix_ht !== null);
  587 + }
574 return true; 588 return true;
575 }; 589 };
576 590
@@ -655,16 +669,20 @@ class MaterielsTable extends AppTable @@ -655,16 +669,20 @@ class MaterielsTable extends AppTable
655 'message' => 'Le matériel vaut moins de ' . $configuration->prix_inventaire_administratif . '€ HT, il n\'est donc pas inventoriable.' 669 'message' => 'Le matériel vaut moins de ' . $configuration->prix_inventaire_administratif . '€ HT, il n\'est donc pas inventoriable.'
656 ]); 670 ]);
657 */ 671 */
  672 +
  673 + /* (EP 202010 n'est plus nécessaire)
658 $rules->add($checkPriceIfIsAdministratif, [ 674 $rules->add($checkPriceIfIsAdministratif, [
659 'errorField' => 'prix_ht', 675 'errorField' => 'prix_ht',
660 //'message' => 'Le matériel ne peut pas être inventoriable et ne pas avoir de prix' 676 //'message' => 'Le matériel ne peut pas être inventoriable et ne pas avoir de prix'
661 - 'message' => "Si le matériel n'est pas technique, son prix doit obligatoirement être supérieur à 1000€ (inventoriable)" 677 + 'message' => "Si le matériel n'est pas technique, son prix HT doit obligatoirement être supérieur à ".
  678 + $this->LAST_SEUIL_INVENTORIABLE."€ (inventoriable)"
662 ]); 679 ]);
663 $rules->add($checkPriceIfIsAdministratif, [ 680 $rules->add($checkPriceIfIsAdministratif, [
664 'errorField' => 'materiel_technique', 681 'errorField' => 'materiel_technique',
665 //'message' => 'Le matériel ne peut pas être inventoriable et ne pas avoir de prix' 682 //'message' => 'Le matériel ne peut pas être inventoriable et ne pas avoir de prix'
666 - 'message' => "Si le matériel n'est pas technique, son prix doit obligatoirement être supérieur à 1000€ (inventoriable)" 683 + 'message' => "Si le matériel n'est pas technique, son prix HT doit obligatoirement être supérieur à ".$this->LAST_SEUIL_INVENTORIABLE."€ (inventoriable)"
667 ]); 684 ]);
  685 + */
668 686
669 $rules->add($rules->isUnique([ 687 $rules->add($rules->isUnique([
670 'numero_laboratoire' 688 'numero_laboratoire'
src/Template/Fournisseurs/cleanup.ctp 0 → 100644
@@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
  1 +
  2 +<div class="fournisseurs index">
  3 +
  4 + <?php echo '<h2><i class="icon-list"></i> Nettoyage de la liste des Fournisseurs</h2>'; ?>
  5 +
  6 + <?= $this->Html->link(
  7 + "Nettoyage de toute la liste (suppression des doublons et des espaces en trop)",
  8 + ['controller'=>'Materiels', 'action' => 'exec_sql_request_for_bugfix'],
  9 + ['title' => 'Nettoyage', 'style' => 'margin: 0 2px', 'escape' => false ])
  10 + ?>
  11 +
  12 + <br><br>
  13 + (TODO) Remplacer un fournisseur par un autre :
  14 + <br>
  15 + Remplacer le fournisseur FOURNISSEUR1 par FOURNISSEUR2
  16 + <br><br>
  17 +
  18 + [SUBMIT]
  19 +
  20 +
  21 +</div>
  22 +
  23 +<!--
  24 +<div class="actions">
  25 + <php echo $this->element('menu') ?>
  26 + <php
  27 +
  28 +echo $this->element('menu_index', [
  29 + 'pluralHumanName' => 'Fournisseurs',
  30 + 'singularHumanName' => 'Fournisseur'
  31 +])?>
  32 + </div>
  33 +-->
0 \ No newline at end of file 34 \ No newline at end of file
src/Template/Materiels/view.ctp
@@ -311,7 +311,7 @@ $CAN_PRINT_LABEL = $IS_VALIDATED &amp;&amp; $configuration-&gt;hasPrinter &amp;&amp; $USER_IS_ADMIN @@ -311,7 +311,7 @@ $CAN_PRINT_LABEL = $IS_VALIDATED &amp;&amp; $configuration-&gt;hasPrinter &amp;&amp; $USER_IS_ADMIN
311 311
312 // Bouton Modifier 312 // Bouton Modifier
313 if ($CAN_EDIT) 313 if ($CAN_EDIT)
314 - $echoActionButton($this->Html, 'icon-pencil', $bStyle, ' Editer', 'materiels', 'edit', $entity->id); 314 + $echoActionButton($this->Html, 'icon-pencil', $bStyle, ' Éditer', 'materiels', 'edit', $entity->id);
315 315
316 // Bouton Supprimer 316 // Bouton Supprimer
317 if ($CAN_DELETE) 317 if ($CAN_DELETE)
@@ -666,10 +666,29 @@ $CAN_PRINT_LABEL = $IS_VALIDATED &amp;&amp; $configuration-&gt;hasPrinter &amp;&amp; $USER_IS_ADMIN @@ -666,10 +666,29 @@ $CAN_PRINT_LABEL = $IS_VALIDATED &amp;&amp; $configuration-&gt;hasPrinter &amp;&amp; $USER_IS_ADMIN
666 } 666 }
667 667
668 $displayElement(__('Prix (HT)'), h($entity->prix_ht) . ' €'); 668 $displayElement(__('Prix (HT)'), h($entity->prix_ht) . ' €');
669 - $displayElement(__('Fournisseur'), $entity->has('fournisseur') ? $entity->fournisseur->nom : ''); 669 +
  670 + // Fournisseur (lien)
  671 + //$displayElement(__('Fournisseur'), $entity->has('fournisseur') ? $entity->fournisseur->nom : '');
  672 + $displayElement(__('Fournisseur'),
  673 + $this->Html->link(
  674 + h($entity->fournisseur->nom),
  675 + ['controller'=>'Fournisseurs', 'action'=>'view', $entity->fournisseur->id]
  676 + )
  677 + );
  678 +
670 $displayElement(__('Lieu de stockage'), $entity->has('site') ? h($entity->site->nom) : ''); 679 $displayElement(__('Lieu de stockage'), $entity->has('site') ? h($entity->site->nom) : '');
671 $displayElement(__('Détail lieu de stockage'), h($entity->lieu_detail)); 680 $displayElement(__('Détail lieu de stockage'), h($entity->lieu_detail));
672 - $displayElement(__('Nom de l\'utilisateur'), $this->Html->link(h($entity->nom_responsable), 'mailto:' . h($entity->email_responsable))); 681 +
  682 + // Acheteur (lien mailto)
  683 + $displayElement(__("Nom de l'acheteur"),
  684 + $this->Html->link(
  685 + h($entity->nom_responsable),
  686 + // Mailto
  687 + 'mailto:' . h($entity->email_responsable)
  688 + //['controller'=>'Users', 'action'=>'view', 'id'=>$entity->id]
  689 + )
  690 + );
  691 +
673 $displayElement(__('N. interne (labo)'), h($entity->numero_laboratoire)); 692 $displayElement(__('N. interne (labo)'), h($entity->numero_laboratoire));
674 if ($entity->gestionnaire_id) { 693 if ($entity->gestionnaire_id) {
675 $gestionnaire = TableRegistry::getTableLocator()->get('Users')->get($entity->gestionnaire_id); 694 $gestionnaire = TableRegistry::getTableLocator()->get('Users')->get($entity->gestionnaire_id);
src/Template/Pages/tools.ctp
@@ -107,6 +107,22 @@ echo &#39;&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&#39;; @@ -107,6 +107,22 @@ echo &#39;&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&#39;;
107 107
108 if ($role == 'Super Administrateur') : 108 if ($role == 'Super Administrateur') :
109 109
  110 + // Exécution d'un script correctif (bugfix) temporaire (superadmin only)
  111 + echo '<tr><td>';
  112 + echo $this->Html->link('Exécuter le dernier script correctif', [
  113 + 'controller' => 'Materiels',
  114 + 'action' => 'exec_sql_request_for_bugfix'
  115 + ]);
  116 + echo '</td></tr>';
  117 +
  118 + // Nettoyage de la liste des fournisseurs (superadmin only)
  119 + echo '<tr><td>';
  120 + echo $this->Html->link('Nettoyer la liste des Fournisseurs', [
  121 + 'controller' => 'Fournisseurs',
  122 + 'action' => 'cleanup'
  123 + ]);
  124 + echo '</td></tr>';
  125 +
110 // Page des messages de log (level info, debug, et notice) 126 // Page des messages de log (level info, debug, et notice)
111 echo '<tr><td>'; 127 echo '<tr><td>';
112 echo $this->Html->link('Voir les messages de LOG', [ 128 echo $this->Html->link('Voir les messages de LOG', [