Commit 719829eb authored by Antony Le Courtes's avatar Antony Le Courtes
Browse files

- Gestion de la reconduction partiel d'une formation

- Gestion checkbox et disable des elements et etape déjà reconduits
- UX
parent 8081c1fe
Loading
Loading
Loading
Loading
+234 −111
Original line number Diff line number Diff line
@@ -43,104 +43,13 @@ class OffreFormationController extends AbstractController



    protected function initFilters()
    {
        /* Mise en place des filtres */
        $this->em()->getFilters()->enable('historique')->init([
            ElementPedagogique::class,
            TypeFormation::class,
            GroupeTypeFormation::class,
            TypeModulateur::class,
        ]);
        $this->em()->getFilters()->enable('annee')->init([
            ElementPedagogique::class,
            Etape::class,
        ]);
    }



    protected function getParams()
    {
        $structure = $this->context()->structureFromQuery() ?: $this->getServiceContext()->getStructure();
        $niveau    = $this->context()->niveauFromQuery();
        $etape     = $this->context()->etapeFromQuery();
        if ($niveau) $niveau = $this->getServiceNiveauEtape()->get($niveau); // entité Niveau
        return [$structure, $niveau, $etape];
    }



    protected function getNeep($structure, $niveau, $etape)
    {
        if (!$structure) return [[], [], []];

        $niveaux  = [];
        $etapes   = [];
        $elements = [];

        $query = $this->em()->createQuery('SELECT
                partial e.{id,code,libelle,sourceCode,niveau,histoDestruction},
                partial tf.{id},
                partial gtf.{id, libelleCourt, ordre},
                partial ep.{id,code,libelle,sourceCode,etape,periode,tauxFoad,fi,fc,fa,tauxFi,tauxFc,tauxFa}
            FROM
              Application\Entity\Db\Etape e
              JOIN e.structure s
              JOIN e.typeFormation tf
              JOIN tf.groupe gtf
              LEFT JOIN e.elementPedagogique ep
            WHERE
              s = :structure OR ep.structure = :structure
            ORDER BY
              gtf.ordre, e.niveau
            ');
        $query->setParameter('structure', $structure);
        $result = $query->getResult();

        foreach ($result as $object) {
            if ($object instanceof Etape) {
                $n                    = NiveauEtape::getInstanceFromEtape($object);
                if ($object->estNonHistorise()) {
                    $niveaux[$n->getId()] = $n;
                }
                if (!$niveau || $niveau->getId() == $n->getId()) {
                    if ($object->estNonHistorise() || $object->getElementPedagogique()->count() > 0){
                        $etapes[] = $object;
                    }
                    if (!$etape || $etape === $object) {
                        foreach ($object->getElementPedagogique() as $ep) {
                            $elements[$ep->getId()] = $ep;
                        }
                    }
                }
            }
        }

        /* Tris */
        uasort($etapes, function (Etape $e1, Etape $e2) {
            $e1Lib = ($e1->getElementPedagogique()->isEmpty() ? 'a_' : 'z_') . strtolower(trim($e1->getLibelle()));
            $e2Lib = ($e2->getElementPedagogique()->isEmpty() ? 'a_' : 'z_') . strtolower(trim($e2->getLibelle()));

            return $e1Lib > $e2Lib;
        });

        uasort($elements, function (ElementPedagogique $e1, ElementPedagogique $e2) {
            $e1Lib = strtolower(trim($e1->getEtape()->getLibelle() . ' ' . $e1->getLibelle()));
            $e2Lib = strtolower(trim($e2->getEtape()->getLibelle() . ' ' . $e2->getLibelle()));

            return $e1Lib > $e2Lib;
        });

        return [$niveaux, $etapes, $elements];
    }



    public function indexAction()
    {
        $this->initFilters();


        list($structure, $niveau, $etape) = $this->getParams();

        // persiste les filtres dans le contexte local
@@ -236,18 +145,26 @@ class OffreFormationController extends AbstractController
    public function reconductionAction()
    {

        $this->initFilters();
        $this->initFilterHistorique();
        list($structure, $niveau, $etape) = $this->getParams();

        $structures = $this->getServiceStructure()->getList($this->getServiceStructure()->finderByEnseignement());
        $anneeEnCours = $this->getServiceContext()->getAnnee();
        list($offresComplementaires, $mappingEtape, $reconductionTotale) = $this->getOffreComplementaire();


        $reconductionStep = '';
        $messageStep = '';
        $fromPost = false;

        //Récupération des paramètres GET
        list($structure, $niveau, $etape) = $this->getParams();

        $request = $this->getRequest();
        if ($request->isPost()) {
            $datas = $request->getPost();
            $fromPost = true;

            //Ajout du mapping des EtapesN et EtapesN1 pour pouvoir reconduire un element pédagogique sur une etape déjà reconduite.
            $datas['mappingEtape'] = $mappingEtape;
            $reconductionProcessus = $this->getProcessusReconduction();
            try{
                if($reconductionProcessus->reconduction($datas))
@@ -265,39 +182,245 @@ class OffreFormationController extends AbstractController
            }

        }


        //Chargement JS nécessaire uniquement sur cette page
        $viewHelperManager = $this->getServiceLocator()->get('ViewHelperManager');
        $headScript = $viewHelperManager->get('headScript');
        $headScript->offsetSetFile(100, '/js/reconduction-offre.js');


        return [
            'fromPost'              => $fromPost,
            'offresComplementaires' => $offresComplementaires,
            'reconductionTotale'    => $reconductionTotale,
            'structure'             => $structure,
            'structures'            => $structures,
            'anneeEnCours'          => $anneeEnCours,
            'reconductionStep'      => $reconductionStep,
            'messageStep'           => $messageStep
        ];



    }



    protected function initFilters()
    {
        $this->initFilterAnnee();
        $this->initFilterHistorique();

    }

    protected function initFilterAnnee()
    {
        $this->em()->getFilters()->enable('annee')->init([
            ElementPedagogique::class,
            Etape::class,
        ]);
    }

    protected function initFilterHistorique()
    {
        /* Mise en place des filtres */
        $this->em()->getFilters()->enable('historique')->init([
            ElementPedagogique::class,
            TypeFormation::class,
            GroupeTypeFormation::class,
            TypeModulateur::class,
        ]);
    }


    protected function disableFilters($name)
    {
        $this->em()->getFilters()->disable($name);
    }



    protected function getParams()
    {
        $structure = $this->context()->structureFromQuery() ?: $this->getServiceContext()->getStructure();
        $niveau    = $this->context()->niveauFromQuery();
        $etape     = $this->context()->etapeFromQuery();
        if ($niveau) $niveau = $this->getServiceNiveauEtape()->get($niveau); // entité Niveau
        return [$structure, $niveau, $etape];
    }



    protected function getNeep($structure, $niveau, $etape, $annee = null)
    {
        if(is_null($annee))
        {
            $annee = $this->getServiceContext()->getAnnee();
        }

        if (!$structure) return [[], [], []];

        $niveaux  = [];
        $etapes   = [];
        $elements = [];

        $query = $this->em()->createQuery('SELECT
                partial e.{id,code,annee,libelle,sourceCode,niveau,histoDestruction},
                partial tf.{id},
                partial gtf.{id, libelleCourt, ordre},
                partial ep.{id,code,libelle,sourceCode,etape,periode,tauxFoad,fi,fc,fa,tauxFi,tauxFc,tauxFa}
            FROM
              Application\Entity\Db\Etape e
              JOIN e.structure s
              JOIN e.typeFormation tf
              JOIN tf.groupe gtf
              LEFT JOIN e.elementPedagogique ep
            WHERE
              (s = :structure OR ep.structure = :structure) AND e.annee = :annee
            ORDER BY
              gtf.ordre, e.niveau
            ');
        $query->setParameter('structure', $structure);
        $query->setParameter('annee', $annee);
        $result = $query->getResult();

        foreach ($result as $object) {
            if ($object instanceof Etape) {
                $n                    = NiveauEtape::getInstanceFromEtape($object);
                if ($object->estNonHistorise()) {
                    $niveaux[$n->getId()] = $n;
                }
                if (!$niveau || $niveau->getId() == $n->getId()) {
                    if ($object->estNonHistorise() || $object->getElementPedagogique()->count() > 0){
                        $etapes[] = $object;
                    }
                    if (!$etape || $etape === $object) {
                        foreach ($object->getElementPedagogique() as $ep) {
                            $elements[$ep->getId()] = $ep;
                        }
                    }
                }
            }
        }

        /* Tris */
        uasort($etapes, function (Etape $e1, Etape $e2) {
            $e1Lib = ($e1->getElementPedagogique()->isEmpty() ? 'a_' : 'z_') . strtolower(trim($e1->getLibelle()));
            $e2Lib = ($e2->getElementPedagogique()->isEmpty() ? 'a_' : 'z_') . strtolower(trim($e2->getLibelle()));

            return $e1Lib > $e2Lib;
        });

        uasort($elements, function (ElementPedagogique $e1, ElementPedagogique $e2) {
            $e1Lib = strtolower(trim($e1->getEtape()->getLibelle() . ' ' . $e1->getLibelle()));
            $e2Lib = strtolower(trim($e2->getEtape()->getLibelle() . ' ' . $e2->getLibelle()));

            return $e1Lib > $e2Lib;
        });

        return [$niveaux, $etapes, $elements];
    }


    /**
     * @return array
     */

    public function getOffreComplementaire()
    {
        $offresComplementaires = [];
        $anneeEnCours = $this->getServiceContext()->getAnnee();
        $anneeSuivante = $this->getServiceAnnee()->getSuivante($anneeEnCours);

        //Récupération des paramètres GET
        list($structure, $niveau, $etape) = $this->getParams();

        $this->getServiceLocalContext()
            ->setStructure($structure)
            ->setNiveau($niveau)
            ->setEtape($etape);

        list($niveaux, $etapes, $elements) = $this->getNeep($structure, $niveau, $etape);

        //Offre année en cours
        list($niveaux, $etapes, $elements) = $this->getNeep($structure, $niveau, $etape, $anneeEnCours);
        //Offre année suivante
        list($niveauxN1, $etapesN1, $elementsN1) = $this->getNeep($structure, $niveau, $etape, $anneeSuivante);
        //Organisation pour traitement dans la vue
        $offresComplementaires = [];
        $codesEtapeN1 = [];
        $codesElementN1 = [];
        $etapesNonReconduits = array_diff($etapes, $etapesN1);
        $elementsNonReconduits = array_diff($elements, $elementsN1);

        $reconductionTotale = 'non';
        if(empty($etapesNonReconduits) && empty($elementsNonReconduits))
        {
            $reconductionTotale = 'oui';
        }

        foreach($elementsN1 as $v)
        {
            $codesElementN1[] = $v->getCode();
        }
        foreach($etapesN1 as $v)
        {
            $codesEtapeN1[] = $v->getCode();
        }

        foreach ($etapes as $v)
        {
            $offresComplementaires[$v->getId()]['reconduction_partiel'] = 'non';
            $offresComplementaires[$v->getId()]['reconduction'] = (in_array($v->getCode(), $codesEtapeN1))?'oui':'non';
            $offresComplementaires[$v->getId()]['etape'] = $v;
            $offresComplementaires[$v->getId()]['elements_pedagogique'] = [];

        }

        foreach ($elements as $v)
        {

            $etapeId = $v->getEtape()->getId();
            $offresComplementaires[$etapeId]['elements_pedagogique'][] = $v;

            if(!in_array($v->getCode(), $codesElementN1))
            {
                $offresComplementaires[$etapeId]['reconduction_partiel'] = 'oui';
            }

        //Chargement JS nécessaire uniquement sur cette page
        $viewHelperManager = $this->getServiceLocator()->get('ViewHelperManager');
        $headScript = $viewHelperManager->get('headScript');
        $headScript->offsetSetFile(100, '/js/reconduction-offre.js');
            $offresComplementaires[$etapeId]['elements_pedagogique'][$v->getId()]['reconduction'] = (in_array($v->getCode(), $codesElementN1))?'oui':'non';
            $offresComplementaires[$etapeId]['elements_pedagogique'][$v->getId()]['element'] = $v;
        }

        return [
            'offresComplementaires' => $offresComplementaires,
            'structure'        => $structure,
            'structures'       => $structures,
            'anneeEnCours'     => $anneeEnCours,
            'reconductionStep' => $reconductionStep,
            'messageStep'      => $messageStep
        ];
        $mappingEtape = $this->createMappingEtapeNEtapeN1($etapes, $etapesN1);


        return [$offresComplementaires, $mappingEtape, $reconductionTotale];
    }

    public function createMappingEtapeNEtapeN1($etapesN, $etapesN1)
    {
        $codesEtapeN = [];
        $codesEtapeN1 = [];
        $mappingEtape = [];


        foreach($etapesN1 as $v)
        {
            $codesEtapeN1[$v->getCode()] = $v->getId();
        }

        foreach($etapesN as $v)
        {
            $codesEtapeN[$v->getCode()] = $v->getId();
        }

        foreach($codesEtapeN as $k => $v)
        {
            if(array_key_exists($k, $codesEtapeN1))
            {
                $mappingEtape[$v] = $codesEtapeN1[$k];
            }
        }

       return $mappingEtape;



+10 −0
Original line number Diff line number Diff line
@@ -37,6 +37,16 @@ class VolumeHoraireEns implements HistoriqueAwareInterface, ImportAwareInterface
    protected $groupes;


    public function __clone()
    {
        if($this->id)
        {
            $this->id = null;
        }
        return $this;
    }



    /**
     * Get id
+9 −2
Original line number Diff line number Diff line
@@ -2,13 +2,13 @@

namespace Application\Processus\Factory;

use Application\Entity\Db\ElementPedagogique;
use Application\Processus\ReconductionProcessus;
use Application\Service\AnneeService;
use Application\Service\CheminPedagogiqueService;
use Application\Service\ContextService;
use Application\Service\ElementPedagogiqueService;
use Application\Service\EtapeService;
use Application\Service\VolumeHoraireEnsService;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

@@ -32,9 +32,16 @@ class ReconductionProcessusFactory implements FactoryInterface
        $etapeService = \Application::$container->get(EtapeService::class);
        $elementPedagogiqueService = \Application::$container->get(ElementPedagogiqueService::class);
        $cheminPedagogiqueService = \Application::$container->get(CheminPedagogiqueService::class);
        $volumeHoraireEnsService = \Application::$container->get(VolumeHoraireEnsService::class);
        $anneeService = \Application::$container->get(AnneeService::class);
        $contextService = \Application::$container->get(ContextService::class);
        $processus = new ReconductionProcessus($etapeService, $elementPedagogiqueService, $cheminPedagogiqueService, $anneeService, $contextService);

        $processus = new ReconductionProcessus($etapeService,
                                               $elementPedagogiqueService,
                                               $cheminPedagogiqueService,
                                               $volumeHoraireEnsService,
                                               $anneeService,
                                               $contextService);

        return $processus;
    }
+45 −6
Original line number Diff line number Diff line
@@ -2,11 +2,14 @@

namespace Application\Processus;

use Application\Entity\Db\VolumeHoraire;
use Application\Entity\Db\VolumeHoraireEns;
use Application\Service\AnneeService;
use Application\Service\CheminPedagogiqueService;
use Application\Service\ContextService;
use Application\Service\ElementPedagogiqueService;
use Application\Service\EtapeService;
use Application\Service\VolumeHoraireEnsService;
use Zend\Debug\Debug;
use Zend\Stdlib\Parameters;

@@ -20,6 +23,7 @@ class ReconductionProcessus extends AbstractProcessus
    protected $etapeService;
    protected $elementPedagogiqueService;
    protected $cheminPedagogiqueService;
    protected $volumeHoraireEnsService;
    protected $anneeService;
    protected $contextService;

@@ -27,33 +31,59 @@ class ReconductionProcessus extends AbstractProcessus
    public function __construct(EtapeService $etapeService,
                                ElementPedagogiqueService $elementPedagogiqueService,
                                CheminPedagogiqueService $cheminPedagogiqueService,
                                VolumeHoraireEnsService $volumeHoraireEnsService,
                                AnneeService $anneeService,
                                ContextService $contextService)
    {
        $this->etapeService = $etapeService;
        $this->elementPedagogiqueService = $elementPedagogiqueService;
        $this->cheminPedagogiqueService = $cheminPedagogiqueService;
        $this->volumeHoraireEnsService = $volumeHoraireEnsService;
        $this->anneeService = $anneeService;
        $this->contextService = $contextService;
    }



    public function reconduction(Parameters $datas)
    {
        if(!empty($datas['etape']))
        if(empty($datas['element']) && empty($datas['etape']))
        {
            Throw new \Exception('Aucune donnée à reconduire');
        }

        if(empty($datas['etape']))
        {
            $datas['etape'] = [];
        }
        $etapeOfElements = array_keys($datas['element']);
        $etapeManquante = array_diff($etapeOfElements,$datas['etape']);
        $etapes = array_merge($datas['etape'], $etapeManquante);

        if(!empty($etapes))
        {
            $anneeEnCours = $this->contextService->getAnnee();
            $em = $this->getEntityManager();
            $dateDuJour = new \DateTime();
            $dateDuJour->format('d/m/Y');
            foreach($datas['etape'] as $idEtape)
            foreach($etapes as $idEtape)
            {
                if(in_array($idEtape, $etapeManquante))
                {
                    if(!array_key_exists($idEtape, $datas['mappingEtape']))
                    {
                        Throw new \Exception('Impossible de reconduire les éléments sélectionné');
                    }
                    $idEtapeN1 = $datas['mappingEtape'][$idEtape];
                    $etapeReconduit = $this->etapeService->get($idEtapeN1);
                }
                else{

                    $etapeEnCours = $this->etapeService->get($idEtape);
                    $etapeReconduit= clone $etapeEnCours;
                    $etapeReconduit->setAnnee($this->anneeService->getSuivante($anneeEnCours));
                    $etapeReconduit->setSpecifiqueEchanges(false);
                    $etapeReconduit->setHistoCreation($dateDuJour);
                    $em->persist($etapeReconduit);
                }
                //Reconduction des éléments pédagogiques pour cette étape
                if(array_key_exists($idEtape, $datas['element']))
                {
@@ -67,7 +97,7 @@ class ReconductionProcessus extends AbstractProcessus
                        //ajout de l'élément à l'étape
                        $etapeReconduit->addElementPedagogique($elementReconduit);
                        $em->persist($elementReconduit);
                        //Recondution des chemins pédagogiques
                        //Reconduction des chemins pédagogiques
                        $cheminsPedagogique = $elementEnCours->getCheminPedagogique();
                        foreach($cheminsPedagogique as $chemin)
                        {
@@ -77,6 +107,16 @@ class ReconductionProcessus extends AbstractProcessus
                            $cheminReconduit->setHistoCreation($dateDuJour);
                            $em->persist($cheminReconduit);
                        }
                        //Reconduction des volumes horaires
                        $volumesHoraire = $elementEnCours->getVolumeHoraireEns();
                        foreach($volumesHoraire as $volume)
                        {
                            $volumeReconduit = clone $volume;
                            $volumeReconduit->setHistoCreation($dateDuJour);
                            $volumeReconduit->setElementPedagogique($elementReconduit);
                            $elementReconduit->addVolumeHoraireEns($volumeReconduit);
                            $em->persist($volumeReconduit);
                        }
                        unset($elementReconduit, $elementEnCours);
                    }
                }
@@ -93,5 +133,4 @@ class ReconductionProcessus extends AbstractProcessus
      return true;
    }


}
 No newline at end of file
+31 −12
Original line number Diff line number Diff line
@@ -21,6 +21,11 @@
</div>
<div class="row" style="margin:0 5px 0 5px;">
    <div class="col-11">



        <h3>Offre de formation complémantaire / Année universitaire :  <?php echo $anneeEnCours->getLibelle(); ?></h3>
        <br/>
        <?php
        if($reconductionStep)
        {
@@ -30,17 +35,24 @@
            echo "<p class=\"bg-danger\" style=\"padding:10px;\">La reconductiond de l'offre de formation a échoué : <br/><br/>" .  $messageStep . "</p>";
        }
        ?>


        <h3>Offre de formation complémantaire / Année universitaire :  <?php echo $anneeEnCours->getLibelle(); ?></h3>
        <br/>
        <?php if($fromPost): ?>
           <p> <a href="<?= $this->url('of/reconduction') ?>" >Retour</a></p>
        <?php else: ?>
        <form action="<?php echo $_SERVER['REQUEST_URI']; ?>" method="POST" id="form-reconduction">

            <?php foreach ($offresComplementaires as $ec): ?>
                <?php if($ec['reconduction_partiel'] == 'oui'): ?>
                    <table class="reconduction-offre table table-bordered table-condensed table-hover">
                <?php else: ?>
                    <table class="reconduction-offre table table-bordered table-condensed table-hover" >
                <?php endif; ?>
                    <thead>
                        <tr>
                        <tr class="<?php if($ec['reconduction'] == 'oui'){echo "active";}?>">
                            <?php if($ec['reconduction'] == 'oui'): ?>
                                <th><input title="Formation déjà reconduite pour l'année prochaine"  type="checkbox" class="checkbox-formation" disabled="disabled" name="etape[]" value="<?= $ec['etape']->getId(); ?>"/></th>
                            <?php else: ?>
                                <th><input type="checkbox" class="checkbox-formation" checked="checked" name="etape[]" value="<?= $ec['etape']->getId(); ?>"/></th>
                            <?php endif; ?>
                        <th colspan="6">Formation : <?= $ec['etape']->__toString() . ' (' . $ec['etape']->getAnnee()->getLibelle() . ')'; ?></th>
                        </tr>
                        <tr>
@@ -62,13 +74,19 @@
                    <?php } ?>

                        <?php foreach ($ec['elements_pedagogique'] as $ep): ?>
                            <tr id="<?= $ep->getId() ?>">
                                <td><input class="checkbox-element" type="checkbox" checked="checked" name="element[<?php echo $ec['etape']->getId();?>][]" value="<?= $ep->getId(); ?>"/></td>
                                <td class="element"><?= $ep->getCode() ?></td>
                                <td class="element"><?= $this->elementPedagogique($ep)->renderLink($ep->getLibelle()) ?></td>
                                <td class="periode"><?= $ep->getPeriode() ?: "" ?></td>
                                <td><?= (bool)$ep->getTauxFoad() ? "Oui" : "Non" ?></td>
                                <td><?= $ep->getRegimesInscription(true) ?></td>
                            <tr id="<?= $ep['element']->getId() ?>" class="<?php if($ep['reconduction'] == 'oui'){echo "active";}?>">
                                <?php if($ep['reconduction'] == 'oui'): ?>
                                    <td>
                                        <input title="Elément pédagogique déjà reconduit pour l'année prochaine" class="checkbox-element" disabled="disabled" type="checkbox" name="element[<?php echo $ec['etape']->getId();?>][]" value="<?= $ep['element']->getId(); ?>"/>
                                    </td>
                                <?php else: ?>
                                    <td><input class="checkbox-element" type="checkbox" checked="checked" name="element[<?php echo $ec['etape']->getId();?>][]" value="<?= $ep['element']->getId(); ?>"/></td>
                                <?php endif; ?>
                                <td class="element"><?= $ep['element']->getCode() ?></td>
                                <td class="element"><?= $this->elementPedagogique($ep['element'])->renderLink($ep['element']->getLibelle()) ?></td>
                                <td class="periode"><?= $ep['element']->getPeriode() ?: "" ?></td>
                                <td><?= (bool)$ep['element']->getTauxFoad() ? "Oui" : "Non" ?></td>
                                <td><?= $ep['element']->getRegimesInscription(true) ?></td>
                            </tr>
                        <?php endforeach; ?>
                    </tbody>
@@ -76,6 +94,7 @@
            <?php endforeach; ?>
            <input id="reconduction-button" class="btn btn-primary" type="button" value="Reconduire l'offre séléctionnée"/>
        </form>
        <?php endif; ?>

    </div>
</div>
Loading