Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
6.93% covered (danger)
6.93%
14 / 202
11.11% covered (danger)
11.11%
1 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
OverviewGenerator
6.93% covered (danger)
6.93%
14 / 202
11.11% covered (danger)
11.11%
1 / 9
8823.39
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
1
 setCollectivity
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
 generateObjectPart
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
6
 generateOrganismIntroductionPart
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 1
156
 generateRegistries
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
0.00%
0 / 1
462
 generateManagementSystemAndCompliance
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
702
 generateContinuousImprovements
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
30
 generateAnnexeMention
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 1
1260
 addHeader
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3/**
4 * This file is part of the MADIS - RGPD Management application.
5 *
6 * @copyright Copyright (c) 2018-2019 Soluris - Solutions Numériques Territoriales Innovantes
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Affero General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22declare(strict_types=1);
23
24namespace App\Domain\Reporting\Generator\Word;
25
26use App\Application\Symfony\Security\UserProvider;
27use App\Domain\Registry\Model\ConformiteOrganisation\Evaluation;
28use App\Domain\User\Dictionary\ContactCivilityDictionary;
29use App\Domain\User\Model\Collectivity;
30use App\Domain\User\Model\ReviewData;
31use PhpOffice\PhpWord\Element\Section;
32use PhpOffice\PhpWord\SimpleType\Jc;
33use PhpOffice\PhpWord\SimpleType\TblWidth;
34use PhpOffice\PhpWord\Style\Table;
35use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
36
37class OverviewGenerator extends AbstractGenerator
38{
39    /**
40     * @var TreatmentGenerator
41     */
42    protected $treatmentGenerator;
43
44    /**
45     * @var ContractorGenerator
46     */
47    protected $contractorGenerator;
48
49    /**
50     * @var MaturityGenerator
51     */
52    protected $maturityGenerator;
53
54    /**
55     * @var MesurementGenerator
56     */
57    protected $mesurementGenerator;
58
59    /**
60     * @var RequestGenerator
61     */
62    protected $requestGenerator;
63
64    /**
65     * @var ViolationGenerator
66     */
67    protected $violationGenerator;
68
69    /**
70     * @var ToolGenerator
71     */
72    protected $toolGenerator;
73
74    /**
75     * @var ConformiteTraitementGenerator
76     */
77    protected $conformiteTraitementGenerator;
78
79    /**
80     * @var ConformiteOrganisationGenerator
81     */
82    protected $conformiteOrganisationGenerator;
83
84    /**
85     * @var UserGenerator
86     */
87    protected $userGenerator;
88
89    /**
90     * @var ProofGenerator
91     */
92    protected $proofGenerator;
93
94    /**
95     * @var string
96     */
97    protected $logoDir;
98
99    /**
100     * @var string
101     */
102    protected $dpdLogo;
103
104    public function __construct(
105        UserProvider $userProvider,
106        ParameterBagInterface $parameterBag,
107        TreatmentGenerator $treatmentGenerator,
108        ContractorGenerator $contractorGenerator,
109        MaturityGenerator $maturityGenerator,
110        MesurementGenerator $mesurementGenerator,
111        RequestGenerator $requestGenerator,
112        ViolationGenerator $violationGenerator,
113        ConformiteTraitementGenerator $conformiteTraitementGenerator,
114        ConformiteOrganisationGenerator $conformiteOrganisationGenerator,
115        UserGenerator $userGenerator,
116        ProofGenerator $proofGenerator,
117        ToolGenerator $toolGenerator,
118        string $logoDir,
119        string $dpdLogo,
120    ) {
121        parent::__construct($userProvider, $parameterBag);
122        $this->treatmentGenerator              = $treatmentGenerator;
123        $this->contractorGenerator             = $contractorGenerator;
124        $this->maturityGenerator               = $maturityGenerator;
125        $this->mesurementGenerator             = $mesurementGenerator;
126        $this->requestGenerator                = $requestGenerator;
127        $this->violationGenerator              = $violationGenerator;
128        $this->conformiteTraitementGenerator   = $conformiteTraitementGenerator;
129        $this->conformiteOrganisationGenerator = $conformiteOrganisationGenerator;
130        $this->userGenerator                   = $userGenerator;
131        $this->proofGenerator                  = $proofGenerator;
132        $this->toolGenerator                   = $toolGenerator;
133        $this->logoDir                         = $logoDir;
134        $this->dpdLogo                         = $dpdLogo;
135    }
136
137    public function setCollectivity(Collectivity $collectivity)
138    {
139        parent::setCollectivity($collectivity);
140        $this->treatmentGenerator->setCollectivity($collectivity);
141        $this->contractorGenerator->setCollectivity($collectivity);
142        $this->maturityGenerator->setCollectivity($collectivity);
143        $this->mesurementGenerator->setCollectivity($collectivity);
144        $this->requestGenerator->setCollectivity($collectivity);
145        $this->violationGenerator->setCollectivity($collectivity);
146        $this->conformiteTraitementGenerator->setCollectivity($collectivity);
147        $this->conformiteOrganisationGenerator->setCollectivity($collectivity);
148        $this->userGenerator->setCollectivity($collectivity);
149        $this->proofGenerator->setCollectivity($collectivity);
150    }
151
152    public function generateObjectPart(Section $section): void
153    {
154        if ($this->collectivity) {
155            $collectivity = $this->collectivity;
156        } else {
157            $collectivity = $this->userProvider->getAuthenticatedUser()->getCollectivity();
158        }
159
160        $section->addTitle('Objet', 1);
161
162        $section->addText(
163            "Ce document constitue le bilan de gestion des données à caractère personnel de la structure {$collectivity->getName()}."
164        );
165    }
166
167    public function generateOrganismIntroductionPart(Section $section): void
168    {
169        if ($this->collectivity) {
170            $collectivity = $this->collectivity;
171        } else {
172            $collectivity = $this->userProvider->getAuthenticatedUser()->getCollectivity();
173        }
174
175        $section->addTitle('Présentation de la structure', 1);
176
177        $section->addTitle('Identité de la structure', 2);
178        $section->addText(
179            \ucfirst($collectivity->getName()) . ' (' . \ucfirst($collectivity->getType()) . ')' .
180            (!empty($collectivity->getPopulation()) ? ', de ' . $collectivity->getPopulation() . ' habitants' : '') .
181            (!empty($collectivity->getNbrAgents()) ? ' comprenant ' . $collectivity->getNbrAgents() . ' salariés' : '') .
182            " a pour SIREN {$collectivity->getSiren()}" .
183            (!empty($collectivity->getFinessGeo()) ? ' (' . $collectivity->getFinessGeo() . ')' : '') .
184            " et est domicilié au {$collectivity->getAddress()->getLineOne()}" .
185            (!empty($collectivity->getAddress()->getLineTwo()) ? ', ' . $collectivity->getAddress()->getLineTwo() : '') .
186            "{$collectivity->getAddress()->getZipCode()}{$collectivity->getAddress()->getCity()}."
187        );
188
189        if (!empty($collectivity->getWebsite())) {
190            $section->addText("Pour consulter le site Internet : {$collectivity->getWebsite()}.");
191        }
192
193        $section->addTitle('Engagement de la direction', 2);
194
195        if (!empty($collectivity->getReportingBlockManagementCommitment())) {
196            \PhpOffice\PhpWord\Shared\Html::addHtml($section, $collectivity->getReportingBlockManagementCommitment(), false, false);
197        } else {
198            $section->addText("La direction de {$collectivity->getName()} a établi, documenté, mis en œuvre une politique de gestion des données à caractère personnel.");
199            $section->addText('Cette politique décrit les mesures techniques et organisationnelles.');
200            $section->addText("Cette politique a pour objectif de permettre à {$collectivity->getName()} de respecter dans le temps les exigences du RGPD et de pouvoir le démontrer.");
201        }
202
203        $section->addTitle('Composition du comité Informatique et Liberté', 2);
204
205        $section->addText("Le comité informatique et liberté est chargé de suivre l'amélioration de la mise en conformité dans le temps. Il est composé de :");
206
207        $legalManager         = $collectivity->getLegalManager();
208        $legalManagerCivility = ContactCivilityDictionary::getCivilities()[$legalManager->getCivility()];
209        $section->addListItem("{$legalManagerCivility} {$legalManager->getFullName()}{$legalManager->getJob()}");
210
211        $referent         = $collectivity->getReferent();
212        $referentCivility = $referent->getCivility() ? ContactCivilityDictionary::getCivilities()[$referent->getCivility()] : null;
213        $section->addListItem("{$referentCivility} {$referent->getFullName()}{$referent->getJob()}");
214
215        $itManager = $collectivity->getItManager();
216        if ($collectivity->isDifferentItManager()) {
217            $itManagerCivility = ContactCivilityDictionary::getCivilities()[$itManager->getCivility()];
218            $section->addListItem("{$itManagerCivility} {$itManager->getFullName()}{$itManager->getJob()}");
219        }
220
221        $dpo = $collectivity->getDpo();
222        if ($collectivity->isDifferentDpo()) {
223            $dpoCivility = ContactCivilityDictionary::getCivilities()[$dpo->getCivility()];
224            $section->addListItem("{$dpoCivility} {$dpo->getFullName()}{$dpo->getJob()}");
225        }
226
227        foreach ($collectivity->getComiteIlContacts() as $comiteIlContact) {
228            $contact  = $comiteIlContact->getContact();
229            $civility = ContactCivilityDictionary::getCivilities()[$contact->getCivility()];
230            $section->addListItem("{$civility} {$contact->getFullName()}{$contact->getJob()}");
231        }
232    }
233
234    public function generateRegistries(
235        Section $section,
236        array $treatments = [],
237        array $contractors = [],
238        array $requests = [],
239        array $violations = [],
240        array $tools = [],
241    ): void {
242        if ($this->collectivity) {
243            $collectivity = $this->collectivity;
244        } else {
245            $collectivity = $this->userProvider->getAuthenticatedUser()->getCollectivity();
246        }
247
248        $registries = [
249            ReviewData::TREATMENT_REGISTRY,
250            ReviewData::CONTRACTOR_REGISTRY,
251            ReviewData::TOOL_REGISTRY,
252            ReviewData::REQUEST_REGISTRY,
253            ReviewData::VIOLATION_REGISTRY,
254        ];
255        $registryCount = 0;
256        foreach ($registries as $registry) {
257            if ($collectivity && $collectivity->getReviewData() && in_array($registry, $collectivity->getReviewData()->getSections())) {
258                // cancel registry if it is tool registry but the module is not active
259                if (ReviewData::TOOL_REGISTRY === $registry && !$collectivity->isHasModuleTools()) {
260                    --$registryCount;
261                }
262                ++$registryCount;
263            }
264        }
265        if ($registryCount) {
266            $section->addTitle('Bilan des registres', 1);
267            $section->addText("{$collectivity->getName()} recense {$registryCount} registres : ");
268        }
269        if (in_array(ReviewData::TREATMENT_REGISTRY, $collectivity->getReviewData()->getSections())) {
270            $section->addListItem('Traitements');
271        }
272        if (in_array(ReviewData::CONTRACTOR_REGISTRY, $collectivity->getReviewData()->getSections())) {
273            $section->addListItem('Sous-traitants');
274        }
275        if ($collectivity->isHasModuleTools() && in_array(ReviewData::TOOL_REGISTRY, $collectivity->getReviewData()->getSections())) {
276            $section->addListItem('Logiciels et supports');
277        }
278        if (in_array(ReviewData::REQUEST_REGISTRY, $collectivity->getReviewData()->getSections())) {
279            $section->addListItem('Demandes des personnes concernées');
280        }
281        if (in_array(ReviewData::VIOLATION_REGISTRY, $collectivity->getReviewData()->getSections())) {
282            $section->addListItem('Violations de données');
283        }
284
285        if (in_array(ReviewData::TREATMENT_REGISTRY, $collectivity->getReviewData()->getSections())) {
286            $this->treatmentGenerator->addGlobalOverview($section, $treatments);
287        }
288        if (in_array(ReviewData::CONTRACTOR_REGISTRY, $collectivity->getReviewData()->getSections())) {
289            $this->contractorGenerator->addGlobalOverview($section, $contractors);
290        }
291        if (in_array(ReviewData::TOOL_REGISTRY, $collectivity->getReviewData()->getSections()) && $collectivity->isHasModuleTools()) {
292            $this->toolGenerator->addSyntheticView($section, $tools, true, true, $collectivity);
293        }
294        if (in_array(ReviewData::REQUEST_REGISTRY, $collectivity->getReviewData()->getSections())) {
295            $this->requestGenerator->addGlobalOverview($section, $requests);
296        }
297        if (in_array(ReviewData::VIOLATION_REGISTRY, $collectivity->getReviewData()->getSections())) {
298            $this->violationGenerator->addGlobalOverview($section, $violations);
299        }
300    }
301
302    public function generateManagementSystemAndCompliance(
303        Section $section,
304        array $maturity = [],
305        array $treatments = [],
306        array $mesurements = [],
307        ?Evaluation $evaluation = null,
308    ): void {
309        $maturity['bilanReport'] = true;
310
311        if ($this->collectivity) {
312            $collectivity = $this->collectivity;
313        } else {
314            $collectivity = $this->userProvider->getAuthenticatedUser()->getCollectivity();
315        }
316
317        if (
318            ($collectivity->getReviewData() && in_array(ReviewData::CONFORMITY_EVALUATION, $collectivity->getReviewData()->getSections()))
319            || ($collectivity->isHasModuleConformiteTraitement() && $collectivity->getReviewData() && in_array(ReviewData::TREATMENT_CONFORMITY, $collectivity->getReviewData()->getSections()))
320            || ($collectivity->isHasModuleConformiteOrganisation() && $collectivity->getReviewData() && in_array(ReviewData::COLLECTIVITY_CONFORMITY, $collectivity->getReviewData()->getSections()))
321            || ($collectivity->getReviewData() && in_array(ReviewData::PROTECT_ACTIONS, $collectivity->getReviewData()->getSections()))
322            || ($collectivity->isHasModuleConformiteTraitement() && $collectivity->getReviewData() && in_array(ReviewData::AIPD, $collectivity->getReviewData()->getSections()))
323        ) {
324            $section->addTitle('Système de management des données à caractère personnel et conformité', 1);
325        }
326
327        if ($collectivity->getReviewData() && in_array(ReviewData::CONFORMITY_EVALUATION, $collectivity->getReviewData()->getSections())) {
328            $this->maturityGenerator->addContextView($section, $maturity);
329            $this->maturityGenerator->addSyntheticView($section, $maturity);
330        }
331
332        if ($collectivity->isHasModuleConformiteTraitement() && $collectivity->getReviewData() && (in_array(ReviewData::AIPD, $collectivity->getReviewData()->getSections()) || in_array(ReviewData::TREATMENT_CONFORMITY, $collectivity->getReviewData()->getSections()))) {
333            $withAIPD    = in_array(ReviewData::AIPD, $collectivity->getReviewData()->getSections());
334            $withConform = in_array(ReviewData::TREATMENT_CONFORMITY, $collectivity->getReviewData()->getSections());
335            $this->conformiteTraitementGenerator->addGlobalOverview($section, $treatments, $withAIPD, $withConform);
336        }
337        if ($collectivity->isHasModuleConformiteOrganisation() && $collectivity->getReviewData() && in_array(ReviewData::COLLECTIVITY_CONFORMITY, $collectivity->getReviewData()->getSections())) {
338            $this->conformiteOrganisationGenerator->addGlobalOverview($section, $evaluation);
339        }
340        if ($collectivity->getReviewData() && in_array(ReviewData::PROTECT_ACTIONS, $collectivity->getReviewData()->getSections())) {
341            $this->mesurementGenerator->addGlobalOverview($section, $mesurements);
342        }
343    }
344
345    public function generateContinuousImprovements(Section $section): void
346    {
347        if ($this->collectivity) {
348            $collectivity = $this->collectivity;
349        } else {
350            $collectivity = $this->userProvider->getAuthenticatedUser()->getCollectivity();
351        }
352        if ($collectivity->getReviewData() && in_array(ReviewData::CONTINUOUS_AMELIORATION, $collectivity->getReviewData()->getSections())) {
353            $section->addTitle("Principe d'amélioration continue", 1);
354            $section->addText('Le système de management des données à caractère personnel s’inscrit dans un principe d’amélioration continue. En conséquence :');
355            if (!empty($collectivity->getReportingBlockManagementCommitment())) {
356                \PhpOffice\PhpWord\Shared\Html::addHtml($section, $collectivity->getReportingBlockContinuousImprovement(), false, false);
357            } else {
358                $section->addListItem('Le référent opérationnel continue de mettre à jour le registre avec les éventuels nouveaux traitements effectués.');
359                $section->addListItem('Le référent opérationnel continue de mettre à jour le registre avec les éventuels nouveaux sous-traitants.');
360                $section->addListItem('Le comité génère un bilan chaque année et met en place les mesures correctives adéquates.');
361            }
362            $section->addText('Le responsable du traitement atteste avoir pris connaissance de l’ensemble des documents, approuve le bilan et s’engage à mettre en œuvre le plan d’action.');
363            $section->addText('Signature du responsable du traitement');
364            $section->addTextBreak(3);
365            $section->addPageBreak();
366        }
367    }
368
369    public function generateAnnexeMention($document, Section $section, array $treatments = [], array $violations = [], array $mesurements = []): void
370    {
371        if (
372            $this->collectivity && $this->collectivity->getReviewData() && (
373                in_array(ReviewData::TREATMENT_REGISTRY, $this->collectivity->getReviewData()->getSections())
374                || in_array(ReviewData::VIOLATION_REGISTRY, $this->collectivity->getReviewData()->getSections())
375                || (in_array(ReviewData::TREATMENT_CONFORMITY, $this->collectivity->getReviewData()->getSections()) && $this->collectivity->isHasModuleConformiteTraitement())
376                || in_array(ReviewData::PROOF_LIST, $this->collectivity->getReviewData()->getSections())
377                || in_array(ReviewData::PROTECT_ACTIONS, $this->collectivity->getReviewData()->getSections())
378                || (in_array(ReviewData::AIPD, $this->collectivity->getReviewData()->getSections()) && $this->collectivity->isHasModuleConformiteTraitement())
379                || in_array(ReviewData::USER_LIST, $this->collectivity->getReviewData()->getSections())
380            )
381        ) {
382            $section->addTitle('Annexes');
383        }
384        if ($this->collectivity && $this->collectivity->getReviewData() && in_array(ReviewData::TREATMENT_REGISTRY, $this->collectivity->getReviewData()->getSections())) {
385            $AnnexeTreatmentListSection = $document->addSection(['orientation' => 'portrait']);
386            $this->addHeader($AnnexeTreatmentListSection);
387            $this->treatmentGenerator->TreatmentAnnexeList($AnnexeTreatmentListSection, $treatments);
388        }
389
390        if ($this->collectivity && $this->collectivity->getReviewData() && in_array(ReviewData::VIOLATION_REGISTRY, $this->collectivity->getReviewData()->getSections())) {
391            $RiskAnnexeSection = $document->addSection(['orientation' => 'landscape']);
392            $this->addHeader($RiskAnnexeSection);
393            $this->violationGenerator->AnnexeList($RiskAnnexeSection, $violations);
394        }
395        if ($this->collectivity && $this->collectivity->getReviewData() && in_array(ReviewData::PROOF_LIST, $this->collectivity->getReviewData()->getSections())) {
396            $ProofAnnexeSection = $document->addSection(['orientation' => 'portrait']);
397            $this->addHeader($ProofAnnexeSection);
398            $this->proofGenerator->ProofList($ProofAnnexeSection);
399        }
400        if ($this->collectivity && $this->collectivity->getReviewData() && in_array(ReviewData::PROTECT_ACTIONS, $this->collectivity->getReviewData()->getSections())) {
401            $protectionActionSection = $document->addSection(['orientation' => 'portrait']);
402            $this->addHeader($protectionActionSection);
403            $this->mesurementGenerator->ProtectionActionAppliedAnnexeTable($protectionActionSection, $mesurements);
404        }
405        if ($this->collectivity && $this->collectivity->isHasModuleConformiteTraitement() && $this->collectivity->getReviewData() && in_array(ReviewData::TREATMENT_CONFORMITY, $this->collectivity->getReviewData()->getSections())) {
406            $RiskAnnexeSection = $document->addSection(['orientation' => 'landscape']);
407            $this->addHeader($RiskAnnexeSection);
408            $this->conformiteTraitementGenerator->SyntheticAnnexeList($RiskAnnexeSection, $treatments);
409        }
410        if ($this->collectivity && $this->collectivity->isHasModuleConformiteTraitement() && $this->collectivity->getReviewData() && in_array(ReviewData::AIPD, $this->collectivity->getReviewData()->getSections())) {
411            $riskAipdSectionBis = $document->addSection(['orientation' => 'landscape']);
412            $this->addHeader($riskAipdSectionBis);
413            $this->treatmentGenerator->RiskTreatmentAnnexeList($riskAipdSectionBis, $treatments);
414        }
415        if ($this->collectivity && $this->collectivity->getReviewData() && in_array(ReviewData::USER_LIST, $this->collectivity->getReviewData()->getSections())) {
416            $AnnexeUserListSection = $document->addSection(['orientation' => 'portrait']);
417            $this->addHeader($AnnexeUserListSection);
418            $this->userGenerator->UserList($AnnexeUserListSection);
419        }
420    }
421
422    private function addHeader(Section $section)
423    {
424        $header = $section->addHeader();
425        $table  = $header->addTable([
426            'borderColor' => '000000',
427            'borderSize'  => 3,
428            'cellMargin'  => 100,
429            'unit'        => TblWidth::PERCENT,
430            'width'       => 100 * 50,
431            'layout'      => Table::LAYOUT_FIXED,
432        ]);
433        $row  = $table->addRow(10, ['tblHeader' => true, 'cantsplit' => true]);
434        $cell = $row->addCell(70 * 50, ['alignment' => Jc::CENTER]);
435        $cell->addText($this->title, ['alignment' => Jc::CENTER, 'bold' => true]);
436        $cell = $row->addCell(30 * 50, ['alignment' => Jc::CENTER]);
437        $cell->addPreserveText('Page {PAGE}/{NUMPAGES}', ['alignment' => Jc::CENTER]);
438
439        $header->addTextBreak();
440    }
441}