From 3713e31c9720610c8911bc0cd281a66b9c9e6615 Mon Sep 17 00:00:00 2001
From: Jean-Philippe Metivier <jean-philippe.metivier@unicaen.fr>
Date: Wed, 4 Dec 2024 09:39:58 +0100
Subject: [PATCH] Emargement as template

---
 module/Agent/src/Entity/Db/Agent.php          | 11 ++++
 .../document/pdf/entete-logo-ccc.phtml        |  2 +-
 .../formation-instance-document.config.php    | 22 ++-----
 .../FormationInstanceDocumentController.php   | 58 ++++++++++++-----
 .../src/Formation/Entity/Db/Seance.php        | 20 ++++++
 .../src/Formation/Entity/Db/Session.php       | 65 ++++++++++++++++++-
 .../Provider/Template/PdfTemplates.php        |  1 +
 .../Service/Seance/SeanceService.php          |  2 +-
 .../view/formation/session/afficher.phtml     |  8 +--
 9 files changed, 150 insertions(+), 39 deletions(-)

diff --git a/module/Agent/src/Entity/Db/Agent.php b/module/Agent/src/Entity/Db/Agent.php
index 407dd1f6..750fd318 100644
--- a/module/Agent/src/Entity/Db/Agent.php
+++ b/module/Agent/src/Entity/Db/Agent.php
@@ -204,6 +204,17 @@ class Agent implements
         return null;
     }
 
+    public function getStructure(): string
+    {
+        $affectation = $this->getAffectationPrincipale();
+        if ($affectation === null) return 'Aucune structure connue';
+
+        $structure = $affectation->getStructure();
+        $niveau2 = $structure->getNiv2();
+        if ($structure === $niveau2) { return $structure->getLibelleLong(); }
+        return $niveau2->getLibelleLong() . " > ". $structure->getLibelleLong();
+    }
+
     /** @return AgentEchelon[] */
     public function getEchelons(?DateTime $date = null, bool $histo = false): array
     {
diff --git a/module/Application/view/application/document/pdf/entete-logo-ccc.phtml b/module/Application/view/application/document/pdf/entete-logo-ccc.phtml
index 2fd7deef..f1d18a18 100644
--- a/module/Application/view/application/document/pdf/entete-logo-ccc.phtml
+++ b/module/Application/view/application/document/pdf/entete-logo-ccc.phtml
@@ -11,7 +11,7 @@
     <tr>
         <td>
             <img style='height:3cm;' src='data:image/png;base64,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' />
-            <img style='height:3cm;' src='<?php echo $image; ?>' />
+            <img style='height:3cm;' src='<?php echo $image; ?>' alt="logo de l'établissement"/>
         </td>
         <td>
             <div style="display: inline-block; margin-right: 0;">
diff --git a/module/Formation/config/merged/formation-instance-document.config.php b/module/Formation/config/merged/formation-instance-document.config.php
index 57cb7aaf..81813b31 100644
--- a/module/Formation/config/merged/formation-instance-document.config.php
+++ b/module/Formation/config/merged/formation-instance-document.config.php
@@ -52,8 +52,7 @@ return [
                 [
                     'controller' => FormationInstanceDocumentController::class,
                     'action' => [
-                        'export-emargement',
-                        'export-tous-emargements',
+                        'generer-emargement',
                     ],
                     'privileges' => [
                         FormationinstancedocumentPrivileges::FORMATIONINSTANCEDOCUMENT_EMARGEMENT
@@ -116,25 +115,14 @@ return [
                             ],
                         ],
                     ],
-                    'export-emargement' => [
+                    'generer-emargement' => [
                         'type' => Segment::class,
                         'options' => [
-                            'route' => '/export-emargement/:journee',
+                            'route' => '/generer-emargement/:session[/:seance]',
                             'defaults' => [
-                                /** @see FormationInstanceDocumentController::exportEmargementAction() */
+                                /** @see FormationInstanceDocumentController::genererEmargementAction() */
                                 'controller' => FormationInstanceDocumentController::class,
-                                'action' => 'export-emargement',
-                            ],
-                        ],
-                    ],
-                    'export-tous-emargements' => [
-                        'type' => Segment::class,
-                        'options' => [
-                            'route' => '/export-tous-emargements/:session',
-                            'defaults' => [
-                                /** @see FormationInstanceDocumentController::exportTousEmargementsAction() */
-                                'controller' => FormationInstanceDocumentController::class,
-                                'action' => 'export-tous-emargements',
+                                'action' => 'generer-emargement',
                             ],
                         ],
                     ],
diff --git a/module/Formation/src/Formation/Controller/FormationInstanceDocumentController.php b/module/Formation/src/Formation/Controller/FormationInstanceDocumentController.php
index 6848e465..218e494b 100644
--- a/module/Formation/src/Formation/Controller/FormationInstanceDocumentController.php
+++ b/module/Formation/src/Formation/Controller/FormationInstanceDocumentController.php
@@ -49,6 +49,49 @@ class FormationInstanceDocumentController extends AbstractActionController
         $this->etablissementInfos[$clef] = $valeur;
     }
 
+    /**
+     * @throws MpdfException
+     */
+    public function genererEmargementAction(): ?string
+    {
+        $session = $this->getSessionService()->getRequestedSession($this);
+        $seance = $this->getSeanceService()->getRequestedSeance($this, 'seance');
+
+        if ($seance !== null) {
+            $seances = [$seance];
+            $title = "Emargement_Session_" . $session->getId() . "_" . $seance->getId();
+        } else {
+            $seances = $session->getSeances();
+            $seances = array_filter($seances, function (Seance $seance) {
+                return $seance->estNonHistorise();
+            });
+            $title = "Emargement_Session_" . $session->getId();
+        }
+
+
+        $rendus = [];
+        foreach ($seances as $seance) {
+            $vars = [
+                'session' => $session,
+                'seance' => $seance,
+                'MacroService' => $this->getMacroService(),
+                'UrlService' => $this->getUrlService(),
+            ];
+            $rendus[$seance->getId()] = $this->getRenduService()->generateRenduByTemplateCode(PdfTemplates::FORMATION_EMARGEMENT, $vars, false);
+        }
+
+        $exporter = new PdfExporter();
+        $exporter->setRenderer($this->renderer);
+        $exporter->getMpdf()->SetTitle($title);
+        $exporter->setHeaderScript('/application/document/pdf/entete-logo-ccc', null, $this->etablissementInfos);
+        $exporter->setFooterScript('/application/document/pdf/pied-vide');
+        $exporter->getMpdf()->SetMargins(0, 0, 50);
+        foreach ($seances as $seance) {
+            $exporter->addBodyHtml($rendus[$seance->getId()]->getCorps());
+        }
+        return $exporter->export($title);
+    }
+
     public function exportEmargementAction(): void
     {
         $journee = $this->getSeanceService()->getRequestedSeance($this);
@@ -76,21 +119,6 @@ class FormationInstanceDocumentController extends AbstractActionController
         exit;
     }
 
-    #[NoReturn] public function exportTousEmargementsAction(): void
-    {
-        $instance = $this->getSessionService()->getRequestedSession($this);
-        $journees = $instance->getSeances();
-        $journees = array_filter($journees, function (Seance $a) {
-            return $a->estNonHistorise();
-        });
-
-        $exporter = new EmargementPdfExporter($this->renderer, 'A4');
-        $exporter->setVars([]);
-        $filemane = "formation_" . $instance->getFormation()->getId() . "_du_" . str_replace("/", "-", $instance->getDebut()) . "_au_" . str_replace("/", "-", $instance->getFin()) . "_emargements.pdf";
-        $exporter->exportAll($journees, $filemane);
-        exit;
-    }
-
     /**
      * @throws MpdfException
      */
diff --git a/module/Formation/src/Formation/Entity/Db/Seance.php b/module/Formation/src/Formation/Entity/Db/Seance.php
index e302b841..f6c3aac5 100644
--- a/module/Formation/src/Formation/Entity/Db/Seance.php
+++ b/module/Formation/src/Formation/Entity/Db/Seance.php
@@ -221,4 +221,24 @@ class Seance implements HistoriqueAwareInterface, HasSourceInterface
         $session = $this->getInstance();
         return ($session->getSeances() === null OR $session->getSeances() === [] OR $this->getDateFin()->format('d/m/Y H:i') === $session->getFin());
     }
+
+    /**
+     * @noinspection PhpUnused
+     * MACRO SEANCE#lieu
+     */
+    public function toStringLieu(): string
+    {
+        if ($this->getLieu() === null) return "Aucun lieu connu";
+        return $this->getLieu()->getBatiment(). " " .$this->getLieu()->getLibelle() . " - " . $this->getLieu()->getCampus() . " - " . $this->getLieu()->getVille();
+    }
+
+    /**
+     * @noinspection PhpUnused
+     * MACRO SEANCE#periode
+     */
+    public function getPeriode() : string
+    {
+        if (!$this->getDateDebut() OR !$this->getDateFin()) return "Aucune période connue";
+        return $this->getDateDebut()->format("d/m/Y H:i"). " au " .$this->getDateFin()->format("d/m/Y H:i");
+    }
 }
\ No newline at end of file
diff --git a/module/Formation/src/Formation/Entity/Db/Session.php b/module/Formation/src/Formation/Entity/Db/Session.php
index c60a72df..ab9612bc 100644
--- a/module/Formation/src/Formation/Entity/Db/Session.php
+++ b/module/Formation/src/Formation/Entity/Db/Session.php
@@ -638,7 +638,38 @@ class Session implements
         return $this->getFormation()->getId() . "/" . $this->getId();
     }
 
-    /** @noinspection PhpUnused */
+    /** @noinspection PhpUnused
+     *  MACRO SESSION#inscrits */
+    public function getArrayListePrincipales(): string
+    {
+        $stagiaiares = array_map(function (Inscription $i) { return $i->getIndividu(); } , $this->getListePrincipale());
+        usort($stagiaiares, function ($a, $b) { return $a->getDenomination(false) <=> $b->getDenomination(false); });
+
+        $text = "<table class='bordered' style='width:100%;'>";
+        $text .= "<thead>";
+        $text .= "<tr style='border-bottom:1px solid black;'>";
+        $text .= "<th style='width: 50%;'>Stagiaires  </th>";
+        $text .= "<th style='width: 50%;'>Signature  </th>";
+        $text .= "</tr>";
+        $text .= "</thead>";
+        $text .= "<tbody>";
+        foreach ($stagiaiares as $stagiaire) {
+            $text .= "<tr>";
+            $text .= "<td>";
+            $text .= $stagiaire->getDenomination() . "<br>";
+            $text .= $stagiaire->getStructure() ;
+            $text .= "</td>";
+            $text .= "<td>" . "</td>";
+            $text .= "</tr>";
+        }
+        $text .= "</tbody>";
+        $text .= "</table>";
+
+        return $text;
+    }
+
+    /** @noinspection PhpUnused
+     *  MACRO SESSION#formateurs*/
     public function getListeFormateurs(): string
     {
         /** @var Formateur[] $formateurs */
@@ -667,6 +698,38 @@ class Session implements
         return $text;
     }
 
+    /** @noinspection PhpUnused
+     * MACRO SESSION#FormateursAvecSignature
+     **/
+    public function getArrayFormateurs(): string
+    {
+        /** @var Formateur[] $formateurs */
+        $formateurs = $this->getFormateurs();
+
+        $text = "<table class='bordered' style='width:100%;'>";
+        $text .= "<thead>";
+        $text .= "<tr style='border-bottom:1px solid black;'>";
+        $text .= "<th style='width:50%'> Dénomination </th>";
+        $text .= "<th style='width:50%'> Signature </th>";
+        $text .= "</tr>";
+        $text .= "</thead>";
+        $text .= "<tbody>";
+        foreach ($formateurs as $formateur) {
+            $text .= "<tr>";
+            $text .= "<td>";
+            $text .= $formateur->getPrenom() . " " . $formateur->getNom() . " <br>";
+            $text .= $formateur->getAttachement();
+            $text .= "</td>";
+            $text .= "<td>";
+            $text .= "</td>";
+            $text .= "</tr>";
+        }
+        $text .= "</tbody>";
+        $text .= "</table>";
+
+        return $text;
+    }
+
     /** @noinspection PhpUnused */
     public function getListeJournees(): string
     {
diff --git a/module/Formation/src/Formation/Provider/Template/PdfTemplates.php b/module/Formation/src/Formation/Provider/Template/PdfTemplates.php
index 99d0026b..7542c1a4 100644
--- a/module/Formation/src/Formation/Provider/Template/PdfTemplates.php
+++ b/module/Formation/src/Formation/Provider/Template/PdfTemplates.php
@@ -8,4 +8,5 @@ class PdfTemplates {
     const FORMATION_ATTESTATION             = "FORMATION_ATTESTATION";
     const FORMATION_HISTORIQUE              = "FORMATION_HISTORIQUE";
     const FORMATION_ABSENCE                 = "FORMATION_ABSENCE";
+    const FORMATION_EMARGEMENT              = "FORMATION_EMARGEMENT";
 }
\ No newline at end of file
diff --git a/module/Formation/src/Formation/Service/Seance/SeanceService.php b/module/Formation/src/Formation/Service/Seance/SeanceService.php
index 885848e9..1d8b3d92 100644
--- a/module/Formation/src/Formation/Service/Seance/SeanceService.php
+++ b/module/Formation/src/Formation/Service/Seance/SeanceService.php
@@ -99,7 +99,7 @@ class SeanceService
      * @param integer $id
      * @return Seance|null
      */
-    public function getSeance(int $id): ?Seance
+    public function getSeance(?int $id): ?Seance
     {
         $qb = $this->createQueryBuilder()
             ->andWhere('journee.id = :id')
diff --git a/module/Formation/view/formation/session/afficher.phtml b/module/Formation/view/formation/session/afficher.phtml
index c3544a07..7efeedee 100644
--- a/module/Formation/view/formation/session/afficher.phtml
+++ b/module/Formation/view/formation/session/afficher.phtml
@@ -342,8 +342,8 @@ $canMesSessions = $this->isAllowed(FormateurPrivileges::getResourceId(FormateurP
                         <br/>
                     <?php endif; ?>
                     <?php if ($canEmargement): ?>
-                        <?php /** @see FormationInstanceDocumentController::exportTousEmargementsAction() */ ?>
-                        <a href="<?php echo $this->url('session/export-tous-emargements', ['session' => $session->getId()], [], true); ?>"
+                        <?php /** @see FormationInstanceDocumentController::genererEmargementAction() */ ?>
+                        <a href="<?php echo $this->url('session/generer-emargement', ['session' => $session->getId()], [], true); ?>"
                            class="btn btn-primary" target="_blank">
                             <span class="icon icon-pdf"></span>
                             Exporter les émargements
@@ -415,8 +415,8 @@ $canMesSessions = $this->isAllowed(FormateurPrivileges::getResourceId(FormateurP
                             </td>
                             <td>
                                 <?php if ($canEmargement) : ?>
-                                    <?php /** @see FormationInstanceDocumentController::exportEmargementAction() */ ?>
-                                    <a href="<?php echo $this->url('session/export-emargement', ['journee' => $journee->getId()], [], true); ?>"
+                                    <?php /** @see FormationInstanceDocumentController::genererEmargementAction() */ ?>
+                                    <a href="<?php echo $this->url('session/generer-emargement', ['session' => $session->getId(), 'seance' => $journee->getId()], [], true); ?>"
                                        title="Exporter l'émargement de la séance de formation" target="_blank">
                                         <span class="icon icon-pdf"></span><span class="lettrine">E</span></a>
                                 <?php endif; ?>
-- 
GitLab