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