From 95dcca14abad9cae260f1ecd6ae6777bf82b0ac2 Mon Sep 17 00:00:00 2001
From: Jean-Philippe Metivier <jean-philippe.metivier@unicaen.fr>
Date: Tue, 26 Nov 2024 14:15:51 +0100
Subject: [PATCH] Export d'inscription

---
 .../Formation/config/merged/export.config.php |  99 +++++++++
 .../Formation/Controller/ExportController.php |  85 ++++++++
 .../Controller/ExportControllerFactory.php    |  38 ++++
 .../Inscription/InscriptionService.php        |  23 +-
 .../export/extraction-inscription.phtml       | 197 ++++++++++++++++++
 .../view/formation/export/index.phtml         |  34 +++
 6 files changed, 474 insertions(+), 2 deletions(-)
 create mode 100644 module/Formation/config/merged/export.config.php
 create mode 100644 module/Formation/src/Formation/Controller/ExportController.php
 create mode 100644 module/Formation/src/Formation/Controller/ExportControllerFactory.php
 create mode 100644 module/Formation/view/formation/export/extraction-inscription.phtml
 create mode 100644 module/Formation/view/formation/export/index.phtml

diff --git a/module/Formation/config/merged/export.config.php b/module/Formation/config/merged/export.config.php
new file mode 100644
index 00000000..dfe2d582
--- /dev/null
+++ b/module/Formation/config/merged/export.config.php
@@ -0,0 +1,99 @@
+<?php
+
+namespace Formation;
+
+use Formation\Controller\ExportController;
+use Formation\Controller\ExportControllerFactory;
+use Laminas\Router\Http\Literal;
+use Laminas\Router\Http\Segment;
+use UnicaenPrivilege\Guard\PrivilegeController;
+
+return [
+    'bjyauthorize' => [
+        'guards' => [
+            PrivilegeController::class => [
+                [
+                    'controller' => ExportController::class,
+                    'action' => [
+                        'index',
+                        'extraction-inscription',
+                    ],
+                    'roles' => [
+                    ],
+                ],
+            ],
+        ],
+    ],
+
+    'navigation' => [
+        'default' => [
+            'home' => [
+                'pages' => [
+                    'administration' => [
+                        'pages' => [
+                            'export' => [
+                                'label' => 'Extraction',
+                                'route' => 'export',
+                                'resource' => PrivilegeController::getResourceId(ExportController::class, 'index'),
+                                'order' => 3100,
+                                'icon' => 'fas fa-angle-right',
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+        ],
+    ],
+
+    'router' => [
+        'routes' => [
+            'export' => [
+                'type' => Literal::class,
+                'options' => [
+                    'route' => '/export',
+                    'defaults' => [
+                        /** @see ExportController::indexAction() */
+                        'controller' => ExportController::class,
+                        'action' => 'index',
+                    ],
+                ],
+                'may_terminate' => true,
+                'child_routes' => [
+                    'extraction-inscription' => [
+                        'type' => Segment::class,
+                        'options' => [
+                            'route' => '/extraction-inscription[/:csv]',
+                            'defaults' => [
+                                /** @see ExportController::extractionInscriptionAction() */
+                                'action' => 'extraction-inscription',
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+        ],
+    ],
+
+    'service_manager' => [
+        'factories' => [
+        ],
+    ],
+    'controllers' => [
+        'factories' => [
+            ExportController::class => ExportControllerFactory::class,
+        ],
+    ],
+    'form_elements' => [
+        'factories' => [
+        ],
+    ],
+    'hydrators' => [
+        'factories' => [
+        ],
+    ],
+    'view_helpers' => [
+        'invokables' => [
+        ],
+    ],
+
+];
\ No newline at end of file
diff --git a/module/Formation/src/Formation/Controller/ExportController.php b/module/Formation/src/Formation/Controller/ExportController.php
new file mode 100644
index 00000000..a3b8d720
--- /dev/null
+++ b/module/Formation/src/Formation/Controller/ExportController.php
@@ -0,0 +1,85 @@
+<?php
+
+namespace Formation\Controller;
+
+use Agent\Entity\Db\Agent;
+use DateTime;
+use Formation\Entity\Db\Domaine;
+use Formation\Entity\Db\StagiaireExterne;
+use Formation\Provider\Etat\InscriptionEtats;
+use Formation\Provider\Etat\SessionEtats;
+use Formation\Service\Inscription\InscriptionServiceAwareTrait;
+use Laminas\Mvc\Controller\AbstractActionController;
+use Laminas\View\Model\ViewModel;
+use UnicaenApp\View\Model\CsvModel;
+use UnicaenEtat\Service\EtatCategorie\EtatCategorieServiceAwareTrait;
+use UnicaenEtat\Service\EtatType\EtatTypeServiceAwareTrait;
+
+class ExportController extends AbstractActionController {
+    use EtatCategorieServiceAwareTrait;
+    use EtatTypeServiceAwareTrait;
+
+    use InscriptionServiceAwareTrait;
+
+
+    public function indexAction(): ViewModel
+    {
+        return new ViewModel([]);
+    }
+
+    public function extractionInscriptionAction(): ViewModel|CsvModel
+    {
+        $csv = $this->params()->fromRoute('csv');
+
+        $inscriptionCategorie = $this->getEtatCategorieService()->getEtatCategorieByCode(InscriptionEtats::TYPE);
+        $inscriptionEtats = $this->getEtatTypeService()->getEtatsTypesByCategorie($inscriptionCategorie);
+
+        $sessionCategorie = $this->getEtatCategorieService()->getEtatCategorieByCode(SessionEtats::TYPE);
+        $sessionEtats = $this->getEtatTypeService()->getEtatsTypesByCategorie($sessionCategorie);
+
+        $params = $this->params()->fromQuery();
+        $params['historise'] = '0';
+        $inscriptions = $this->getInscriptionService()->getInscriptionsWithFiltre($params);
+
+        if ($csv) {
+            $headers = ["stagiaire", "affectation", "action de formation", "domaines", "période", "Au plan de formation"];
+            $records = [];
+            foreach ($inscriptions as $inscription) {
+                $stagiaire = $inscription->getIndividu();
+                $affecation = null;
+                if ($stagiaire instanceof StagiaireExterne) $affecation = $stagiaire->getStructure();
+                if ($stagiaire instanceof Agent) {
+                    $structure = ($stagiaire->getAffectationPrincipale())?->getStructure();
+                    if ($structure) $affecation = (($structure->getNiv2() AND $structure->getNiv2() !== $structure)?($structure->getNiv2()->getLibelleCourt()." > "):"").$structure->getLibelleCourt();
+                }
+                $session = $inscription->getSession();
+                $action = $session->getFormation();
+                $domaines = array_map(function (Domaine $domaine) {return $domaine->getLibelle();}, $action->getDomaines());
+                $records[] = [
+                    "stagiaire" => $stagiaire->getDenomination(false),
+                    "affectation" => $affecation,
+                    "action de formation" => $action->getLibelle(),
+                    "domaines" => implode("\n",$domaines),
+                    "période" => $session->getPeriode(),
+                    "Au plan de formation" => (!empty($session->getDemandesExternes())) ? "Hors plan de formation":"Dans le plan de formation",
+                ];
+            }
+            $date = (new DateTime())->format('Ymd-His');
+            $filename="export_inscriptions_".$date.".csv";
+            $CSV = new CsvModel();
+            $CSV->setDelimiter(';');
+            $CSV->setEnclosure('"');
+            $CSV->setHeader($headers);
+            $CSV->setData($records);
+            $CSV->setFilename($filename);
+            return $CSV;
+        }
+        return new ViewModel([
+            'params' => $params,
+            'inscriptionEtats' => $inscriptionEtats,
+            'sessionEtats' => $sessionEtats,
+
+            'inscriptions' => $inscriptions,
+        ]);
+    }
+}
\ No newline at end of file
diff --git a/module/Formation/src/Formation/Controller/ExportControllerFactory.php b/module/Formation/src/Formation/Controller/ExportControllerFactory.php
new file mode 100644
index 00000000..bdd8fbf5
--- /dev/null
+++ b/module/Formation/src/Formation/Controller/ExportControllerFactory.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace Formation\Controller;
+
+use Formation\Service\Inscription\InscriptionService;
+use Psr\Container\ContainerExceptionInterface;
+use Psr\Container\ContainerInterface;
+use Psr\Container\NotFoundExceptionInterface;
+use UnicaenEtat\Service\EtatCategorie\EtatCategorieService;
+use UnicaenEtat\Service\EtatType\EtatTypeService;
+
+class ExportControllerFactory {
+
+
+    /**
+     * @throws ContainerExceptionInterface
+     * @throws NotFoundExceptionInterface
+     */
+    public function __invoke(ContainerInterface $container): ExportController
+    {
+        /**
+         * @var EtatCategorieService $etatCategorieService
+         * @var EtatTypeService $etatTypeService
+         * @var InscriptionService $inscriptionService
+         */
+        $etatCategorieService = $container->get(EtatCategorieService::class);
+        $etatTypeService = $container->get(EtatTypeService::class);
+        $inscriptionService = $container->get(InscriptionService::class);
+
+        $controller = new ExportController();
+        $controller->setEtatCategorieService($etatCategorieService);
+        $controller->setEtatTypeService($etatTypeService);
+        $controller->setInscriptionService($inscriptionService);
+
+        return $controller;
+    }
+
+}
\ No newline at end of file
diff --git a/module/Formation/src/Formation/Service/Inscription/InscriptionService.php b/module/Formation/src/Formation/Service/Inscription/InscriptionService.php
index c5a5eb0e..56ac2fd8 100644
--- a/module/Formation/src/Formation/Service/Inscription/InscriptionService.php
+++ b/module/Formation/src/Formation/Service/Inscription/InscriptionService.php
@@ -279,9 +279,20 @@ class InscriptionService
     {
         $qb = $this->createQueryBuilder()->orderBy('inscription.histoCreation', 'asc');
 
-        if (isset($params['etat'])) {
-            $qb = Inscription::decorateWithEtatsCodes($qb, 'inscription', [$params['etat']]);
+        if (isset($params['etat_inscription']) AND $params['etat_inscription'] != '') {
+            $qb = Inscription::decorateWithEtatsCodes($qb, 'inscription', [$params['etat_inscription']], 'inscriptionEtats');
         }
+        if (isset($params['etat_session']) AND $params['etat_session'] != '') {
+            $qb = Session::decorateWithEtatsCodes($qb, 'session', [$params['etat_session']], 'sessionEtats');
+        }
+        if (isset($params['liste']) AND $params['liste'] != '') {
+            if ($params['liste'] !== "non classée") {
+                $qb = $qb->andWhere('inscription.liste = :liste')->setParameter('liste', $params['liste']);
+            } else {
+                $qb = $qb->andWhere('inscription.liste IS NULL');
+            }
+        }
+
         if (isset($params['historise'])) {
             if ($params['historise'] === '1') $qb = $qb->andWhere('inscription.histoDestruction IS NOT NULL');
             if ($params['historise'] === '0') $qb = $qb->andWhere('inscription.histoDestruction IS NULL');
@@ -295,6 +306,14 @@ class InscriptionService
                 ->andWhere('journee.jour >= :debut')->setParameter('debut', $debut)
                 ->andWhere('journee.jour <= :fin')->setParameter('fin', $fin);
         }
+        if (isset($params['date_debut']) AND $params['date_debut'] !== "") {
+            $dateDebut = DateTime::createFromFormat('Y-m-d H:i', $params['date_debut'].' 06:00');
+            $qb = $qb->join('session.journees', 'journeeDebut')->andWhere('journeeDebut.jour >= :debut')->setParameter('debut', $dateDebut);
+        }
+        if (isset($params['date_fin'])  AND $params['date_fin'] !== "") {
+            $dateFin = DateTime::createFromFormat('Y-m-d H:i', $params['date_fin'].' 20:00');
+            $qb = $qb->join('session.journees', 'journeeFin')->andWhere('journeeFin.jour <= :fin')->setParameter('fin', $dateFin);
+        }
 
         $result = $qb->getQuery()->getResult();
         return $result;
diff --git a/module/Formation/view/formation/export/extraction-inscription.phtml b/module/Formation/view/formation/export/extraction-inscription.phtml
new file mode 100644
index 00000000..6f13c8ad
--- /dev/null
+++ b/module/Formation/view/formation/export/extraction-inscription.phtml
@@ -0,0 +1,197 @@
+<?php
+
+/**
+ * @see \Formation\Controller\ExportController::extractionInscriptionAction()
+ * @var EtatType[] $inscriptionEtats
+ * @var EtatType[] $sessionEtats
+ * @var Inscription[] $inscriptions
+ * @var array $params
+ *
+ **/
+
+use Agent\Entity\Db\Agent;
+use Formation\Entity\Db\Inscription;
+use Formation\Entity\Db\StagiaireExterne;
+use UnicaenEtat\Entity\Db\EtatType;
+
+$this->headTitle("Extraction d'inscription");
+
+?>
+
+<h1 class="page-header">
+    Extraction d'inscription
+</h1>
+
+<div class="card">
+    <div class="card-header bg-default">
+        Filtres pour l'extraction des inscriptions
+    </div>
+    <div class="card-body">
+        <form action="<?php $this->url('export/extraction-inscription', [], [], true); ?>" method="get">
+        <div class="row">
+            <div class="col-md-10">
+                <div class="row">
+                    <div class="col-md-4">
+                        <label for="etat_inscription">État de l'inscription :</label>
+                        <select id="etat_inscription" name="etat_inscription" class="selectpicker form-control">
+                            <option value="">Tous les états </option>
+                            <?php foreach ($inscriptionEtats as $etat) : ?>
+                                <option
+                                    value="<?php echo $etat->getCode(); ?>"
+                                    data-content='<?php echo $this->etattype($etat); ?> <?php echo htmlentities($etat->getLibelle()); ?>'
+                                    <?php if ($params['etat_inscription'] === $etat->getCode()) : ?> selected <?php endif;?>
+                                >
+                                    <?php echo $etat->getLibelle(); ?>
+                                </option>
+                            <?php endforeach; ?>
+                        </select>
+                    </div>
+                    <div class="col-md-4">
+                        <label for="etat_session">État de la session :</label>
+                        <select id="etat_session" name="etat_session" class="selectpicker form-control">
+                            <option value="">Tous les états </option>
+                            <?php foreach ($sessionEtats as $etat) : ?>
+                                <option
+                                    value="<?php echo $etat->getCode(); ?>"
+                                    data-content='<?php echo $this->etattype($etat); ?> <?php echo htmlentities($etat->getLibelle()); ?>'
+                                    <?php if ($params['etat_session'] === $etat->getCode()) : ?> selected <?php endif;?>
+                                >
+                                    <?php echo $etat->getLibelle(); ?>
+                                </option>
+                            <?php endforeach; ?>
+                        </select>
+                    </div>
+                    <div class="col-md-4">
+                        <label for="liste">Liste :</label>
+                        <select id="liste" name="liste" class="selectpicker form-control">
+                            <option value="">Toutes listes </option>
+                            <option value="<?php echo Inscription::PRINCIPALE; ?>"
+                                    <?php if (isset($params['liste']) AND $params['liste'] === Inscription::PRINCIPALE) : ?> selected <?php endif;?>
+                            >
+                                Principale
+                            </option>
+                            <option value="<?php echo Inscription::COMPLEMENTAIRE; ?>"
+                                <?php if (isset($params['liste']) AND $params['liste'] === Inscription::COMPLEMENTAIRE) : ?> selected <?php endif;?>
+                            >
+                                Complémentaire
+                            </option>
+                            <option value="non classée"
+                                <?php if (isset($params['liste']) AND $params['liste'] === "non classée") : ?> selected <?php endif;?>
+                            >
+                                Non classée
+                            </option>
+                        </select>
+                    </div>
+                    <div class="col-md-4">
+                        <label for="date_debut">Date de début</label>
+                        <input type="date" id="date_debut" name="date_debut" class="form-control"
+                               value="<?php if (isset($params['date_debut'])) echo $params['date_debut']; ?>"
+                        />
+                    </div>
+                    <div class="col-md-4">
+                        <label for="date_fin">Date de fin</label>
+                        <input type="date" id="date_fin" name="date_fin" class="form-control"
+                               value="<?php if (isset($params['date_fin'])) echo $params['date_fin']; ?>"
+                        />
+                    </div>
+                </div>
+
+            </div>
+            <div class="col-md-2">
+                <button class="btn btn-primary" id="filter">
+                    <span class="icon icon-filtrer"></span>
+                    Filtrer
+                </button>
+                <br>
+                <button class="btn btn-primary" id="clear">
+                    <span class="icon icon-gommer"></span>
+                    R.A.Z.
+                </button>
+            </div>
+        </div>
+        </form>
+    </div>
+</div>
+
+<?php /** @see \Formation\Controller\ExportController::extractionInscriptionAction(); */ ?>
+<a href="<?php echo $this->url('export/extraction-inscription', ['csv' => 'csv'], [], true); ?>" class="btn btn-primary">
+    <span class="icon icon-csv"></span>
+    Exporter au format CSV
+</a>
+
+<table class="table table-condensed" id="inscriptions">
+    <thead>
+    <tr>
+        <th> Stagiaire </th>
+        <th> Affectation </th>
+<!--        <th> État de l'inscription</th>-->
+        <th> Action de formation </th>
+        <th> Domaine </th>
+        <th> Période </th>
+<!--        <th> État de la sesion</th>-->
+<!--        <th> Liste </th>-->
+        <th> Au plan de formation</th>
+    </tr>
+    </thead>
+    <tbody>
+    <?php foreach ($inscriptions as $inscription) : ?>
+        <?php
+            $stagiaire = $inscription->getIndividu();
+            $affecation = null;
+            if ($stagiaire instanceof StagiaireExterne) $affecation = $stagiaire->getStructure();
+            if ($stagiaire instanceof Agent) {
+                $structure = ($stagiaire->getAffectationPrincipale())?->getStructure();
+                if ($structure) $affecation = (($structure->getNiv2() AND $structure->getNiv2() !== $structure)?($structure->getNiv2()->getLibelleCourt()." > "):"").$structure->getLibelleCourt();
+            }
+            $session = $inscription->getSession();
+            $action = $session->getFormation();
+        ?>
+        <tr>
+            <td data-order="<?php echo $stagiaire->getDenomination(false); ?>">
+                <?php echo $stagiaire->getDenomination(); ?>
+            </td>
+            <td> <?php echo $affecation; ?> </td>
+<!--            <td> --><?php //echo $this->etatinstance($inscription->getEtatActif()); ?><!--</td>-->
+            <td> <?php echo $action->getLibelle(); ?> </td>
+            <td>
+                <?php $domaines = $action->getDomaines(); ?>
+                <?php if (empty($domaines)): ?>
+                    <em>Aucun domaine</em>
+                <?php else : ?>
+                    <?php foreach ($domaines as $domaine) : ?>
+                        <?php echo $domaine->getLibelle(); ?><br/>
+                    <?php endforeach; ?>
+                <?php endif; ?>
+            </td>
+            <td> <?php echo $session->getPeriode(); ?> </td>
+<!--            <td> --><?php //echo $this->etatinstance($session->getEtatActif()); ?><!--</td>-->
+<!--            <td> --><?php //echo $inscription->getListe(); ?><!-- </td>-->
+            <td>
+                <?php if (!empty($session->getDemandesExternes())) : ?>
+                    Hors plan de formation
+                <?php else: ?>
+                    Dans le plan de formation
+                <?php endif ?>
+            </td>
+        </tr>
+    <?php endforeach; ?>
+    </tbody>
+</table>
+
+<script>
+    $(document).ready(function () {
+        $('table#inscriptions').DataTable({
+            // sorting: false,
+            paging: false,
+            autoWidth: false,
+            language: {
+                url: '/js/datatables_fr.json'
+            }
+        });
+    });
+
+    $('button#clear').click(function (e) {
+        e.preventDefault();
+        window.location = '?';
+    });
+</script>
diff --git a/module/Formation/view/formation/export/index.phtml b/module/Formation/view/formation/export/index.phtml
new file mode 100644
index 00000000..8af82b82
--- /dev/null
+++ b/module/Formation/view/formation/export/index.phtml
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * @see \Formation\Controller\ExportController::indexAction())
+ */
+
+$this->headTitle("Extractions");
+
+?>
+
+<h1 class="page-header">
+    Extractions
+</h1>
+
+<h2>
+    Extractions basées sur les inscriptions
+</h2>
+
+<div class="row">
+    <div class="col-md-10">
+        Réaliser des extractions d'inscriptions en fonction de critères liés aux états des inscriptions, des sessions associées, des listes, ...
+    </div>
+    <div class="col-md-2">
+        <a href="<?php echo $this->url('export/extraction-inscription',[],[], true); ?>"
+           class="btn btn-secondary"
+        >
+            <span class="icon icon-listing"></span>
+            Accéder à l'extraction
+        </a>
+
+    </div>
+</div>
+
+
-- 
GitLab