Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 146 |
|
0.00% |
0 / 8 |
CRAP | |
0.00% |
0 / 1 |
ConformiteOrganisationGenerator | |
0.00% |
0 / 146 |
|
0.00% |
0 / 8 |
756 | |
0.00% |
0 / 1 |
addSyntheticView | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
addDetailedView | |
0.00% |
0 / 42 |
|
0.00% |
0 / 1 |
42 | |||
addGlobalOverview | |
0.00% |
0 / 61 |
|
0.00% |
0 / 1 |
20 | |||
getConformitesTable | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
30 | |||
extractConformiteProcessus | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
getFormattedReponse | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
20 | |||
getFormattedParticipants | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
12 | |||
getFormattedActionsDeProtection | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 |
1 | <?php |
2 | |
3 | namespace App\Domain\Reporting\Generator\Word; |
4 | |
5 | use App\Domain\Registry\Dictionary\ConformiteOrganisation\ReponseDictionary; |
6 | use App\Domain\Registry\Model\ConformiteOrganisation\Conformite; |
7 | use App\Domain\Registry\Model\ConformiteOrganisation\Evaluation; |
8 | use App\Domain\Registry\Model\ConformiteOrganisation\Reponse; |
9 | use App\Domain\Registry\Model\Mesurement; |
10 | use App\Domain\Registry\Service\ConformiteOrganisationService; |
11 | use App\Domain\User\Dictionary\ContactCivilityDictionary; |
12 | use PhpOffice\PhpWord\Element\Section; |
13 | use PhpOffice\PhpWord\Shared\Converter; |
14 | use PhpOffice\PhpWord\SimpleType\TblWidth; |
15 | use PhpOffice\PhpWord\Style\ListItem; |
16 | |
17 | class ConformiteOrganisationGenerator extends AbstractGenerator implements ImpressionGeneratorInterface |
18 | { |
19 | protected $average; |
20 | |
21 | public function addSyntheticView(Section $section, array $data): void |
22 | { |
23 | /* Not used anymore in this generator since it's useless |
24 | All content is generated in the addDetailedView() method below */ |
25 | } |
26 | |
27 | public function addDetailedView(Section $section, array $data): void |
28 | { |
29 | /** @var Evaluation $evaluation */ |
30 | $evaluation = $data[0]; |
31 | |
32 | /* ////////////////////////////////////////////////////////////// */ |
33 | $section->addTitle('Contexte', 1); |
34 | $contextData = [ |
35 | [ |
36 | 'Date de l\'évaluation', |
37 | $evaluation->getDate()->format('Y-m-d'), |
38 | ], |
39 | [ |
40 | 'Liste des participants', |
41 | [['array' => $this->getFormattedParticipants($evaluation)]], |
42 | ], |
43 | ]; |
44 | $this->addTable($section, $contextData, false, self::TABLE_ORIENTATION_VERTICAL); |
45 | |
46 | /* ////////////////////////////////////////////////////////////// */ |
47 | $section->addTitle('Liste des processus', 1); |
48 | |
49 | $orderedConformites = ConformiteOrganisationService::getOrderedConformites($evaluation); |
50 | $tableData = $this->getConformitesTable($orderedConformites); |
51 | |
52 | $this->addTable($section, $tableData, false, self::TABLE_ORIENTATION_HORIZONTAL); |
53 | |
54 | /* ////////////////////////////////////////////////////////////// */ |
55 | $section->addPageBreak(); |
56 | $section->addTitle('Détail des processus', 1); |
57 | |
58 | /** @var Conformite $conformite */ |
59 | foreach ($orderedConformites as $key => $conformite) { |
60 | if (0 != $key) { |
61 | $section->addPageBreak(); |
62 | } |
63 | |
64 | $processus = []; |
65 | |
66 | $section->addTitle($conformite->getProcessus()->getNom(), 3); |
67 | $section->addText($conformite->getProcessus()->getDescription()); |
68 | |
69 | foreach (ConformiteOrganisationService::getOrderedReponse($conformite) as $reponse) { |
70 | $processus[] = [ |
71 | \strip_tags($reponse->getQuestion()->getNom()), |
72 | $this->getFormattedReponse($reponse), |
73 | ]; |
74 | } |
75 | $actions = \iterable_to_array($conformite->getActionProtections()); |
76 | $withAllActions = $data[1]; /* Useless, for reading purpose only */ |
77 | if (!$withAllActions) { |
78 | $actions = $conformite->getNonAppliedActionProtections(); |
79 | } |
80 | |
81 | $actions = !empty(\iterable_to_array($conformite->getActionProtections())) |
82 | ? $this->getFormattedActionsDeProtection($actions) |
83 | : 'Aucune'; |
84 | $processus[] = [ |
85 | 'Actions de protection', |
86 | $actions, |
87 | ]; |
88 | |
89 | $this->addTable($section, $processus, false, self::TABLE_ORIENTATION_VERTICAL); |
90 | } |
91 | } |
92 | |
93 | public function addGlobalOverview(Section $section, ?Evaluation $evaluation = null) |
94 | { |
95 | if (null === $evaluation) { |
96 | return; |
97 | } |
98 | |
99 | $conformites = ConformiteOrganisationService::getOrderedConformites($evaluation); |
100 | |
101 | $scores = []; |
102 | foreach ($conformites as $conformite) { |
103 | $scores[] = $conformite->getConformite(); |
104 | } |
105 | |
106 | $style = [ |
107 | 'width' => Converter::cmToEmu(15), |
108 | 'height' => Converter::cmToEmu(11), |
109 | 'showAxisLabels' => true, |
110 | 'showGridY' => true, |
111 | 'dataLabelOptions' => [ |
112 | 'showVal' => false, |
113 | 'showCatName' => false, |
114 | ], |
115 | ]; |
116 | |
117 | $section->addTitle('Analyse de la conformité de la structure', 2); |
118 | $listStyle = ['listType' => ListItem::TYPE_NUMBER_NESTED]; |
119 | $section->addText('Afin de répondre aux objectifs du RGPD, la gestion des données à caractère personnel est structurée en 12 processus dont les objectifs sont définis dans le document figurant en annexe et à valeur de preuve.'); |
120 | $section->addText('Chacun des 12 processus est évalué annuellement et selon l’échelle de maturité ci-après.'); |
121 | $section->addText('Lorsque cela est nécessaire une ou plusieurs actions de progrès sont proposées au responsable du traitement pour validation et mise en opération.'); |
122 | $section->addText('Liste des 12 processus :'); |
123 | $section->addListItem('Organiser la conformité', 0, null, $listStyle); |
124 | $section->addListItem('Gérer les exigences et les poursuites', 0, null, $listStyle); |
125 | $section->addListItem('Gérer les sous-traitants de données à caractère personnel', 0, null, $listStyle); |
126 | $section->addListItem('Évaluer et auditer', 0, null, $listStyle); |
127 | $section->addListItem('Gérer les traitements', 0, null, $listStyle); |
128 | $section->addListItem('Sensibiliser, former, communiquer', 0, null, $listStyle); |
129 | $section->addListItem('Gérer les risques et les impacts sur la vie privée', 0, null, $listStyle); |
130 | $section->addListItem('Gérer les droits des personnes concernées', 0, null, $listStyle); |
131 | $section->addListItem('Gérer les violations de données à caractère personnel', 0, null, $listStyle); |
132 | $section->addListItem('Gérer la protection des données à caractère personnel', 0, null, $listStyle); |
133 | $section->addListItem('Gérer la documentation et les preuves', 0, null, $listStyle); |
134 | $section->addListItem('Gérer les opérations du système de management de la protection des données', 0, null, $listStyle); |
135 | |
136 | $this->average = 0; |
137 | $tableData = $this->getConformitesTable($conformites); |
138 | |
139 | $section->addText('Le graphique représente la situation au ' . date('d/m/Y') . '. Sur l’ensemble des processus, la moyenne est de ' . round($this->average, 2) . '/5. À chaque processus, des propositions d’améliorations sont faites puis retranscrites dans le plan de progrès.'); |
140 | |
141 | $section->addChart('column', $this->extractConformiteProcessus($evaluation), $scores, $style); |
142 | |
143 | $tableStyleConformite = [ |
144 | 'borderColor' => '006699', |
145 | 'borderSize' => 6, |
146 | 'cellMargin' => 100, |
147 | 'unit' => TblWidth::PERCENT, |
148 | 'width' => 100 * 50, |
149 | ]; |
150 | $tableOrganisationConformite = $section->addTable($tableStyleConformite); |
151 | $tableOrganisationConformite->addRow(null, ['tblHeader' => true, 'cantsplit' => true]); |
152 | $cell = $tableOrganisationConformite->addCell(2000, $this->cellHeadStyle); |
153 | $cell->addText('Pilote', $this->textHeadStyle); |
154 | $cell = $tableOrganisationConformite->addCell(4500, $this->cellHeadStyle); |
155 | $cell->addText('Processus', $this->textHeadStyle); |
156 | $cell = $tableOrganisationConformite->addCell(1500, $this->cellHeadStyle); |
157 | $cell->addText('Conformité', $this->textHeadStyle); |
158 | |
159 | foreach ($tableData as $line) { |
160 | $tableOrganisationConformite->addRow(null, ['cantsplit' => true]); |
161 | $cell1 = $tableOrganisationConformite->addCell(2000); |
162 | $cell1->addText($line[0]); |
163 | $cell2 = $tableOrganisationConformite->addCell(4500); |
164 | $cell2->addText($line[1]); |
165 | $cell3 = $tableOrganisationConformite->addCell(1500, ['align' => 'center', 'bgColor' => $line[2]['style']['bgColor']]); |
166 | $cell3->addText($line[2]['content']['text'], ['bold' => true], ['align' => 'center']); |
167 | } |
168 | } |
169 | |
170 | private function getConformitesTable(array $conformites): array |
171 | { |
172 | $tableData = []; |
173 | foreach ($conformites as $conformite) { |
174 | $this->average += $conformite->getConformite(); |
175 | switch (true) { |
176 | case $conformite->getConformite() < 2.5: |
177 | $bgColor = 'ffa7a7'; |
178 | break; |
179 | case $conformite->getConformite() < 3.5: |
180 | $bgColor = 'fac9ad'; |
181 | break; |
182 | default: |
183 | $bgColor = 'bce292'; |
184 | break; |
185 | } |
186 | $tableData[] = [ |
187 | $conformite->getPilote() ?? 'Inexistant', |
188 | $conformite->getProcessus()->getNom(), |
189 | ['content' => ['text' => $conformite->getConformite()], 'style' => ['bgColor' => $bgColor, 'bold' => true]], |
190 | ]; |
191 | } |
192 | $this->average /= 12; |
193 | |
194 | return $tableData; |
195 | } |
196 | |
197 | private function extractConformiteProcessus(Evaluation $evaluation): array |
198 | { |
199 | $processus = []; |
200 | foreach (ConformiteOrganisationService::getOrderedConformites($evaluation) as $conformite) { |
201 | $processus[] = $conformite->getProcessus()->getNom(); |
202 | } |
203 | |
204 | return $processus; |
205 | } |
206 | |
207 | private function getFormattedReponse(Reponse $reponse): string |
208 | { |
209 | switch ($reponse->getReponse()) { |
210 | case null: |
211 | return 'Inexistant'; |
212 | case ReponseDictionary::NON_CONCERNE: |
213 | return |
214 | ReponseDictionary::getReponseLabelFromKey($reponse->getReponse()) . |
215 | ' (' . $reponse->getReponseRaison() . ')'; |
216 | default: |
217 | return ReponseDictionary::getReponseLabelFromKey($reponse->getReponse()); |
218 | } |
219 | } |
220 | |
221 | private function getFormattedParticipants(Evaluation $evaluation): array |
222 | { |
223 | $participants = []; |
224 | foreach ($evaluation->getParticipants() as $participant) { |
225 | $participantsString = ''; |
226 | $participantsString .= ContactCivilityDictionary::getCivilities()[$participant->getCivilite()]; |
227 | $participantsString .= ' ' . $participant->getPrenom() . ' ' . $participant->getNomDeFamille(); |
228 | if (null !== $participant->getFonction()) { |
229 | $participantsString .= ', ' . $participant->getFonction(); |
230 | } |
231 | $participants[] = $participantsString; |
232 | } |
233 | |
234 | return $participants; |
235 | } |
236 | |
237 | private function getFormattedActionsDeProtection(array $actions) |
238 | { |
239 | $formattedActions = []; |
240 | /** @var Mesurement $action */ |
241 | foreach ($actions as $action) { |
242 | $formattedActions[] = $action->getName(); |
243 | } |
244 | |
245 | return $formattedActions; |
246 | } |
247 | } |