Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 362 |
|
0.00% |
0 / 9 |
CRAP | |
0.00% |
0 / 1 |
ConformiteTraitementGenerator | |
0.00% |
0 / 362 |
|
0.00% |
0 / 9 |
5402 | |
0.00% |
0 / 1 |
addGlobalOverview | |
0.00% |
0 / 182 |
|
0.00% |
0 / 1 |
1806 | |||
colorCell | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
2 | |||
valueCell | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
2 | |||
addSyntheticView | |
0.00% |
0 / 24 |
|
0.00% |
0 / 1 |
12 | |||
addDetailedView | |
0.00% |
0 / 50 |
|
0.00% |
0 / 1 |
56 | |||
sortTreatmentByConformiteTraitementByLevelAndTreatmentName | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
12 | |||
sortReponseByQuestionPosition | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
SyntheticAnnexeList | |
0.00% |
0 / 78 |
|
0.00% |
0 / 1 |
182 | |||
BgColorSyntheticTreatment | |
0.00% |
0 / 6 |
|
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 | |
22 | declare(strict_types=1); |
23 | |
24 | namespace App\Domain\Reporting\Generator\Word; |
25 | |
26 | use App\Domain\Registry\Calculator\Completion\ConformiteTraitementCompletion; |
27 | use App\Domain\Registry\Dictionary\ConformiteTraitementLevelDictionary; |
28 | use App\Domain\Registry\Model\ConformiteTraitement\Reponse; |
29 | use App\Domain\Registry\Model\Mesurement; |
30 | use App\Domain\Registry\Model\Treatment; |
31 | use PhpOffice\PhpWord\Element\Section; |
32 | use PhpOffice\PhpWord\Element\Table; |
33 | use PhpOffice\PhpWord\Shared\Converter; |
34 | use PhpOffice\PhpWord\SimpleType\TblWidth; |
35 | use PhpOffice\PhpWord\Style\ListItem; |
36 | |
37 | class ConformiteTraitementGenerator extends AbstractGenerator implements ImpressionGeneratorInterface |
38 | { |
39 | /** |
40 | * Global overview : Information to display for conformiteTraitement in overview report. |
41 | */ |
42 | public function addGlobalOverview(Section $section, array $data, $withAIPD = true, $withConform = true): void |
43 | { |
44 | if (empty($data)) { |
45 | return; |
46 | } |
47 | $tableStyleConformite = [ |
48 | 'borderColor' => '006699', |
49 | 'borderSize' => 6, |
50 | 'cellMargin' => 100, |
51 | 'unit' => TblWidth::PERCENT, |
52 | 'width' => 100 * 50, |
53 | ]; |
54 | |
55 | if ($withConform) { |
56 | $section->addTitle('Analyse de la conformité des traitements', 2); |
57 | |
58 | uasort($data, [$this, 'sortTreatmentByConformiteTraitementByLevelAndTreatmentName']); |
59 | |
60 | // Table data |
61 | // Add header |
62 | $tableData = [ |
63 | [ |
64 | 'Traitement', |
65 | 'Gestionnaire', |
66 | 'Date de révision de la conformité', |
67 | 'Conformité', |
68 | ], |
69 | ]; |
70 | |
71 | $chartCategories = []; |
72 | $chartData = []; |
73 | $conformites = ConformiteTraitementLevelDictionary::getConformites(); |
74 | foreach ($conformites as $key => $label) { |
75 | $chartCategories[] = $label; |
76 | $chartData[$key] = 0; |
77 | } |
78 | |
79 | /** @var Treatment $treatment */ |
80 | foreach ($data as $treatment) { |
81 | $conformiteTraitement = $treatment->getConformiteTraitement(); |
82 | $level = ConformiteTraitementCompletion::getConformiteTraitementLevel($conformiteTraitement); |
83 | |
84 | $date = null; |
85 | if (!\is_null($conformiteTraitement)) { |
86 | $date = $conformiteTraitement->getCreatedAt(); |
87 | } |
88 | |
89 | $tableData[] = [ |
90 | $treatment->getName(), |
91 | $treatment->getManager(), |
92 | ConformiteTraitementLevelDictionary::getConformites()[$level], |
93 | $this->getDate($date, 'd/m/Y'), |
94 | ]; |
95 | |
96 | ++$chartData[$level]; |
97 | } |
98 | |
99 | $section->addText('Les 10 critères suivants correspondent aux principes fondamentaux du RGPD et ont fait l’objet d’une évaluation :'); |
100 | $listStyle = ['listType' => ListItem::TYPE_NUMBER]; |
101 | $section->addListItem('Finalités', 0, null, $listStyle); |
102 | $section->addListItem('Licéité', 0, null, $listStyle); |
103 | $section->addListItem('Minimisation des données', 0, null, $listStyle); |
104 | $section->addListItem('Qualité des données', 0, null, $listStyle); |
105 | $section->addListItem('Durée de conservation', 0, null, $listStyle); |
106 | $section->addListItem('Information des personnes concernées', 0, null, $listStyle); |
107 | $section->addListItem('Recueil de consentement', 0, null, $listStyle); |
108 | $section->addListItem('Exercice des différents droits', 0, null, $listStyle); |
109 | $section->addListItem('Sous-traitance', 0, null, $listStyle); |
110 | $section->addListItem('Transferts en dehors de l’union européenne', 0, null, $listStyle); |
111 | |
112 | $textrun = $section->addTextRun(); |
113 | $textrun->addText('Une synthèse de l’analyse de la conformité des traitements et à valeur de preuve '); |
114 | $textrun->addLink('listConformityTreatments', 'figure en annexe', ['underline' => 'single'], [], true); |
115 | $textrun->addText('.'); |
116 | |
117 | $section->addText('Ci-dessous l’évaluation de la conformité des traitements au ' . date('d/m/Y') . ' :'); |
118 | |
119 | $chart = $section->addChart( |
120 | 'pie', |
121 | $chartCategories, |
122 | $chartData, |
123 | [ |
124 | 'height' => Converter::cmToEmu(11), |
125 | 'width' => Converter::cmToEmu(15), |
126 | ] |
127 | ); |
128 | |
129 | $chart->getStyle()->setColors(\array_values(ConformiteTraitementLevelDictionary::getHexaConformitesColors())); |
130 | |
131 | $countTypes = array_count_values(array_column($tableData, '2')); |
132 | $conformes = array_key_exists('Conforme', $countTypes) ? $countTypes['Conforme'] : 0; |
133 | $nonConformesMineurs = array_key_exists('Non-conformité mineure', $countTypes) ? $countTypes['Non-conformité mineure'] : 0; |
134 | $nonConformesMajeurs = array_key_exists('Non-conformité majeure', $countTypes) ? $countTypes['Non-conformité majeure'] : 0; |
135 | $NonEvalues = array_key_exists('Non évalué', $countTypes) ? $countTypes['Non évalué'] : 0; |
136 | |
137 | $section->addText('Sur les ' . (count($tableData) - 1) . ' traitements :'); |
138 | $section->addListItem('Conforme(s) : ' . $conformes); |
139 | $section->addListItem('Non-conformité(s) mineure(s) : ' . $nonConformesMineurs); |
140 | $section->addListItem('Non-conformité(s) majeure(s) : ' . $nonConformesMajeurs); |
141 | $section->addListItem('Non évalué(s) : ' . $NonEvalues); |
142 | |
143 | $tableConformite = $section->addTable($tableStyleConformite); |
144 | $headersTable = $tableData[0]; |
145 | $tableConformite->addRow(null, ['tblHeader' => true, 'cantsplit' => true]); |
146 | foreach ($headersTable as $element) { |
147 | $cell = $tableConformite->addCell(2500, $this->cellHeadStyle); |
148 | $cell->addText($element, $this->textHeadStyle); |
149 | } |
150 | unset($tableData[0]); |
151 | foreach ($tableData as $line) { |
152 | $tableConformite->addRow(null, ['cantsplit' => true]); |
153 | $cell1 = $tableConformite->addCell(2500); |
154 | $cell1->addText($line[0]); |
155 | $cell2 = $tableConformite->addCell(2500); |
156 | $cell2->addText($line[1]); |
157 | $cell3 = $tableConformite->addCell(2500); |
158 | $cell3->addText($line[3]); |
159 | $styleCellConformite = match ($line[2]) { |
160 | 'Conforme' => ['bgColor' => 'bce292'], |
161 | 'Non-conformité mineure' => ['bgColor' => 'fac9ad'], |
162 | 'Non-conformité majeure' => ['bgColor' => 'ffa7a7'], |
163 | 'Non évalué' => ['bgColor' => 'ffffff'], |
164 | }; |
165 | $cell4 = $tableConformite->addCell(2500, $styleCellConformite); |
166 | $cell4->addText($line[2], ['bold' => true]); |
167 | } |
168 | } |
169 | |
170 | if (false === $withAIPD) { |
171 | return; |
172 | } |
173 | // Analyse impact |
174 | $section->addTitle('Analyse d’impact', 2); |
175 | |
176 | $cntAipdToDo = 0; |
177 | $cntAipdRealised = 0; |
178 | foreach ($data as $treatment) { |
179 | $conformite = $treatment->getConformiteTraitement(); |
180 | $aipd = null; |
181 | if ($conformite) { |
182 | $aipd = $conformite->getLastAnalyseImpact(); |
183 | } |
184 | |
185 | if ($conformite && $conformite->getNeedsAipd()) { |
186 | ++$cntAipdToDo; |
187 | } |
188 | |
189 | if ($aipd) { |
190 | ++$cntAipdRealised; |
191 | } |
192 | } |
193 | |
194 | $section->addText("Une analyse d’impact sur la protection des données est une étude, qui doit être réalisée si possible en amont du projet, sur des traitements contenant des critères susceptibles d'engendrer un risque élevé pour les droits et libertés des personnes concernées. "); |
195 | if (0 === $cntAipdRealised) { |
196 | $section->addText('À ce jour, il n’y a pas eu d’Analyse d’impact réalisées.'); |
197 | } |
198 | |
199 | $textrun = $section->addTextRun(); |
200 | $textrun->addText('Le tableau des traitements à risque et à valeur de preuve '); |
201 | $textrun->addLink('AipdRisks', 'figure en annexe.', ['underline' => 'single'], [], true); |
202 | |
203 | $section->addText('Ci-dessous, la liste des traitements pour lequel une analyse d’impact sur la protection des données est requise. Au vu des critères, il semble que ' . $cntAipdToDo . ' traitements requière(nt) une analyse d’impact.'); |
204 | |
205 | $tableNeedAipd = $section->addTable($tableStyleConformite); |
206 | $tableNeedAipd->addRow(null, ['tblHeader' => true, 'cantsplit' => true]); |
207 | foreach (['Nom du traitement', 'Données sensibles', 'Critères de risques'] as $element) { |
208 | $cell = $tableNeedAipd->addCell(2500, $this->cellHeadStyle); |
209 | $cell->addText($element, $this->textHeadStyle); |
210 | } |
211 | |
212 | $aipdFinished = []; |
213 | foreach ($data as $treatment) { |
214 | $cnt_sensible = 0; |
215 | $sensibleDatas = []; |
216 | $specificTreatments = []; |
217 | $treatment->isLargeScaleCollection() ? $specificTreatments[] = 'Collecte à large échelle' : null; |
218 | $treatment->isDataCrossing() ? $specificTreatments[] = 'Croisement d\'ensemble de données' : null; |
219 | $treatment->isAutomatedDecisionsWithLegalEffect() ? $specificTreatments[] = 'Décision automatique avec effet juridique' : null; |
220 | $treatment->isEvaluationOrRating() ? $specificTreatments[] = 'Évaluation ou notation' : null; |
221 | $treatment->isAutomaticExclusionService() ? $specificTreatments[] = 'Exclusion du bénéfice d\'un droit, d’un service ou contrat' : null; |
222 | $treatment->isVulnerablePeople() ? $specificTreatments[] = 'Personnes vulnérables' : null; |
223 | $treatment->isSystematicMonitoring() ? $specificTreatments[] = 'Surveillance systématique' : null; |
224 | $treatment->isInnovativeUse() ? $specificTreatments[] = 'Usage innovant' : null; |
225 | |
226 | foreach ($treatment->getDataCategories() as $category) { |
227 | if ($category->isSensible()) { |
228 | $sensibleDatas[] = $category; |
229 | } |
230 | } |
231 | if ($treatment->getConformiteTraitement() && $treatment->getConformiteTraitement()->getNeedsAipd()) { |
232 | $tableNeedAipd->addRow(null, ['cantsplit' => true]); |
233 | $cell = $tableNeedAipd->addCell(2500); |
234 | $cell->addText($treatment->getName()); |
235 | $cell = $tableNeedAipd->addCell(2500); |
236 | foreach ($sensibleDatas as $sensibleData) { |
237 | $cell->addListItem(htmlspecialchars((string) $sensibleData, ENT_COMPAT, 'UTF-8'), (int) null, [], [], ['spaceAfter' => 0]); |
238 | } |
239 | $cell = $tableNeedAipd->addCell(2500); |
240 | foreach ($specificTreatments as $specificTreatment) { |
241 | $cell->addListItem($specificTreatment, (int) null, [], [], ['spaceAfter' => 0]); |
242 | } |
243 | } |
244 | |
245 | if ($treatment->getConformiteTraitement() && $aipd = $treatment->getConformiteTraitement()->getLastAnalyseImpact()) { |
246 | if ('non_realisee' !== $aipd->getStatut() && 'en_cours' !== $aipd->getStatut()) { |
247 | $aipdFinished[] = [ |
248 | $treatment->getName(), |
249 | $treatment->getConformiteTraitement()->getLastAnalyseImpact()->getUpdatedAt(), |
250 | $treatment->getConformiteTraitement()->getLastAnalyseImpact()->getAvisReferent(), |
251 | $treatment->getConformiteTraitement()->getLastAnalyseImpact()->getAvisDpd(), |
252 | $treatment->getConformiteTraitement()->getLastAnalyseImpact()->getAvisRepresentant(), |
253 | $treatment->getConformiteTraitement()->getLastAnalyseImpact()->getAvisResponsable(), |
254 | ]; |
255 | } |
256 | } |
257 | } |
258 | |
259 | $section->addTextBreak(); |
260 | $text = match (count($aipdFinished)) { |
261 | 0 => "Aucun traitement n'a fait l'objet d'une analyse d'impact.", |
262 | 1 => "1 traitement a fait l'objet d'une analyse d'impact.", |
263 | default => count($aipdFinished) . ' traitements ont fait l’objet d’une analyse d’impact.', |
264 | }; |
265 | $section->addText($text); |
266 | |
267 | $tableAipdExist = $section->addTable($tableStyleConformite); |
268 | $tableAipdExist->addRow(null, ['tblHeader' => true, 'cantSplit' => true]); |
269 | foreach (['Traitements', 'Date de réalisation de l’AIPD', 'Avis du référent RGPD', 'Avis du DPD', 'Avis des représentants des personnes concernées', 'Validation du responsable du traitement'] as $element) { |
270 | $cell = $tableAipdExist->addCell(1000, $this->cellHeadStyle); |
271 | $cell->addText($element, $this->textHeadStyle); |
272 | } |
273 | foreach ($aipdFinished as $line) { |
274 | $tableAipdExist->addRow(null, ['cantSplit' => true]); |
275 | $cell = $tableAipdExist->addCell(1000); |
276 | $cell->addText($line[0]); |
277 | $cell = $tableAipdExist->addCell(1000); |
278 | $cell->addText($line[1]->format('d/m/Y')); |
279 | for ($i = 2; $i <= 5; ++$i) { |
280 | $cell = $tableAipdExist->addCell(1000, ['bgColor' => $this->colorCell($line[$i]->getReponse())]); |
281 | $cell->addText($this->valueCell($line[$i]->getReponse())); |
282 | } |
283 | } |
284 | } |
285 | |
286 | private function colorCell($value) |
287 | { |
288 | $return_value = match ($value) { |
289 | 'favorable' => 'bce292', |
290 | 'defavorable' => 'ffa7a7', |
291 | 'pas_de_reponse' => 'ffffff', |
292 | 'favorable_reserve' => 'fac9ad', |
293 | }; |
294 | |
295 | return $return_value; |
296 | } |
297 | |
298 | private function valueCell($value) |
299 | { |
300 | $return_value = match ($value) { |
301 | 'favorable' => 'Favorable', |
302 | 'defavorable' => 'Défavorable', |
303 | 'pas_de_reponse' => 'Pas de réponse', |
304 | 'favorable_reserve' => 'Favorable avec réserve', |
305 | }; |
306 | |
307 | return $return_value; |
308 | } |
309 | |
310 | public function addSyntheticView(Section $section, array $data): void |
311 | { |
312 | $section->addTitle('Liste des traitements', 1); |
313 | $section->addBookmark('Traitements en annexe'); |
314 | |
315 | uasort($data, [$this, 'sortTreatmentByConformiteTraitementByLevelAndTreatmentName']); |
316 | |
317 | // Table data |
318 | // Add header |
319 | $tableData = [ |
320 | [ |
321 | 'Traitement', |
322 | 'Gestionnaire', |
323 | 'Date de révision de la conformité', |
324 | 'Conformité', |
325 | ], |
326 | ]; |
327 | |
328 | /** @var Treatment $treatment */ |
329 | foreach ($data as $treatment) { |
330 | $conformiteTraitement = $treatment->getConformiteTraitement(); |
331 | $level = ConformiteTraitementCompletion::getConformiteTraitementLevel($conformiteTraitement); |
332 | |
333 | $date = null; |
334 | if (!\is_null($conformiteTraitement)) { |
335 | $date = $conformiteTraitement->getCreatedAt(); |
336 | } |
337 | |
338 | $tableData[] = [ |
339 | $treatment->getName(), |
340 | $treatment->getManager(), |
341 | $this->getDate($date, 'd/m/Y'), |
342 | ConformiteTraitementLevelDictionary::getConformites()[$level], |
343 | ]; |
344 | } |
345 | |
346 | $this->addTable($section, $tableData, true, self::TABLE_ORIENTATION_HORIZONTAL); |
347 | } |
348 | |
349 | public function addDetailedView(Section $section, array $data): void |
350 | { |
351 | $section->addTitle('Détail des traitements', 1); |
352 | |
353 | /** @var Treatment $treatment */ |
354 | foreach ($data as $key => $treatment) { |
355 | $conformiteTraitement = $treatment->getConformiteTraitement(); |
356 | if (\is_null($conformiteTraitement)) { |
357 | continue; |
358 | } |
359 | |
360 | if (0 != $key) { |
361 | $section->addPageBreak(); |
362 | } |
363 | |
364 | $questionsData = [ |
365 | [ |
366 | 'data' => [ |
367 | 'Principes fondamentaux', |
368 | ['text' => 'Conformité', 'style' => $this->textHeadStyle], |
369 | ['text' => 'Actions de protections', 'style' => $this->textHeadStyle], |
370 | ], |
371 | 'style' => [ |
372 | 'bgColor' => '3c8dbc', |
373 | 'bold' => true, |
374 | 'color' => 'ffffff', |
375 | ], |
376 | ], |
377 | ]; |
378 | |
379 | $reponses = \iterable_to_array($conformiteTraitement->getReponses()); |
380 | |
381 | uasort($reponses, [$this, 'sortReponseByQuestionPosition']); |
382 | |
383 | foreach ($reponses as $reponse) { |
384 | $actionsProtections = \array_map(function (Mesurement $mesurement) { |
385 | return $mesurement->getName(); |
386 | }, \iterable_to_array($reponse->getActionProtections())); |
387 | |
388 | $questionsData[] = [ |
389 | $reponse->getQuestion()->getQuestion(), |
390 | $reponse->isConforme() ? 'Conforme' : 'Non-conforme', |
391 | !empty($actionsProtections) ? join(', ', $actionsProtections) : 'Pas d\'action', |
392 | ]; |
393 | } |
394 | |
395 | $section->addTitle($conformiteTraitement->getTraitement()->getName(), 3); |
396 | $this->addTable($section, $questionsData, true, self::TABLE_ORIENTATION_VERTICAL); |
397 | |
398 | $historyData = [ |
399 | [ |
400 | 'Date de création', |
401 | $this->getDate($conformiteTraitement->getCreatedAt()), |
402 | ], |
403 | [ |
404 | 'Date de modification', |
405 | $this->getDate($conformiteTraitement->getUpdatedAt()), |
406 | ], |
407 | [ |
408 | 'Modifié par', |
409 | $conformiteTraitement->getUpdatedBy(), |
410 | ], |
411 | ]; |
412 | |
413 | $section->addTitle('Historique', 3); |
414 | $this->addTable($section, $historyData, false, self::TABLE_ORIENTATION_VERTICAL); |
415 | } |
416 | } |
417 | |
418 | private function sortTreatmentByConformiteTraitementByLevelAndTreatmentName(Treatment $a, Treatment $b) |
419 | { |
420 | $weightA = ConformiteTraitementLevelDictionary::getConformitesWeight()[ConformiteTraitementCompletion::getConformiteTraitementLevel($a->getConformiteTraitement())]; |
421 | $weightB = ConformiteTraitementLevelDictionary::getConformitesWeight()[ConformiteTraitementCompletion::getConformiteTraitementLevel($b->getConformiteTraitement())]; |
422 | |
423 | if ($weightA === $weightB) { |
424 | return strcmp($a->getName(), $b->getName()); |
425 | } |
426 | |
427 | return ($weightA < $weightB) ? -1 : 1; |
428 | } |
429 | |
430 | private function sortReponseByQuestionPosition(Reponse $a, Reponse $b) |
431 | { |
432 | $orderA = $a->getQuestion()->getPosition(); |
433 | $orderB = $b->getQuestion()->getPosition(); |
434 | |
435 | return ($orderA < $orderB) ? -1 : 1; |
436 | } |
437 | |
438 | public function SyntheticAnnexeList($section, $treatments) |
439 | { |
440 | $section->addBookmark('listConformityTreatments'); |
441 | $section->addTitle('Synthèse de la conformité des traitements évalués', 2); |
442 | $section->addText('Légende :'); |
443 | $section->AddListItem('C = Conforme'); |
444 | $section->AddListItem('NCM = Non conforme mineure'); |
445 | $section->AddListItem('NC = Non conforme majeure'); |
446 | |
447 | $styleCellHeader = ['textDirection' => \PhpOffice\PhpWord\Style\Cell::TEXT_DIR_BTLR, 'bgColor' => '3c8dbc', 'vAlign' => 'center']; |
448 | |
449 | // Affichage du header du tableau |
450 | $tableSyntheticAnnexeList = $section->addTable($this->tableStyle); |
451 | $tableSyntheticAnnexeList->addRow(2000, ['tblHeader' => true, 'cantsplit' => true]); |
452 | $cell = $tableSyntheticAnnexeList->addCell(1000, ['bgColor' => '3c8dbc', 'vAlign' => 'bottom']); |
453 | $cell->addText('Traitements', $this->textHeadStyle); |
454 | |
455 | $ConformiteNames = ['Finalités', 'Licéité du traitement', 'Minimisation des données', 'Qualité des données', 'Durées de conservation', 'Information des personnes', 'Recueil du consentement', "Droit d'Accès", 'Droit de rectification', 'Droit de limitation', 'Droit de portabilité', "Droit d'effacement", "Droit d'opposition", 'Sous-traitance', 'Transferts hors UE']; |
456 | foreach ($ConformiteNames as $item) { |
457 | $cell = $tableSyntheticAnnexeList->addCell(300, $styleCellHeader); |
458 | $cell->addText($item, $this->textHeadStyle); |
459 | } |
460 | |
461 | $cell = $tableSyntheticAnnexeList->addCell(100, ['borderTopColor' => 'ffffff', 'borderTopSize' => 2, 'borderBottomColor' => 'ffffff', 'borderBottomSize' => 2]); |
462 | $cell->addText(''); |
463 | $cell = $tableSyntheticAnnexeList->addCell(300, ['bgColor' => '3c8dbc', 'vAlign' => 'bottom']); |
464 | $cell->addText('C', $this->textHeadStyle); |
465 | $cell = $tableSyntheticAnnexeList->addCell(300, ['bgColor' => '3c8dbc', 'vAlign' => 'bottom']); |
466 | $cell->addText('NCM', $this->textHeadStyle); |
467 | $cell = $tableSyntheticAnnexeList->addCell(300, ['bgColor' => '3c8dbc', 'vAlign' => 'bottom']); |
468 | $cell->addText('NC', $this->textHeadStyle); |
469 | |
470 | // End header |
471 | |
472 | $listConformityName = [ |
473 | 'C' => [1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 0, 7 => 0, 8 => 0, 9 => 0, 10 => 0, 11 => 0, 12 => 0, 13 => 0, 14 => 0, 15 => 0], |
474 | 'NC' => [1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 0, 7 => 0, 8 => 0, 9 => 0, 10 => 0, 11 => 0, 12 => 0, 13 => 0, 14 => 0, 15 => 0], |
475 | 'NCM' => [1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 0, 7 => 0, 8 => 0, 9 => 0, 10 => 0, 11 => 0, 12 => 0, 13 => 0, 14 => 0, 15 => 0], |
476 | ]; |
477 | |
478 | // Affichage des données de chaque conformité de traitement |
479 | foreach ($treatments as $treatment) { |
480 | if ($treatment->getConformiteTraitement()) { |
481 | $ConformityTreatmentValues = []; |
482 | $sorted = $treatment->getConformiteTraitement()->getReponses()->toArray(); |
483 | usort($sorted, function (Reponse $rep1, Reponse $rep2) { |
484 | return $rep1->getQuestion()->getPosition() - $rep2->getQuestion()->getPosition(); |
485 | }); |
486 | /** @var Reponse $response */ |
487 | foreach ($sorted as $response) { |
488 | // get number of planned actions for this response |
489 | $plannedActions = 0; |
490 | /** @var Mesurement $actionProtection */ |
491 | foreach ($response->getActionProtections() as $actionProtection) { |
492 | if (!\is_null($actionProtection->getPlanificationDate())) { |
493 | ++$plannedActions; |
494 | } |
495 | } |
496 | $NonConformityValue = $plannedActions > 0 ? 'NCM' : 'NC'; |
497 | $ConformityTreatmentValues[$response->getQuestion()->getPosition()] = $response->isConforme() ? 'C' : $NonConformityValue; |
498 | } |
499 | |
500 | $tableSyntheticAnnexeList->addRow(); |
501 | $cell = $tableSyntheticAnnexeList->addCell(1000); |
502 | $cell->addText($treatment->getName(), ['size' => 8]); |
503 | |
504 | $C = 0; |
505 | $NC = 0; |
506 | $NCM = 0; |
507 | |
508 | foreach ($ConformityTreatmentValues as $key => $value) { |
509 | // For each question add a cell saying if conforme or not |
510 | $cell = $tableSyntheticAnnexeList->addCell(300, ['bgColor' => $this->BgColorSyntheticTreatment($value), 'vAlign' => 'center']); |
511 | $cell->addText($value, ['size' => 8], ['alignment' => 'center']); |
512 | ++$listConformityName[$value][$key]; |
513 | |
514 | match ($value) { |
515 | 'C' => $C++, |
516 | 'NC' => $NC++, |
517 | 'NCM' => $NCM++, |
518 | }; |
519 | } |
520 | |
521 | $cell = $tableSyntheticAnnexeList->addCell(100, ['borderTopColor' => 'ffffff', 'borderTopSize' => 2, 'borderBottomColor' => 'ffffff', 'borderBottomSize' => 2]); |
522 | $cell->addText(''); |
523 | $cell = $tableSyntheticAnnexeList->addCell(300, ['bgColor' => 'bce292', 'vAlign' => 'center']); |
524 | $cell->addText($C, ['bold' => true], ['alignment' => 'center']); |
525 | $cell = $tableSyntheticAnnexeList->addCell(300, ['bgColor' => 'ffff80', 'vAlign' => 'center']); |
526 | $cell->addText($NCM, ['bold' => true], ['alignment' => 'center']); |
527 | $cell = $tableSyntheticAnnexeList->addCell(300, ['bgColor' => 'ffa7a7', 'vAlign' => 'center']); |
528 | $cell->addText($NC, ['bold' => true], ['alignment' => 'center']); |
529 | } |
530 | } |
531 | |
532 | $tableSyntheticAnnexeList->addRow(60, ['exactHeight' => true]); |
533 | $cell = $tableSyntheticAnnexeList->addCell(1000, ['borderTopColor' => 'ffffff', 'borderTopSize' => 2, 'borderBottomColor' => 'ffffff', 'borderBottomSize' => 2, 'borderLeftColor' => 'ffffff', 'borderLeftSize' => 2, 'borderRightColor' => 'ffffff', 'borderRightSize' => 2]); |
534 | $cell->addText(''); |
535 | |
536 | foreach ($listConformityName as $key => $datas) { |
537 | $tableSyntheticAnnexeList->addRow(400, ['exactHeight' => true]); |
538 | $cell = $tableSyntheticAnnexeList->addCell(1000, ['bgColor' => '3c8dbc']); |
539 | $cell->addText($key, $this->textHeadStyle, ['alignment' => 'right']); |
540 | foreach ($datas as $key1 => $item) { |
541 | $cell = $tableSyntheticAnnexeList->addCell(300, ['bgColor' => $this->BgColorSyntheticTreatment($key)]); |
542 | $cell->addText($item, ['bold' => true], ['alignment' => 'center']); |
543 | |
544 | if (15 === $key1) { |
545 | $cell = $tableSyntheticAnnexeList->addCell(100, ['borderTopColor' => 'ffffff', 'borderTopSize' => 2, 'borderRightColor' => 'ffffff', 'BorderRightSize' => 2, 'borderBottomColor' => 'ffffff', 'borderBottomSize' => 2]); |
546 | $cell->addText(''); |
547 | } |
548 | } |
549 | } |
550 | } |
551 | |
552 | private function BgColorSyntheticTreatment($value) |
553 | { |
554 | $return_value = match ($value) { |
555 | 'C' => 'bce292', |
556 | 'NC' => 'ffa7a7', |
557 | 'NCM' => 'ffff80', |
558 | }; |
559 | |
560 | return $return_value; |
561 | } |
562 | } |