Commit 5733c01a authored by Laurent Lecluse's avatar Laurent Lecluse
Browse files

Nouveau système de suppression d'intervenant

parent 24b340f3
Loading
Loading
Loading
Loading
+19 −6
Changes for module/Application/src/Application/Controller/IntervenantController.php: 19 added lines, 6 removed lines.
Original line number Diff line number Diff line
@@ -118,6 +118,13 @@ class IntervenantController extends AbstractController
            throw new \LogicException('Intervenant introuvable');
        }

        if ($this->params()->fromQuery('menu', false) !== false) { // pour gérer uniquement l'affichage du menu
            $vh = new ViewModel();
            $vh->setTemplate('application/intervenant/menu');

            return $vh;
        }

        $this->addIntervenantRecent($intervenant);

        return compact('intervenant', 'role', 'tab');
@@ -424,23 +431,29 @@ class IntervenantController extends AbstractController
        if (!$intervenant) {
            throw new \Exception('Intervenant introuvable');
        }
        $intervenantCode = $intervenant->getCode();

        $intSuppr = $this->getProcessusIntervenant()->suppression($intervenant);

        if ($ids = $this->params()->fromPost('ids')) {
            try {
                $intSuppr->delete($ids);
                if (!empty($ids)) {
                    $res = $intSuppr->delete($ids);
                    $this->getServiceWorkflow()->calculerTableauxBord([], $intervenant);
                $this->flashMessenger()->addSuccessMessage('Fiche intervenant supprimée intégralement. Vous allez être redirigé(e) vers la page de recherche des intervenants.');
                    if ($res) {
                        $this->flashMessenger()->addSuccessMessage('Données de l\'intervenant supprimées');
                    } else {
                        $this->flashMessenger()->addErrorMessage('Une ou plusieurs erreurs ont été rencontrées');
                    }
                }
            } catch (\Exception $e) {
                $this->flashMessenger()->addErrorMessage($this->translate($e));
            }
        } else {
            $this->flashMessenger()->addWarningMessage(
                'Attention : La suppression d\'une fiche entraine la suppression de toutes les données associées pour l\'année en cours'
            );
        }
        $tree = $intSuppr->getTree();
        if (!$tree) {
            $intervenant = $this->getServiceIntervenant()->getByCode($intervenantCode);
        }

        return compact('intervenant', 'tree');
    }
+49 −18
Changes for module/Application/src/Application/Model/TreeNode.php: 49 added lines, 18 removed lines.
Original line number Diff line number Diff line
@@ -2,9 +2,10 @@

namespace Application\Model;

class TreeNode implements \IteratorAggregate, \ArrayAccess {
class TreeNode implements \IteratorAggregate, \ArrayAccess
{

    CONST ABSOLUTE_ID_SEPARATOR = '/';
    const ABSOLUTE_ID_SEPARATOR = '/';

    /**
     * @var mixed
@@ -12,20 +13,25 @@ class TreeNode implements \IteratorAggregate, \ArrayAccess {
    private $id;

    /**
     * @var string
     * @var ?string
     */
    private $label;

    /**
     * @var integer
     * @var ?int
     */
    private $ordre;

    /**
     * @var string
     * @var ?string
     */
    private $icon;

    /**
     * @var ?string
     */
    private $title;

    /**
     * @var TreeNode
     */
@@ -93,9 +99,9 @@ class TreeNode implements \IteratorAggregate, \ArrayAccess {


    /**
     * @return string
     * @return string|null
     */
    public function getLabel()
    public function getLabel(): ?string
    {
        return $this->label;
    }
@@ -103,11 +109,11 @@ class TreeNode implements \IteratorAggregate, \ArrayAccess {


    /**
     * @param string $label
     * @param string|null $label
     *
     * @return TreeNode
     */
    public function setLabel($label)
    public function setLabel(?string $label): TreeNode
    {
        $this->label = $label;

@@ -117,9 +123,9 @@ class TreeNode implements \IteratorAggregate, \ArrayAccess {


    /**
     * @return int
     * @return int|null
     */
    public function getOrdre()
    public function getOrdre(): ?int
    {
        return $this->ordre;
    }
@@ -127,11 +133,11 @@ class TreeNode implements \IteratorAggregate, \ArrayAccess {


    /**
     * @param int $ordre
     * @param int|null $ordre
     *
     * @return TreeNode
     */
    public function setOrdre($ordre)
    public function setOrdre(?int $ordre): TreeNode
    {
        $this->ordre = $ordre;

@@ -141,9 +147,9 @@ class TreeNode implements \IteratorAggregate, \ArrayAccess {


    /**
     * @return string
     * @return string|null
     */
    public function getIcon()
    public function getIcon(): ?string
    {
        return $this->icon;
    }
@@ -151,11 +157,11 @@ class TreeNode implements \IteratorAggregate, \ArrayAccess {


    /**
     * @param string $icon
     * @param string|null $icon
     *
     * @return TreeNode
     */
    public function setIcon($icon)
    public function setIcon(?string $icon): TreeNode
    {
        $this->icon = $icon;

@@ -164,6 +170,30 @@ class TreeNode implements \IteratorAggregate, \ArrayAccess {



    /**
     * @return string|null
     */
    public function getTitle(): ?string
    {
        return $this->title;
    }



    /**
     * @param string|null $title
     *
     * @return TreeNode
     */
    public function setTitle(?string $title): TreeNode
    {
        $this->title = $title;

        return $this;
    }



    /**
     * @param $id
     *
@@ -313,7 +343,8 @@ class TreeNode implements \IteratorAggregate, \ArrayAccess {
    /**
     * @return \ArrayIterator
     */
    public function getIterator() {
    public function getIterator()
    {
        return new \ArrayIterator($this->children);
    }

+227 −29
Changes for module/Application/src/Application/Processus/Intervenant/SuppressionProcessus.php: 227 added lines, 29 removed lines.
Original line number Diff line number Diff line
@@ -2,9 +2,9 @@

namespace Application\Processus\Intervenant;

use Application\Entity\Db\Intervenant;
use Application\Entity\Db\Traits\IntervenantAwareTrait;
use Application\Model\TreeNode;
use Application\Traits\TranslatorTrait;
use UnicaenApp\Service\EntityManagerAwareTrait;


@@ -12,6 +12,7 @@ class SuppressionProcessus
{
    use EntityManagerAwareTrait;
    use IntervenantAwareTrait;
    use TranslatorTrait;


    protected $queries = [
@@ -127,6 +128,7 @@ ORDER BY
SELECT
  CASE WHEN v.histo_destruction IS NULL THEN 1 ELSE 0 END visible,
  v.intervenant_id         parent_id,
  tv.code                  type_validation_code,
  v.id                     id,
  'Validations'            categorie,
  tv.libelle || ' par ' || u.display_name || ' le ' || to_char( v.histo_creation, 'dd/mm/YYYY \"à\" HH24:MI' ) label,
@@ -346,6 +348,8 @@ WHERE
SELECT
  CASE WHEN v.histo_destruction IS NULL THEN 1 ELSE 0 END visible,
  vvh.volume_horaire_id    parent_id,
  vvh.volume_horaire_id    volume_horaire_id,
  vvh.validation_id        validation_id,
  '[VOLUME_HORAIRE_ID:' || vvh.VOLUME_HORAIRE_ID || ',VALIDATION_ID:' || vvh.validation_id || ']' id,
  null                     categorie,
  'Validation du ' || to_char( v.histo_creation, 'dd/mm/YYYY \"à\" HH24:MI' ) || ' par ' || u.display_name label,
@@ -363,6 +367,8 @@ WHERE
SELECT
  CASE WHEN v.histo_destruction IS NULL THEN 1 ELSE 0 END visible,
  vvh.volume_horaire_ref_id parent_id,
  vvh.volume_horaire_ref_id volume_horaire_ref_id,
  vvh.validation_id         validation_id,
  '[VOLUME_HORAIRE_REF_ID:' || vvh.VOLUME_HORAIRE_REF_ID || ',VALIDATION_ID:' || vvh.validation_id || ']' id,
  null                      categorie,
  'Validation du ' || to_char( v.histo_creation, 'dd/mm/YYYY \"à\" HH24:MI' ) || ' par ' || u.display_name label,
@@ -376,7 +382,7 @@ WHERE
        ",


        'VALIDATION.FICHIER' => "
        'FICHIER.VALIDATION' => "
SELECT
  CASE WHEN v.histo_destruction IS NULL THEN 1 ELSE 0 END visible,
  f.id                     parent_id,
@@ -393,6 +399,29 @@ WHERE
        ",
    ];

    protected $delete  = [
        '.MISE_EN_PAIEMENT'           => [],
        'CONTRAT.VALIDATION'          => ['queries' => ['UPDATE CONTRAT SET VALIDATION_ID = NULL WHERE validation_id = :ID']],
        'CONTRAT.FICHIER'             => [],
        '.CONTRAT'                    => ['queries' => ['UPDATE VOLUME_HORAIRE SET contrat_id = null WHERE contrat_id = :ID', 'UPDATE contrat SET CONTRAT_ID = NULL WHERE contrat_id = :ID']],
        '.AGREMENT'                   => [],
        '.VALIDATION'                 => [],
        '.VALIDATION_VOL_HORAIRE'     => ['key' => ['VALIDATION_ID', 'VOLUME_HORAIRE_ID']],
        '.VALIDATION_VOL_HORAIRE_REF' => ['key' => ['VALIDATION_ID', 'VOLUME_HORAIRE_REF_ID']],
        'PIECE_JOINTE.FICHIER'        => ['queries' => ['DELETE FROM piece_jointe_fichier WHERE fichier_id = :ID']],
        '.PIECE_JOINTE'               => [],
        '.VOLUME_HORAIRE'             => [],
        '.VOLUME_HORAIRE_REF'         => [],
        '.SERVICE'                    => ['queries' => ['DELETE FROM formule_resultat_service WHERE service_id = :ID']],
        '.SERVICE_REFERENTIEL'        => ['queries' => ['DELETE FROM formule_resultat_service_ref WHERE service_referentiel_id = :ID']],
        '.MODIFICATION_SERVICE_DU'    => [],
        '.INTERVENANT_DOSSIER'        => [],
        '.INTERVENANT'                => ['queries' => [
            'DELETE FROM validation WHERE intervenant_id = :ID',// Suppression de toutes les validations orphelines restantes
            'DELETE FROM formule_resultat WHERE intervenant_id = :ID' // Suppression de tous les restes de formules de calcul
        ]],
    ];

    /**
     * @var array
     */
@@ -453,6 +482,7 @@ WHERE
                    }
                    $d['TABLE']                  = $dest;
                    $d['PARENT_TABLE']           = $ref;
                    $d['DELETE']                 = false;
                    $this->data[$dest][$d['ID']] = $d;
                }
                if (isset($this->data[$dest])) {
@@ -464,8 +494,12 @@ WHERE



    protected function makeTree(int $id): TreeNode
    protected function makeTree(int $id): ?TreeNode
    {
        if (!isset($this->data['INTERVENANT'][$id])) {
            return null;
        }

        $d = $this->data['INTERVENANT'][$id];

        $node = $this->makeNode($d);
@@ -480,7 +514,14 @@ WHERE
    {
        $node = new TreeNode($data['TABLE'] . '#' . $data['ID']);
        $node->setIcon($data['ICON']);
        if (isset($data['ERROR'])) {
            $node->setLabel($data['LABEL'] . ' <span style="font-weight:bold;color:red" title="' . htmlentities($data['ERROR']) . '">Erreur rencontrée</span>');
        } else {
            $node->setLabel($data['LABEL']);
        }

        if (isset($data['TITLE'])) $node->setTitle($data['TITLE']);


        return $node;
    }
@@ -489,20 +530,11 @@ WHERE

    protected function makeNodes(string $table, $id, TreeNode $parent)
    {
        $subTables = [];
        foreach ($this->queries as $tbls => $null) {
            [$p, $c] = explode('.', $tbls);
            if ($p == $table) {
                if (array_key_exists($c, $this->data)) {
                    $subTables[] = $c;
                }
            }
        }

        foreach ($subTables as $t) {
            foreach ($this->data[$t] as $null => $d) {
                if ($d['PARENT_ID'] == $id && $d['VISIBLE'] == 1) {
        foreach ($this->data as $t => $ds) {
            foreach ($ds as $null => $d) {
                if ($d['PARENT_TABLE'] == $table && $d['PARENT_ID'] == $id && $d['VISIBLE'] == 1) {
                    $n = $this->makeNode($d);

                    if ($d['CATEGORIE']) {
                        $cats = explode('|', $d['CATEGORIE']);
                        $cp   = $parent;
@@ -510,7 +542,7 @@ WHERE
                            if ($cp->has($categorie)) {
                                $cp = $cp->get($categorie);
                            } else {
                                $newNode = new TreeNode(uniqid('cat-'));
                                $newNode = new TreeNode($table == 'INTERVENANT' ? $categorie : uniqid('cat-'));
                                $newNode->setLabel($categorie);
                                $cp->add($newNode);
                                $cp = $newNode;
@@ -528,30 +560,196 @@ WHERE



    public function delete(array $ids)
    public function delete(array $ids, bool $force = false): bool
    {
        $this->getData();
        $fids = [];
        $this->tagDelete($ids, $force);
        $this->makeDeleteQueries();

        return $this->doDelete();
    }



    private function tagDelete(array $ids, bool $force)
    {
        /* On positionne le tag sur toutes les data à détruire */
        foreach ($ids as $id) {
            if (false !== strpos($id, '#')) {
                [$table, $id] = explode('#', $id);
                if (isset($this->data[$table][$id])) {
                    if ($id[0] == '[') {
                        $kvs = explode(',', substr($id, 1, -2));
                        foreach ($kvs as $i => $kv) {
                            [$k, $v] = explode(':', $kv);
                            $fids[$table][$id][$k] = (int)$v;
                    //$this->subTagDelete($table, $id, true, $force);
                    $this->data[$table][$id]['DELETE'] = true;
                }
                    } else {
                        $fids[$table][$id] = ['ID' => (int)$id];
            }
        }
                //var_dump($table, $id);


        /* On détruit les sous-éléments si on est en FORCE ou bien si les sous-éléments sont cachés pour ne pas qu'ils gênent */
        foreach ($this->data as $table => $ds) {
            foreach ($ds as $i => $d) {
                if ($d['DELETE']) {
                    $this->subDelete($d['TABLE'], $d ['ID'], $force);
                }
            }
        }

        /* Si on est en mode soft, on ne supprime pas les parents dont les enfants doivent rester */
        foreach ($this->data as $table => $ds) {
            foreach ($ds as $i => $d) {
                if (!$force && !$d['DELETE']) {
                    $dp = $d;
                    while ($dp['PARENT_ID']) {
                        $pTable = $dp['PARENT_TABLE'];
                        $pId    = $dp['PARENT_ID'];
                        $dp     = $this->data[$pTable][$pId];
                        if ($this->data[$pTable][$pId]['DELETE']) {
                            $this->data[$pTable][$pId]['DELETE'] = false;
                        }
                    }
                }
            }
        }

        /* Suppression des validations de VH ou VHRef orphelines */
        if (isset($this->data['VALIDATION'])) {
            foreach ($this->data['VALIDATION'] as $vid => $vdata) {
                if (isset($vdata['TYPE_VALIDATION_CODE'])) {
                    if ('SERVICES_PAR_COMP' == $vdata['TYPE_VALIDATION_CODE'] && isset($this->data['VALIDATION_VOL_HORAIRE'])) {
                        $found = false;
                        foreach ($this->data['VALIDATION_VOL_HORAIRE'] as $vvh) {
                            if ($vvh['VALIDATION_ID'] == $vid && (false === $vvh['DELETE'])) {
                                $found = true;
                                break;
                            }
                        }
                        if (!$found) {
                            $this->data['VALIDATION'][$vid]['DELETE'] = true;
                        }
                    }
                    if ('REFERENTIEL' == $vdata['TYPE_VALIDATION_CODE'] && isset($this->data['VALIDATION_VOL_HORAIRE_REF'])) {
                        $found = false;
                        foreach ($this->data['VALIDATION_VOL_HORAIRE_REF'] as $vvh) {
                            if ($vvh['VALIDATION_ID'] == $vid && (false === $vvh['DELETE'])) {
                                $found = true;
                                break;
                            }
                        }
                        if (!$found) {
                            $this->data['VALIDATION'][$vid]['DELETE'] = true;
                        }
                    }
                }
            }
        }
        /* DEBUG *
        $delIds = [];
        foreach ($this->data as $table => $ds) {
            foreach ($ds as $i => $d) {
                if ($d['DELETE']) {
                    if (!isset($delIds[$table])) $delIds[$table] = [];
                    $delIds[$table][]                = $d['ID'];
                    $this->data[$table][$i]['LABEL'] .= '<span style="font-weight:bold;color:red"> (à supprimer!)</span>';
                }
            }
        }
        //var_dump($this->data);
        var_dump($ids);
        var_dump($fids);
        var_dump($this->data);
        var_dump($delIds);
        /* FIN DEBUG */
    }



    private function makeDeleteQueries()
    {
        foreach ($this->delete as $rule => $config) {
            [$ruleParent, $ruleTable] = explode('.', $rule);
            $keyCols = isset($config['key']) ? $config['key'] : ['ID'];
            $queries = isset($config['queries']) ? $config['queries'] : [];
            $delSql  = '';
            foreach ($keyCols as $k) {
                if ($delSql == '') {
                    $delSql .= 'DELETE FROM ' . $ruleTable . ' WHERE ';
                } else {
                    $delSql .= ' AND ';
                }
                $delSql .= $k . ' = :' . $k;
            }
            $queries[] = $delSql;

            if (isset($this->data[$ruleTable])) {
                foreach ($this->data[$ruleTable] as $i => $d) {
                    if (!$ruleParent || $ruleParent == $d['PARENT_TABLE']) {
                        if (isset($d['DELETE']) && $d['DELETE']) {
                            foreach ($queries as $query) {
                                $delQuery = $query;
                                foreach ($keyCols as $k) {
                                    $delQuery = str_replace(':' . $k, (int)$d[$k], $delQuery);
                                }
                                if (!isset($this->data[$ruleTable][$i]['DELETE_QUERIES'])) {
                                    $this->data[$ruleTable][$i]['DELETE_QUERIES'] = [];
                                }
                                $this->data[$ruleTable][$i]['DELETE_QUERIES'][] = $delQuery;
                            }
                        }
                    }
                }
            }
        }
    }



    private function doDelete(): bool
    {
        $res = true;
        foreach ($this->delete as $rule => $null) {
            [$ruleParent, $ruleTable] = explode('.', $rule);
            if (isset($this->data[$ruleTable])) {
                foreach ($this->data[$ruleTable] as $i => $d) {
                    if ((!$ruleParent || $d['PARENT_TABLE'] == $ruleParent) && isset($d['DELETE_QUERIES']) && !empty($d['DELETE_QUERIES'])) {
                        if (!$this->deleteItem($ruleTable, $i)) $res = false;
                    }
                }
            }
        }

        return $res;
    }



    private function deleteItem(string $table, string $id): bool
    {
        $data = &$this->data[$table][$id];
        try {
            foreach ($data['DELETE_QUERIES'] as $sql) {
                $this->getEntityManager()->getConnection()->exec($sql);
            }
            unset($this->data[$table][$id]);
            $res = true;
        } catch (\Exception $e) {
            $data['ERROR'] = $this->translate($e->getMessage());
            $res           = false;
        }

        return $res;
    }



    protected function subDelete(string $table, string $id, bool $force)
    {
        foreach ($this->data as $t => $ds) {
            foreach ($ds as $i => $d) {
                if ($d['PARENT_TABLE'] == $table && $d['PARENT_ID'] == $id && !$d['DELETE']) {
                    if ($force || !$d['VISIBLE']) {
                        $this->data[$t][$i]['DELETE'] = true;
                    }
                    $this->subDelete($t, $i, $force);
                }
            }
        }
    }
}
 No newline at end of file
+0 −1
Changes for module/Application/src/Application/Service/IntervenantService.php: 0 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -113,7 +113,6 @@ class IntervenantService extends AbstractEntityService

    public function getByCode(string $code): ?Intervenant
    {
        $code        = null;
        $anneeId     = $this->getServiceContext()->getAnnee()->getId();
        $statutId    = null;
        $structureId = $this->getServiceContext()->getStructure();
+5 −4
Changes for module/Application/src/Application/View/Helper/TreeViewHelper.php: 5 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -93,14 +93,15 @@ class TreeViewHelper extends AbstractViewHelper
            $html .= $this->getView()->tag('ul')->html($sHtml);
        }

        $attrs          = [
            'id' => $node->getId(),
        ];
        $attrs          = [];
        $attrs['id']    = $node->getId();
        $attrs['class'] = 'jstree-open';
        if ($node->getTitle()) {
            $attrs['title'] = $node->getTitle();
        }
        if ($node->getIcon()) {
            $attrs['data-jstree'] = [
                'icon' => $node->getIcon(),

            ];
        }

Loading