setActionsNounAndPastVerb([ 'cleanupFournisseurs' => ['Nettoyage','nettoyé'], //'replaceFournisseur' => ['Remplacement','remplacé'], ]); /* * b) Actions de ce controleur qui enverront des notifications (log et/ou email) * * 'log' = logger seulement * 'mail' => envoyer un mail seulement * 'both' = faire les 2 (logger ET envoyer un mail) * */ $this->setNotificationAllowedOnActions([ 'cleanupFournisseurs' => 'both', //'replaceFournisseur' => 'both', 'index' => 'both', ]); /* * c) Règles d'accès (ACLs) * */ /* // - Action 'cleanup' $this->setAuthorizationsForAction('cleanup (page de Nettoyage)', -1, [ 'admin' => 0, 'super' => 0, ]); */ $this->setAuthorizationsForAction('cleanupFournisseurs (Nettoyage de la liste des fournisseurs)', -1, [ 'admin' => 0, 'super' => 0, ]); /* $this->setAuthorizationsForAction("replaceFournisseur (remplacement d'un fournisseur)", -1, [ 'admin' => 0, 'super' => 0, ]); */ } // setAuthorizations() /** * Give authorization for unite * * @param * $user * @return boolean */ //public function isAuthorized($user) /* public function isAuthorized($user, $action = null, $id=null, $role=null, $userCname=null) { $this->myDebug("step 2A (specific): FournisseursController.isAuthorized(user)"); $this->myDebug("user is:", $user); //$this->myDebug($user); // $configuration = $this->confLabinvent; // $action = $this->request->getAttribute('params')['action']; // $role = TableRegistry::get('Users')->find()->where(['username' => $user[$configuration->authentificationType_ldap][0]])->first()['role']; $action = $this->getActionPassed(); $role = $this->getUserRole($user); // TOUS /S * if (in_array($action, ['view', 'index'])) { * return true; * } S/ // Super-Admin peut accéder à chaque action // if($role == 'Super Administrateur') return true; /S * // Administration + peut ajouter, supprimer ou modifier * if( in_array($action,['add'])) { * return true; * } S/ // Tout le monde peut tout faire sur les fournisseurs //if( in_array($action,['add', 'edit', 'delete'])) { if ( in_array( $action, // C, R, U, D autorisé [ 'add', 'view', 'edit', 'delete'] ) ) return true; // Administration peut ajouter, supprimer ou modifier un fournisseur // if($role == 'Administration' && in_array($action,['add','delete','edit'])) return true; // Par défaut // return false; // return parent::isAuthorized($user); return $this->isAuthorizedCommons($user); } */ /* // Page de nettoyage de la liste des fournisseurs public function cleanup() { } */ // (EP20201019) Remplacement d'un fournisseur doublon ($f_doublon) par un autre ($f_ok) (en BD) private function _replaceFournisseur($f_doublon, $f_ok, $DEBUG=false) { $NL = '
'; $ftable= $this->Fournisseurs; $DEBUG && print( '- Relie les matos de ['.$f_doublon->nom.'](id '.$f_doublon->id.') à ['.$f_ok->nom.'](id '.$f_ok->id.') :'.$NL ); foreach ($f_doublon->materiels as $m) { //debug($m); $DEBUG && print('-- matos '.$m->id.' : f_id='.$m->fournisseur_id.', ['.$m->designation.']'.$NL); $m->fournisseur_id = $f_ok->id; //echo($m->id.': f_id='.$m->fournisseur_id.', ['.$m->designation.']'); //!$DEBUG && $this->Materiels->save($m); //if ( !$this->Materiels->save($m) ) { if (!$DEBUG) if ( ! $ftable->Materiels->save($m, ['checkRules'=>false]) ) { 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 $DEBUG && print( '- Delete ['.$f_doublon->nom.']('.$f_doublon->id.')'.$NL ); !$DEBUG && $ftable->delete($f_doublon); } // (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 $fdoublon au fournisseur f_max $this->_replaceFournisseur($fdoublon, $f_max, $DEBUG); /* 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; $this->redirect( ['action' => 'index'] ); } /** * Index method * * @return \Cake\Network\Response|null */ public function index() { $success = ''; // POST ? (remplacement d'un fournisseur par un autre) if ($this->request->is('post')) { $DEBUG = false; //$DEBUG = true; $data = $this->request->getData(); //debug($data); $f_bad_id = $data['fournisseur_bad_id']; $f_ok_id = $data['fournisseur_ok_id']; // On n'agit que si les fournisseurs sont différents if ( ($f_bad_id && $f_ok_id) && ($f_bad_id != $f_ok_id) ) { //debug("ok"); $f_ok = $this->Fournisseurs->get($f_ok_id); $f_bad = $this->Fournisseurs->get( $f_bad_id, [ 'contain'=>['Materiels'] ] ); $this->_replaceFournisseur($f_bad, $f_ok, $DEBUG); $success = 'Le remplacement a bien été effectué'; } //else debug("ko"); } //$entities = $this->paginate($this->Fournisseurs); $entities = $this->paginate($this->Fournisseurs, [ /* 'limit' => $limit, 'maxLimit' => 1000, 'sortWhitelist' => [ 'designation', 'numero_laboratoire', 'Categories.nom', 'Organismes.nom', 'numero_inventaire_organisme', //'nom_responsable', 'nom_user', 'status', 'date_acquisition', 'etiquette', ], */ 'order' => [ 'nom' => 'asc' ], ]); $fournisseurs = $this->Fournisseurs->find('list', [ 'keyField' => 'id', 'valueField' => 'nom', //'order' => 'Fournisseurs.nom' 'order' => 'nom' ]); $this->set(compact('success', 'entities', 'fournisseurs')); /* Inutile sauf si on fait du JSON $this->set('_serialize', [ 'fournisseurs' ]); */ } /** * View method * * @param string|null $id * Fournisseurs id. * @return \Cake\Network\Response|null * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found. */ public function view($id = null) { return $this->view_generic($id, [ 'Materiels', ]); /* $fournisseur = $this->Fournisseurs->get($id); $materiels = TableRegistry::get('Materiels')->find('all')->where([ 'fournisseur_id =' => $id ]); $this->set('materiels', $materiels); $this->set('fournisseur', $fournisseur); $this->set('_serialize', [ 'fournisseur' ]); */ } /** * add_or_edit method * * - add : * @return \Cake\Network\Response|void Redirects on successful add, renders view otherwise * * - edit : * @param string|null $id fournisseur id * @return \Cake\Network\Response|void Redirects on successful edit, renders view otherwise. * @throws \Cake\Network\Exception\NotFoundException When record not found * */ private function add_or_edit_simple($id = null) { $IS_ADD = ($id===null); $fournisseur = $IS_ADD ? $this->Fournisseurs->newEntity() : $this->Fournisseurs->get($id); $request_types = $IS_ADD ? 'post' : ['patch','post','put']; $verb = $IS_ADD ? 'ajouté' : 'modifié'; $action_redirect = $IS_ADD ? 'index' : 'view'; //if ($this->request->is('post')) { //if ($this->request->is(['patch','post','put'])) { if ($this->request->is($request_types)) { $fournisseur = $this->Fournisseurs->patchEntity($fournisseur, $this->request->getData()); if ($this->Fournisseurs->save($fournisseur)) { $this->Flash->success(__("Le fournisseur a bien été $verb")); return $this->redirect([ 'action' => $action_redirect, $id // null si ADD ]); } else { $this->Flash->error(__("Le fournisseur n'a pas pu être $verb")); } } $this->set(compact('fournisseur')); /* Seulement si JSON $this->set('_serialize', [ 'fournisseur' ]); */ } // add_or_edit() /** * Add method * * @return \Cake\Network\Response|void Redirects on successful add, renders view otherwise. */ public function add() { $this->add_or_edit_simple(); /* $fournisseur = $this->Fournisseurs->newEntity(); if ($this->request->is('post')) { $fournisseur = $this->Fournisseurs->patchEntity($fournisseur, $this->request->getData()); if ($this->Fournisseurs->save($fournisseur)) { $this->Flash->success(__('Le fournisseur a bien été ajouté.')); return $this->redirect([ 'action' => 'index' ]); } else { $this->Flash->error(__('Le fournisseur n\'a pas pu être ajouté.')); } } $this->set(compact('fournisseur')); $this->set('_serialize', [ 'fournisseur' ]); */ } /** * Edit method * * @param string|null $id * fournisseur id. * @return \Cake\Network\Response|void Redirects on successful edit, renders view otherwise. * @throws \Cake\Network\Exception\NotFoundException When record not found. */ public function edit($id = null) { $this->add_or_edit_simple($id); /* $fournisseur = $this->Fournisseurs->get($id); if ($this->request->is(['patch','post','put'])) { $fournisseur = $this->Fournisseurs->patchEntity($fournisseur, $this->request->getData()); if ($this->Fournisseurs->save($fournisseur)) { $this->Flash->success(__('Le fournisseur a bien été édité.')); return $this->redirect([ 'action' => 'view', $id ]); } else { $this->Flash->error(__('Le fournisseur n\'a pas pu être édité.')); } } $this->set(compact('fournisseur')); $this->set('_serialize', [ 'fournisseur' ]); */ } /** * Delete method * * @param string|null $id * fournisseur id. * @return \Cake\Network\Response|null Redirects to index. * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found. */ public function delete($id = null) { $this->request->allowMethod([ 'post', 'delete' ]); $fournisseur = $this->Fournisseurs->get($id); if ($this->Fournisseurs->delete($fournisseur)) { $this->Flash->success(__('Le fournisseur a bien été supprimé.')); } else { $this->Flash->error(__('Le fournisseur n\'a pas pu être supprimé.')); } return $this->redirect([ 'action' => 'index' ]); } }