From 0afc9ddfb260e953d29746718c7537aa30f78a89 Mon Sep 17 00:00:00 2001
From: Jonathan Foucher <jfoucher@gmail.com>
Date: Tue, 1 Apr 2025 15:16:26 +0200
Subject: [PATCH] Make table widths consistent. Fixes
 https://gitlab.adullact.net/soluris/madis/-/issues/1004

---
 .../Generator/Word/AbstractGenerator.php      |  8 ++++-
 .../Word/ConformiteOrganisationGenerator.php  |  2 ++
 .../Word/ConformiteTraitementGenerator.php    |  1 +
 .../Generator/Word/MaturityGenerator.php      |  2 ++
 .../Generator/Word/MesurementGenerator.php    |  1 +
 .../Generator/Word/OverviewGenerator.php      | 30 +++++++++++++++++++
 .../Generator/Word/ViolationGenerator.php     |  2 +-
 7 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/src/Domain/Reporting/Generator/Word/AbstractGenerator.php b/src/Domain/Reporting/Generator/Word/AbstractGenerator.php
index 08317f145..067112eb6 100644
--- a/src/Domain/Reporting/Generator/Word/AbstractGenerator.php
+++ b/src/Domain/Reporting/Generator/Word/AbstractGenerator.php
@@ -40,6 +40,7 @@ use PhpOffice\PhpWord\Settings;
 use PhpOffice\PhpWord\SimpleType\Jc;
 use PhpOffice\PhpWord\SimpleType\TblWidth;
 use PhpOffice\PhpWord\Style;
+use PhpOffice\PhpWord\Style\Table;
 use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 use Symfony\Component\HttpFoundation\BinaryFileResponse;
 use Symfony\Component\HttpFoundation\ResponseHeaderBag;
@@ -76,6 +77,8 @@ abstract class AbstractGenerator implements GeneratorInterface
      */
     protected $collectivity;
 
+    protected ?string $title = null;
+
     /**
      * AbstractGenerator constructor.
      */
@@ -92,6 +95,7 @@ abstract class AbstractGenerator implements GeneratorInterface
             'cellMargin'  => 100,
             'unit'        => TblWidth::PERCENT,
             'width'       => 100 * 50,
+            'layout'      => Table::LAYOUT_FIXED,
         ];
 
         $this->cellHeadStyle = [
@@ -314,6 +318,7 @@ abstract class AbstractGenerator implements GeneratorInterface
      */
     public function createContentSection(PhpWord $document, string $title): Section
     {
+        $this->title = $title;
         // Create section
         $section = $document->addSection();
 
@@ -325,11 +330,12 @@ abstract class AbstractGenerator implements GeneratorInterface
             'cellMargin'  => 100,
             'unit'        => TblWidth::PERCENT,
             'width'       => 100 * 50,
+            'layout'      => Table::LAYOUT_FIXED,
         ]);
         $row  = $table->addRow(10, ['tblHeader' => true, 'cantsplit' => true]);
         $cell = $row->addCell(70 * 50, ['alignment' => Jc::CENTER]);
         $cell->addText($title, ['alignment' => Jc::CENTER, 'bold' => true]);
-        $cell = $row->addCell(15 * 50, ['alignment' => Jc::CENTER]);
+        $cell = $row->addCell(30 * 50, ['alignment' => Jc::CENTER]);
         $cell->addPreserveText('Page {PAGE}/{NUMPAGES}', ['alignment' => Jc::CENTER]);
 
         $header->addTextBreak();
diff --git a/src/Domain/Reporting/Generator/Word/ConformiteOrganisationGenerator.php b/src/Domain/Reporting/Generator/Word/ConformiteOrganisationGenerator.php
index e53009dc8..67f052769 100644
--- a/src/Domain/Reporting/Generator/Word/ConformiteOrganisationGenerator.php
+++ b/src/Domain/Reporting/Generator/Word/ConformiteOrganisationGenerator.php
@@ -13,6 +13,7 @@ use PhpOffice\PhpWord\Element\Section;
 use PhpOffice\PhpWord\Shared\Converter;
 use PhpOffice\PhpWord\SimpleType\TblWidth;
 use PhpOffice\PhpWord\Style\ListItem;
+use PhpOffice\PhpWord\Style\Table;
 
 class ConformiteOrganisationGenerator extends AbstractGenerator implements ImpressionGeneratorInterface
 {
@@ -146,6 +147,7 @@ class ConformiteOrganisationGenerator extends AbstractGenerator implements Impre
             'cellMargin'  => 100,
             'unit'        => TblWidth::PERCENT,
             'width'       => 100 * 50,
+            'layout'      => Table::LAYOUT_FIXED,
         ];
         $tableOrganisationConformite = $section->addTable($tableStyleConformite);
         $tableOrganisationConformite->addRow(null, ['tblHeader' => true, 'cantsplit' => true]);
diff --git a/src/Domain/Reporting/Generator/Word/ConformiteTraitementGenerator.php b/src/Domain/Reporting/Generator/Word/ConformiteTraitementGenerator.php
index f1e6785f7..60698e98b 100644
--- a/src/Domain/Reporting/Generator/Word/ConformiteTraitementGenerator.php
+++ b/src/Domain/Reporting/Generator/Word/ConformiteTraitementGenerator.php
@@ -50,6 +50,7 @@ class ConformiteTraitementGenerator extends AbstractGenerator implements Impress
             'cellMargin'  => 100,
             'unit'        => TblWidth::PERCENT,
             'width'       => 100 * 50,
+            'layout'      => \PhpOffice\PhpWord\Style\Table::LAYOUT_FIXED,
         ];
 
         if ($withConform) {
diff --git a/src/Domain/Reporting/Generator/Word/MaturityGenerator.php b/src/Domain/Reporting/Generator/Word/MaturityGenerator.php
index 61d21e755..a14ab9f17 100644
--- a/src/Domain/Reporting/Generator/Word/MaturityGenerator.php
+++ b/src/Domain/Reporting/Generator/Word/MaturityGenerator.php
@@ -29,6 +29,7 @@ use App\Domain\Maturity\Model\Survey;
 use App\Domain\Registry\Model\Mesurement;
 use PhpOffice\PhpWord\Element\Section;
 use PhpOffice\PhpWord\Shared\Converter;
+use PhpOffice\PhpWord\Style\Table;
 
 class MaturityGenerator extends AbstractGenerator implements ImpressionGeneratorInterface
 {
@@ -66,6 +67,7 @@ class MaturityGenerator extends AbstractGenerator implements ImpressionGenerator
                 'borderColor' => '006699',
                 'borderSize'  => 6,
                 'cellMargin'  => 100,
+                'layout'      => Table::LAYOUT_FIXED,
             ]);
 
             $cellStyle = ['bgColor' => '3c8dbc'];
diff --git a/src/Domain/Reporting/Generator/Word/MesurementGenerator.php b/src/Domain/Reporting/Generator/Word/MesurementGenerator.php
index 585b55d64..b980bd434 100644
--- a/src/Domain/Reporting/Generator/Word/MesurementGenerator.php
+++ b/src/Domain/Reporting/Generator/Word/MesurementGenerator.php
@@ -61,6 +61,7 @@ class MesurementGenerator extends AbstractGenerator implements ImpressionGenerat
             'cellMargin'  => 100,
             'unit'        => TblWidth::PERCENT,
             'width'       => 100 * 50,
+            'layout'      => \PhpOffice\PhpWord\Style\Table::LAYOUT_FIXED,
         ];
 
         uasort($data, [$this, 'sortMesurementByDate']);
diff --git a/src/Domain/Reporting/Generator/Word/OverviewGenerator.php b/src/Domain/Reporting/Generator/Word/OverviewGenerator.php
index 67a573de2..be461403f 100644
--- a/src/Domain/Reporting/Generator/Word/OverviewGenerator.php
+++ b/src/Domain/Reporting/Generator/Word/OverviewGenerator.php
@@ -29,6 +29,9 @@ use App\Domain\User\Dictionary\ContactCivilityDictionary;
 use App\Domain\User\Model\Collectivity;
 use App\Domain\User\Model\ReviewData;
 use PhpOffice\PhpWord\Element\Section;
+use PhpOffice\PhpWord\SimpleType\Jc;
+use PhpOffice\PhpWord\SimpleType\TblWidth;
+use PhpOffice\PhpWord\Style\Table;
 use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 
 class OverviewGenerator extends AbstractGenerator
@@ -380,32 +383,59 @@ class OverviewGenerator extends AbstractGenerator
         }
         if ($this->collectivity && $this->collectivity->getReviewData() && in_array(ReviewData::TREATMENT_REGISTRY, $this->collectivity->getReviewData()->getSections())) {
             $AnnexeTreatmentListSection = $document->addSection(['orientation' => 'portrait']);
+            $this->addHeader($AnnexeTreatmentListSection);
             $this->treatmentGenerator->TreatmentAnnexeList($AnnexeTreatmentListSection, $treatments);
         }
 
         if ($this->collectivity && $this->collectivity->getReviewData() && in_array(ReviewData::VIOLATION_REGISTRY, $this->collectivity->getReviewData()->getSections())) {
             $RiskAnnexeSection = $document->addSection(['orientation' => 'landscape']);
+            $this->addHeader($RiskAnnexeSection);
             $this->violationGenerator->AnnexeList($RiskAnnexeSection, $violations);
         }
         if ($this->collectivity && $this->collectivity->getReviewData() && in_array(ReviewData::PROOF_LIST, $this->collectivity->getReviewData()->getSections())) {
             $ProofAnnexeSection = $document->addSection(['orientation' => 'portrait']);
+            $this->addHeader($ProofAnnexeSection);
             $this->proofGenerator->ProofList($ProofAnnexeSection);
         }
         if ($this->collectivity && $this->collectivity->getReviewData() && in_array(ReviewData::PROTECT_ACTIONS, $this->collectivity->getReviewData()->getSections())) {
             $protectionActionSection = $document->addSection(['orientation' => 'portrait']);
+            $this->addHeader($protectionActionSection);
             $this->mesurementGenerator->ProtectionActionAppliedAnnexeTable($protectionActionSection, $mesurements);
         }
         if ($this->collectivity && $this->collectivity->isHasModuleConformiteTraitement() && $this->collectivity->getReviewData() && in_array(ReviewData::TREATMENT_CONFORMITY, $this->collectivity->getReviewData()->getSections())) {
             $RiskAnnexeSection = $document->addSection(['orientation' => 'landscape']);
+            $this->addHeader($RiskAnnexeSection);
             $this->conformiteTraitementGenerator->SyntheticAnnexeList($RiskAnnexeSection, $treatments);
         }
         if ($this->collectivity && $this->collectivity->isHasModuleConformiteTraitement() && $this->collectivity->getReviewData() && in_array(ReviewData::AIPD, $this->collectivity->getReviewData()->getSections())) {
             $riskAipdSectionBis = $document->addSection(['orientation' => 'landscape']);
+            $this->addHeader($riskAipdSectionBis);
             $this->treatmentGenerator->RiskTreatmentAnnexeList($riskAipdSectionBis, $treatments);
         }
         if ($this->collectivity && $this->collectivity->getReviewData() && in_array(ReviewData::USER_LIST, $this->collectivity->getReviewData()->getSections())) {
             $AnnexeUserListSection = $document->addSection(['orientation' => 'portrait']);
+            $this->addHeader($AnnexeUserListSection);
             $this->userGenerator->UserList($AnnexeUserListSection);
         }
     }
+
+    private function addHeader(Section $section)
+    {
+        $header = $section->addHeader();
+        $table  = $header->addTable([
+            'borderColor' => '000000',
+            'borderSize'  => 3,
+            'cellMargin'  => 100,
+            'unit'        => TblWidth::PERCENT,
+            'width'       => 100 * 50,
+            'layout'      => Table::LAYOUT_FIXED,
+        ]);
+        $row  = $table->addRow(10, ['tblHeader' => true, 'cantsplit' => true]);
+        $cell = $row->addCell(70 * 50, ['alignment' => Jc::CENTER]);
+        $cell->addText($this->title, ['alignment' => Jc::CENTER, 'bold' => true]);
+        $cell = $row->addCell(30 * 50, ['alignment' => Jc::CENTER]);
+        $cell->addPreserveText('Page {PAGE}/{NUMPAGES}', ['alignment' => Jc::CENTER]);
+
+        $header->addTextBreak();
+    }
 }
diff --git a/src/Domain/Reporting/Generator/Word/ViolationGenerator.php b/src/Domain/Reporting/Generator/Word/ViolationGenerator.php
index a636a3edb..0263b0a63 100644
--- a/src/Domain/Reporting/Generator/Word/ViolationGenerator.php
+++ b/src/Domain/Reporting/Generator/Word/ViolationGenerator.php
@@ -310,7 +310,7 @@ class ViolationGenerator extends AbstractGenerator implements ImpressionGenerato
         return $translatedValues;
     }
 
-    public function AnnexeList($section, $violations)
+    public function AnnexeList(Section $section, $violations)
     {
         $section->addTitle('Liste des violations de données', 2);
         $tableViolationAnnexeApplied = $section->addTable($this->tableStyle);
-- 
GitLab