Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
9.95% |
37 / 372 |
|
23.08% |
6 / 26 |
CRAP | |
0.00% |
0 / 1 |
ConformiteTraitementController | |
9.95% |
37 / 372 |
|
23.08% |
6 / 26 |
9605.07 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
14 / 14 |
|
100.00% |
1 / 1 |
3 | |||
getDomain | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getModel | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getModelClass | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
reportAction | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
6 | |||
getFormType | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getListData | |
85.71% |
6 / 7 |
|
0.00% |
0 / 1 |
3.03 | |||
listAction | |
100.00% |
13 / 13 |
|
100.00% |
1 / 1 |
1 | |||
createAction | |
0.00% |
0 / 30 |
|
0.00% |
0 / 1 |
110 | |||
editAction | |
0.00% |
0 / 31 |
|
0.00% |
0 / 1 |
156 | |||
startAipdAction | |
0.00% |
0 / 32 |
|
0.00% |
0 / 1 |
132 | |||
setAnalyseReponsesQuestionConformite | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
6 | |||
listDataTables | |
0.00% |
0 / 23 |
|
0.00% |
0 / 1 |
110 | |||
getPlanifiedMesurements | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
20 | |||
getIcon | |
0.00% |
0 / 25 |
|
0.00% |
0 / 1 |
56 | |||
getLabelAndKeysArray | |
0.00% |
0 / 38 |
|
0.00% |
0 / 1 |
12 | |||
getRequestCriteria | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
12 | |||
getTreatmentLink | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
getAvisAipd | |
0.00% |
0 / 26 |
|
0.00% |
0 / 1 |
72 | |||
getQuestionConformity | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
56 | |||
getTreatmentConformity | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
30 | |||
generateActionCellContent | |
0.00% |
0 / 38 |
|
0.00% |
0 / 1 |
132 | |||
returnHtmlAction | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
isTreatmentInUserServices | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
getResults | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
12 | |||
getBaseDataTablesResponse | |
0.00% |
0 / 8 |
|
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\Registry\Controller; |
25 | |
26 | use App\Application\Controller\CRUDController; |
27 | use App\Application\Symfony\Security\UserProvider; |
28 | use App\Application\Traits\ServersideDatatablesTrait; |
29 | use App\Domain\AIPD\Converter\ModeleToAnalyseConverter; |
30 | use App\Domain\AIPD\Model\AnalyseImpact; |
31 | use App\Domain\AIPD\Repository as AipdRepository; |
32 | use App\Domain\Documentation\Model\Category; |
33 | use App\Domain\Registry\Calculator\Completion\ConformiteTraitementCompletion; |
34 | use App\Domain\Registry\Dictionary\ConformiteTraitementLevelDictionary; |
35 | use App\Domain\Registry\Form\Type\ConformiteTraitement\ConformiteTraitementType; |
36 | use App\Domain\Registry\Model; |
37 | use App\Domain\Registry\Model\ConformiteTraitement\ConformiteTraitement; |
38 | use App\Domain\Registry\Model\Treatment; |
39 | use App\Domain\Registry\Repository; |
40 | use App\Domain\Registry\Symfony\EventSubscriber\Event\ConformiteTraitementEvent; |
41 | use App\Domain\Reporting\Handler\WordHandler; |
42 | use App\Domain\User\Dictionary\UserRoleDictionary; |
43 | use App\Domain\User\Model\User; |
44 | use App\Domain\User\Repository as UserRepository; |
45 | use Doctrine\ORM\EntityManagerInterface; |
46 | use Doctrine\ORM\Tools\Pagination\Paginator; |
47 | use Knp\Snappy\Pdf; |
48 | use Symfony\Component\EventDispatcher\EventDispatcherInterface; |
49 | use Symfony\Component\HttpFoundation\JsonResponse; |
50 | use Symfony\Component\HttpFoundation\Request; |
51 | use Symfony\Component\HttpFoundation\Response; |
52 | use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; |
53 | use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; |
54 | use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; |
55 | use Symfony\Component\Routing\RouterInterface; |
56 | use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; |
57 | use Symfony\Contracts\Translation\TranslatorInterface; |
58 | |
59 | /** |
60 | * @property Repository\ConformiteTraitement\ConformiteTraitement $repository |
61 | */ |
62 | class ConformiteTraitementController extends CRUDController |
63 | { |
64 | use ServersideDatatablesTrait; |
65 | |
66 | /** |
67 | * @var UserRepository\Collectivity |
68 | */ |
69 | protected $collectivityRepository; |
70 | |
71 | /** |
72 | * @var Repository\Treatment |
73 | */ |
74 | protected $treatmentRepository; |
75 | |
76 | /** |
77 | * @var WordHandler |
78 | */ |
79 | protected $wordHandler; |
80 | |
81 | /** |
82 | * @var AuthorizationCheckerInterface |
83 | */ |
84 | protected $authorizationChecker; |
85 | |
86 | /** |
87 | * @var UserProvider |
88 | */ |
89 | protected $userProvider; |
90 | |
91 | /** |
92 | * @var Repository\ConformiteTraitement\Question |
93 | */ |
94 | protected $questionRepository; |
95 | |
96 | /** |
97 | * @var EventDispatcherInterface |
98 | */ |
99 | protected $dispatcher; |
100 | |
101 | private AipdRepository\ModeleAnalyse $modeleRepository; |
102 | |
103 | private RouterInterface $router; |
104 | |
105 | public function __construct( |
106 | EntityManagerInterface $entityManager, |
107 | TranslatorInterface $translator, |
108 | Repository\ConformiteTraitement\ConformiteTraitement $repository, |
109 | UserRepository\Collectivity $collectivityRepository, |
110 | WordHandler $wordHandler, |
111 | AuthorizationCheckerInterface $authorizationChecker, |
112 | UserProvider $userProvider, |
113 | Repository\Treatment $treatmentRepository, |
114 | Repository\ConformiteTraitement\Question $questionRepository, |
115 | EventDispatcherInterface $dispatcher, |
116 | Pdf $pdf, |
117 | AipdRepository\ModeleAnalyse $modeleRepository, |
118 | RouterInterface $router, |
119 | ) { |
120 | parent::__construct($entityManager, $translator, $repository, $pdf, $userProvider, $authorizationChecker); |
121 | $this->collectivityRepository = $collectivityRepository; |
122 | $this->wordHandler = $wordHandler; |
123 | $this->authorizationChecker = $authorizationChecker; |
124 | $this->userProvider = $userProvider; |
125 | $this->treatmentRepository = $treatmentRepository; |
126 | $this->questionRepository = $questionRepository; |
127 | $this->dispatcher = $dispatcher; |
128 | $this->modeleRepository = $modeleRepository; |
129 | $this->router = $router; |
130 | $this->repository = $repository; |
131 | |
132 | // Deny access to single collectivity users if conformite traitement module is disabled |
133 | // Fixes https://gitlab.adullact.net/soluris/madis/-/issues/949 |
134 | $user = $userProvider->getAuthenticatedUser(); |
135 | if ($user && !$user->hasModuleConformiteTraitement()) { |
136 | throw new AccessDeniedHttpException('Ce module est désactivé sur votre structure'); |
137 | } |
138 | } |
139 | |
140 | protected function getDomain(): string |
141 | { |
142 | return 'registry'; |
143 | } |
144 | |
145 | protected function getModel(): string |
146 | { |
147 | return 'conformite_traitement'; |
148 | } |
149 | |
150 | protected function getModelClass(): string |
151 | { |
152 | return ConformiteTraitement::class; |
153 | } |
154 | |
155 | public function reportAction() |
156 | { |
157 | $collectivity = $this->userProvider->getAuthenticatedUser()->getCollectivity(); |
158 | |
159 | if (!$collectivity->isHasModuleConformiteTraitement()) { |
160 | return $this->redirectToRoute('registry_conformite_organisation_list'); |
161 | } |
162 | $objects = $this->treatmentRepository->findAllByCollectivity( |
163 | $collectivity |
164 | ); |
165 | |
166 | return $this->wordHandler->generateRegistryConformiteTraitementReport($objects); |
167 | } |
168 | |
169 | protected function getFormType(): string |
170 | { |
171 | return ConformiteTraitementType::class; |
172 | } |
173 | |
174 | protected function getListData() |
175 | { |
176 | $collectivity = null; |
177 | $user = $this->userProvider->getAuthenticatedUser(); |
178 | |
179 | if (!$this->authorizationChecker->isGranted('ROLE_ADMIN')) { |
180 | $collectivity = $user->getCollectivity(); |
181 | } |
182 | |
183 | if (\in_array(UserRoleDictionary::ROLE_REFERENT, $user->getRoles())) { |
184 | $collectivity = \iterable_to_array($user->getCollectivitesReferees()); |
185 | } |
186 | |
187 | return $this->treatmentRepository->findAllActiveByCollectivityWithHasModuleConformiteTraitement($collectivity); |
188 | } |
189 | |
190 | public function listAction(): Response |
191 | { |
192 | $user = $this->userProvider->getAuthenticatedUser(); |
193 | $services_user = $user->getServices(); |
194 | $criteria = []; |
195 | |
196 | $category = $this->entityManager->getRepository(Category::class)->findOneBy([ |
197 | 'name' => 'Conformité des traitements', |
198 | ]); |
199 | |
200 | return $this->render('Registry/Conformite_traitement/list.html.twig', [ |
201 | 'objects' => $this->getListData(), |
202 | 'totalItem' => $this->repository->count($criteria), |
203 | 'category' => $category, |
204 | 'services_user' => $services_user, |
205 | 'route' => $this->router->generate('registry_conformite_traitement_list_datatables'), |
206 | ]); |
207 | } |
208 | |
209 | /** |
210 | * {@inheritdoc} |
211 | * Override method in order to hydrate questions. |
212 | */ |
213 | public function createAction(Request $request): Response |
214 | { |
215 | /** |
216 | * @var ConformiteTraitement |
217 | */ |
218 | $object = new ConformiteTraitement(); |
219 | |
220 | /** @var User $user */ |
221 | $user = $this->getUser(); |
222 | |
223 | /** @var Treatment $traitement */ |
224 | $traitement = $this->treatmentRepository->findOneById($request->get('idTraitement')); |
225 | if ($traitement->getCollectivity() && !$traitement->getCollectivity()->isHasModuleConformiteTraitement()) { |
226 | throw new AccessDeniedHttpException('La structure de ce traitement a le module conformité des traitements désactivé'); |
227 | } |
228 | $object->setTraitement($traitement); |
229 | |
230 | if (!$user->hasAccessTo($traitement)) { |
231 | return $this->redirectToRoute($this->getRouteName('list')); |
232 | } |
233 | |
234 | $service = $object->getTraitement()->getService(); |
235 | $user = $this->userProvider->getAuthenticatedUser(); |
236 | $services_user = $user->getServices(); |
237 | |
238 | if (!($this->authorizationChecker->isGranted('ROLE_USER') && ($services_user->isEmpty() || $services_user->contains($service)))) { |
239 | return $this->redirectToRoute('registry_treatment_list'); |
240 | } |
241 | |
242 | // Before create form, hydrate answers array with potential question responses |
243 | foreach ($this->questionRepository->findAll(['position' => 'ASC']) as $question) { |
244 | $reponse = new Model\ConformiteTraitement\Reponse(); |
245 | $reponse->setQuestion($question); |
246 | $object->addReponse($reponse); |
247 | } |
248 | |
249 | $form = $this->createForm($this->getFormType(), $object); |
250 | |
251 | $form->handleRequest($request); |
252 | if ($form->isSubmitted() && $form->isValid()) { |
253 | $em = $this->getDoctrine()->getManager(); |
254 | $em->persist($object); |
255 | $em->flush(); |
256 | |
257 | $this->addFlash('success', $this->getFlashbagMessage('success', 'create', $object)); |
258 | |
259 | return $this->redirectToRoute($this->getRouteName('list')); |
260 | } |
261 | |
262 | $serviceEnabled = $object->getTraitement()->getCollectivity()->getIsServicesEnabled(); |
263 | |
264 | return $this->render($this->getTemplatingBasePath('create'), [ |
265 | 'form' => $form->createView(), |
266 | 'serviceEnabled' => $serviceEnabled, |
267 | ]); |
268 | } |
269 | |
270 | /** |
271 | * {@inheritdoc} |
272 | * Override method in order to hydrate new questions. |
273 | * |
274 | * @param string $id The ID of the data to edit |
275 | */ |
276 | public function editAction(Request $request, string $id): Response |
277 | { |
278 | /** @var ConformiteTraitement $object */ |
279 | $object = $this->repository->findOneById($id); |
280 | if (!$object) { |
281 | throw new NotFoundHttpException("No object found with ID '{$id}'"); |
282 | } |
283 | |
284 | if (!$object->getTraitement() || !$object->getTraitement()->getCollectivity() || !$object->getTraitement()->getCollectivity()->isHasModuleConformiteTraitement()) { |
285 | throw new NotFoundHttpException("No object found with ID '{$id}'"); |
286 | } |
287 | |
288 | /** @var User $user */ |
289 | $user = $this->getUser(); |
290 | if (!$user->hasAccessTo($object->getTraitement())) { |
291 | return $this->redirectToRoute($this->getRouteName('list')); |
292 | } |
293 | |
294 | $service = $object->getTraitement()->getService(); |
295 | $user = $this->userProvider->getAuthenticatedUser(); |
296 | $services_user = $user->getServices(); |
297 | |
298 | if (!($this->authorizationChecker->isGranted('ROLE_USER') && ($services_user->isEmpty() || $services_user->contains($service)))) { |
299 | return $this->redirectToRoute('registry_treatment_list'); |
300 | } |
301 | |
302 | // Before create form, hydrate new answers array with potential question responses |
303 | foreach ($this->questionRepository->findNewQuestionsNotUseInGivenConformite($object) as $question) { |
304 | $reponse = new Model\ConformiteTraitement\Reponse(); |
305 | $reponse->setQuestion($question); |
306 | $object->addReponse($reponse); |
307 | } |
308 | |
309 | $form = $this->createForm($this->getFormType(), $object, ['validation_groups' => ['default', $this->getModel(), 'edit']]); |
310 | |
311 | $form->handleRequest($request); |
312 | if ($form->isSubmitted() && $form->isValid()) { |
313 | $this->formPrePersistData($object); |
314 | $this->entityManager->persist($object); |
315 | $this->entityManager->flush(); |
316 | |
317 | $this->dispatcher->dispatch(new ConformiteTraitementEvent($object)); |
318 | |
319 | $this->addFlash('success', $this->getFlashbagMessage('success', 'edit', $object)); |
320 | |
321 | return $this->redirectToRoute($this->getRouteName('list')); |
322 | } |
323 | |
324 | $serviceEnabled = $object->getTraitement()->getCollectivity()->getIsServicesEnabled(); |
325 | |
326 | return $this->render($this->getTemplatingBasePath('edit'), [ |
327 | 'form' => $form->createView(), |
328 | 'serviceEnabled' => $serviceEnabled, |
329 | ]); |
330 | } |
331 | |
332 | public function startAipdAction(Request $request, string $id) |
333 | { |
334 | /** @var ConformiteTraitement $conformiteTraitement */ |
335 | $conformiteTraitement = $this->repository->findOneById($id); |
336 | if (!$conformiteTraitement) { |
337 | throw new NotFoundHttpException("No object found with ID '{$id}'"); |
338 | } |
339 | |
340 | /** @var User $user */ |
341 | $user = $this->getUser(); |
342 | $traitement = $conformiteTraitement->getTraitement(); |
343 | if ($traitement->getCollectivity() && !$traitement->getCollectivity()->isHasModuleConformiteTraitement()) { |
344 | throw new AccessDeniedHttpException('La structure de ce traitement a le module conformité des traitements désactivé'); |
345 | } |
346 | if (!$user->hasAccessTo($traitement)) { |
347 | return $this->redirectToRoute($this->getRouteName('list')); |
348 | } |
349 | |
350 | if ($request->isMethod('GET')) { |
351 | return $this->render($this->getTemplatingBasePath('start'), [ |
352 | 'totalItem' => $this->modeleRepository->count(), |
353 | 'route' => $this->router->generate('aipd_analyse_impact_modele_datatables', ['collectivity' => $conformiteTraitement->getTraitement()->getCollectivity()->getId()->toString()]), |
354 | 'conformiteTraitement' => $conformiteTraitement, |
355 | ]); |
356 | } |
357 | |
358 | if (!$request->request->has('modele_choice')) { |
359 | throw new BadRequestHttpException('Parameter modele_choice must be present'); |
360 | } |
361 | |
362 | if (null === $modele = $this->modeleRepository->findOneById($request->request->get('modele_choice'))) { |
363 | throw new NotFoundHttpException('No modele with Id ' . $request->request->get('modele_choice') . ' exists.'); |
364 | } |
365 | |
366 | $analyseImpact = ModeleToAnalyseConverter::createFromModeleAnalyse($modele); |
367 | $analyseImpact->setCreatedAt(new \DateTimeImmutable()); |
368 | $analyseImpact->setConformiteTraitement($conformiteTraitement); |
369 | |
370 | $this->setAnalyseReponsesQuestionConformite($analyseImpact, $conformiteTraitement); |
371 | |
372 | foreach ($analyseImpact->getScenarioMenaces() as $scenarioMenace) { |
373 | if (null !== $scenarioMenace->getMesuresProtections()) { |
374 | foreach ($scenarioMenace->getMesuresProtections() as $mesureProtection) { |
375 | $this->entityManager->persist($mesureProtection); |
376 | } |
377 | } |
378 | } |
379 | |
380 | $this->entityManager->persist($analyseImpact); |
381 | $this->entityManager->flush(); |
382 | |
383 | return $this->redirectToRoute('aipd_analyse_impact_create', [ |
384 | 'id' => $analyseImpact->getId(), |
385 | ]); |
386 | } |
387 | |
388 | private function setAnalyseReponsesQuestionConformite(AnalyseImpact &$analyseImpact, ConformiteTraitement $conformiteTraitement) |
389 | { |
390 | foreach ($conformiteTraitement->getReponses() as $reponse) { |
391 | $q = $reponse->getQuestion()->getQuestion(); |
392 | $q = $analyseImpact->getQuestionConformitesOfName($q); |
393 | $q->setAnalyseImpact($analyseImpact); |
394 | $q->setReponseConformite($reponse); |
395 | $reponse->addAnalyseQuestionConformite($q); |
396 | $this->entityManager->persist($reponse); |
397 | } |
398 | } |
399 | |
400 | public function listDataTables(Request $request): JsonResponse |
401 | { |
402 | $criteria = $this->getRequestCriteria(); |
403 | |
404 | $treatments = $this->getResults($request, $criteria); |
405 | $reponse = $this->getBaseDataTablesResponse($request, $treatments, $criteria); |
406 | |
407 | /** @var Treatment $treatment */ |
408 | foreach ($treatments as $treatment) { |
409 | if (is_array($treatment) && count($treatment) > 0) { |
410 | $treatment = $treatment[0]; |
411 | } |
412 | $actions = $this->generateActionCellContent($treatment); |
413 | |
414 | $reponse['data'][] = [ |
415 | 'icon' => $this->getIcon($treatment), |
416 | 'nom' => $this->getTreatmentLink($treatment), |
417 | 'collectivite' => $this->isGranted('ROLE_REFERENT') ? $treatment->getCollectivity()->getName() : '', |
418 | 'service' => $this->userProvider->getAuthenticatedUser()->hasServices() && $treatment->getService() ? $treatment->getService()->getName() : '', |
419 | 'gestionnaire' => $treatment->getManager(), |
420 | 'conformite_traitement' => $this->getTreatmentConformity($treatment), |
421 | 'conformite_question' => $this->getQuestionConformity($treatment), |
422 | 'eval_createdAt' => $treatment->getConformiteTraitement() ? date_format($treatment->getConformiteTraitement()->getCreatedAt(), 'd/m/Y') : null, |
423 | 'avis_aipd' => $this->getAvisAipd($treatment), |
424 | 'aipd_createdAt' => $treatment->getConformiteTraitement() && $treatment->getConformiteTraitement()->getLastAnalyseImpact() ? date_format($treatment->getConformiteTraitement()->getLastAnalyseImpact()->getCreatedAt(), 'd/m/Y') : null, |
425 | 'actions' => $actions, |
426 | ]; |
427 | } |
428 | |
429 | $jsonResponse = new JsonResponse(); |
430 | $jsonResponse->setJson(\json_encode($reponse)); |
431 | |
432 | return $jsonResponse; |
433 | } |
434 | |
435 | protected function getPlanifiedMesurements(ConformiteTraitement $conformiteTraitement): array |
436 | { |
437 | $planifiedMesurementsToBeNotified = []; |
438 | foreach ($conformiteTraitement->getReponses() as $reponse) { |
439 | $mesurements = \iterable_to_array($reponse->getActionProtectionsPlanifiedNotSeens()); |
440 | foreach ($mesurements as $mesurement) { |
441 | if (!\in_array($mesurement, $planifiedMesurementsToBeNotified)) { |
442 | \array_push($planifiedMesurementsToBeNotified, $mesurement); |
443 | } |
444 | } |
445 | } |
446 | |
447 | return $planifiedMesurementsToBeNotified; |
448 | } |
449 | |
450 | protected function getIcon(Treatment $treatment) |
451 | { |
452 | // return '<span style="background:red">blabla</span>'; |
453 | $conf = $treatment->getConformiteTraitement(); |
454 | $planifiedMesurementToBeNotified = []; |
455 | if ($conf) { |
456 | $planifiedMesurementToBeNotified = $this->getPlanifiedMesurements($conf); |
457 | } |
458 | $result = ''; |
459 | if (count($planifiedMesurementToBeNotified)) { |
460 | $m = ''; |
461 | |
462 | foreach ($planifiedMesurementToBeNotified as $mes) { |
463 | $m .= '<li>' . $mes->getName() . '</li>'; |
464 | } |
465 | |
466 | $result = '<div class="mesurement-hide"> |
467 | <i aria-hidden="true" class="primary-i fas fa-exclamation-circle"></i> |
468 | <div class="primary"> |
469 | <span>' . $this->translator->trans('registry.conformite_traitement.label.tooltip.mesurements_done') . '</span> |
470 | <ul>' . $m . '</ul> |
471 | </div> |
472 | </div>'; |
473 | } |
474 | if ($conf && $conf->getNeedsAipd()) { |
475 | $aipd = $conf->getLastAnalyseImpact(); |
476 | if ($aipd) { |
477 | $result .= '<div> |
478 | <span style="display:none"> |
479 | ' . $this->translator->trans('registry.conformite_traitement.label.tooltip.aipd_in_progress') . ' |
480 | </span> |
481 | <i class="fa fa-exclamation-triangle" aria-label="' . $this->translator->trans('registry.conformite_traitement.label.tooltip.aipd_in_progress') . '" title="' . $this->translator->trans('registry.conformite_traitement.label.tooltip.aipd_in_progress') . '" style="color:#f39c12;"></i> |
482 | </div>'; |
483 | } else { |
484 | $result .= '<div> |
485 | <span style="display:none"> |
486 | ' . $this->translator->trans('registry.conformite_traitement.label.tooltip.aipd_to_do') . ' |
487 | </span> |
488 | <i class="fa fa-exclamation-triangle" aria-label="' . $this->translator->trans('registry.conformite_traitement.label.tooltip.aipd_to_do') . '" title="' . $this->translator->trans('registry.conformite_traitement.label.tooltip.aipd_to_do') . '" style="color:#dd4b39;"></i> |
489 | </div>'; |
490 | } |
491 | } |
492 | |
493 | return $result; |
494 | } |
495 | |
496 | protected function getLabelAndKeysArray(): array |
497 | { |
498 | if ($this->authorizationChecker->isGranted('ROLE_REFERENT')) { |
499 | return [ |
500 | 'icon', |
501 | 'name', |
502 | 'collectivite', |
503 | 'service', |
504 | 'gestionnaire', |
505 | 'conformite_traitement', |
506 | 'conformite_questions', |
507 | 'eval_createdAt', |
508 | 'avis_aipd', |
509 | 'aipd_createdAt', |
510 | 'actions', |
511 | ]; |
512 | } elseif ($this->userProvider->getAuthenticatedUser()->hasServices()) { |
513 | return [ |
514 | 'icon', |
515 | 'name', |
516 | 'service', |
517 | 'gestionnaire', |
518 | 'conformite_traitement', |
519 | 'conformite_questions', |
520 | 'eval_createdAt', |
521 | 'avis_aipd', |
522 | 'aipd_createdAt', |
523 | 'actions', |
524 | ]; |
525 | } |
526 | |
527 | return [ |
528 | 'icon', |
529 | 'name', |
530 | 'gestionnaire', |
531 | 'conformite_traitement', |
532 | 'conformite_questions', |
533 | 'eval_createdAt', |
534 | 'avis_aipd', |
535 | 'aipd_createdAt', |
536 | 'actions', |
537 | ]; |
538 | } |
539 | |
540 | private function getRequestCriteria() |
541 | { |
542 | $criteria = []; |
543 | $user = $this->userProvider->getAuthenticatedUser(); |
544 | |
545 | if (!$this->authorizationChecker->isGranted('ROLE_ADMIN')) { |
546 | $criteria['collectivity'] = $user->getCollectivity(); |
547 | } |
548 | |
549 | if (\in_array(UserRoleDictionary::ROLE_REFERENT, $user->getRoles())) { |
550 | $criteria['collectivity'] = $user->getCollectivitesReferees(); |
551 | } |
552 | |
553 | // Add active treatment criteria |
554 | // Fixes https://gitlab.adullact.net/soluris/madis/-/issues/966 |
555 | $criteria['active'] = true; |
556 | |
557 | // Only for collectivites that have conformité traitement module active |
558 | // Fix for https://gitlab.adullact.net/soluris/madis/-/issues/950#note_147289 |
559 | $criteria['hasModuleConformiteTraitement'] = true; |
560 | |
561 | return $criteria; |
562 | } |
563 | |
564 | private function getTreatmentLink(Treatment $treatment): string |
565 | { |
566 | $path = $this->router->generate('registry_treatment_show', ['id' => $treatment->getId()]); |
567 | |
568 | return '<a href="' . $path . '">' . $treatment->getName() . '</a> '; |
569 | } |
570 | |
571 | private function getAvisAipd(Treatment $treatment) |
572 | { |
573 | if (!$treatment->getConformiteTraitement()) { |
574 | return '<span class="label label-default" style="min-width: 100%; display: inline-block;">Non réalisée</span>'; |
575 | } |
576 | $conf = $treatment->getConformiteTraitement(); |
577 | |
578 | if (null === $conf->getLastAnalyseImpact()) { |
579 | return '<span class="label label-default" style="min-width: 100%; display: inline-block;">Non réalisée</span>'; |
580 | } |
581 | $analyse_impact = $conf->getLastAnalyseImpact(); |
582 | $statut = $analyse_impact->getStatut(); |
583 | |
584 | switch ($statut) { |
585 | case 'defavorable': |
586 | $label = 'Défavorable'; |
587 | $class = 'label-danger'; |
588 | break; |
589 | case 'favorable_reserve': |
590 | $label = 'Favorable avec réserve(s)'; |
591 | $class = 'label-warning'; |
592 | break; |
593 | case 'favorable': |
594 | $label = 'Favorable'; |
595 | $class = 'label-success'; |
596 | break; |
597 | case 'en_cours': |
598 | $label = 'En cours'; |
599 | $class = 'label-default'; |
600 | break; |
601 | default: |
602 | $label = 'Non réalisée'; |
603 | $class = 'label-default'; |
604 | } |
605 | |
606 | return '<span class="label ' . $class . '" style="min-width: 100%; display: inline-block;">' . $label . '</span>'; |
607 | } |
608 | |
609 | private function getQuestionConformity(Treatment $treatment): string |
610 | { |
611 | $res = ''; |
612 | $ct = $treatment->getConformiteTraitement(); |
613 | if ($ct) { |
614 | $nbTotal = $ct->getNbConformes() + $ct->getNbNonConformesMineures() + $ct->getNbNonConformesMajeures(); |
615 | $widthNbConforme = $nbTotal > 0 ? round(($ct->getNbConformes() * 100) / $nbTotal) : 0; |
616 | $widthNbMineure = $nbTotal > 0 ? round(($ct->getNbNonConformesMineures() * 100) / $nbTotal) : 0; |
617 | $widthNbMajeure = 100 - ($widthNbConforme + $widthNbMineure); |
618 | $res .= '<div class="stacked-bar-graph">'; |
619 | if ($widthNbConforme) { |
620 | $res .= '<span style="width:' . $widthNbConforme . '%" class="bar-conforme tooltipchart"><span class="tooltipcharttext">Conforme : ' . $ct->getNbConformes() . '</span></span>'; |
621 | } |
622 | if ($widthNbMineure) { |
623 | $res .= '<span style="width:' . $widthNbMineure . '%" class="bar-non-conforme-mineure tooltipchart"><span class="tooltipcharttext">Non-conforme mineure : ' . $ct->getNbNonConformesMineures() . '</span></span>'; |
624 | } |
625 | if ($widthNbMajeure) { |
626 | $res .= '<span style="width:' . $widthNbMajeure . '%" class="bar-non-conforme-majeure tooltipchart"><span class="tooltipcharttext">Non-conforme majeure : ' . $ct->getNbNonConformesMajeures() . '</span></span>'; |
627 | } |
628 | |
629 | $res .= '</div>'; |
630 | } |
631 | |
632 | return $res; |
633 | } |
634 | |
635 | private function getTreatmentConformity(Treatment $treatment) |
636 | { |
637 | if (!$treatment->getConformiteTraitement()) { |
638 | return '<span class="label label-default" style="min-width: 100%; display: inline-block;">Non évalué</span>'; |
639 | } |
640 | $conf = $treatment->getConformiteTraitement(); |
641 | $level = ConformiteTraitementCompletion::getConformiteTraitementLevel($conf); |
642 | |
643 | $weight = ConformiteTraitementLevelDictionary::getConformitesWeight()[$level]; |
644 | |
645 | switch ($weight) { |
646 | case 1: |
647 | $label = 'Conforme'; |
648 | $class = 'label-success'; |
649 | break; |
650 | case 2: |
651 | $label = 'Non-conforme mineure'; |
652 | $class = 'label-warning'; |
653 | break; |
654 | default: |
655 | $label = 'Non-conforme majeure'; |
656 | $class = 'label-danger'; |
657 | } |
658 | |
659 | return '<span class="label ' . $class . '" style="min-width: 100%; display: inline-block;">' . $label . '</span>'; |
660 | } |
661 | |
662 | private function generateActionCellContent(Treatment $treatment) |
663 | { |
664 | $id = $treatment->getId(); |
665 | $conformityTreatment = $treatment->getConformiteTraitement(); |
666 | $aipd = $conformityTreatment?->getLastAnalyseImpact(); |
667 | $blocHtml = ''; |
668 | $user = $this->userProvider->getAuthenticatedUser(); |
669 | |
670 | $interact = true; |
671 | if ($treatment->getCollectivity()->getIsServicesEnabled() && $user->hasServices() && !$treatment->isInUserServices($user)) { |
672 | $interact = false; |
673 | } |
674 | if ($this->authorizationChecker->isGranted('ROLE_USER') && $interact) { |
675 | if (!$conformityTreatment) { |
676 | $path = $this->router->generate('registry_conformite_traitement_create', ['idTraitement' => $id]); |
677 | $title = $this->translator->trans('registry.conformite_traitement.action.show_conformite_traitement'); |
678 | $class = 'fa-clipboard-check'; |
679 | $blocHtml .= $this->returnHtmlAction($path, $title, $class); |
680 | } else { |
681 | $path = $this->router->generate('registry_conformite_traitement_edit', ['id' => $conformityTreatment->getId()]); |
682 | $title = $this->translator->trans('registry.conformite_traitement.action.show_conformite_traitement'); |
683 | $class = 'fa-clipboard-check'; |
684 | $blocHtml .= $this->returnHtmlAction($path, $title, $class); |
685 | if ($aipd) { |
686 | if ($aipd->isValidated()) { |
687 | $path = $this->router->generate('aipd_analyse_impact_print', ['id' => $aipd->getId()]); |
688 | $title = $this->translator->trans('aipd.analyse_impact.action.print'); |
689 | $class = 'fa-print'; |
690 | $blocHtml .= $this->returnHtmlAction($path, $title, $class); |
691 | } else { |
692 | $path = $this->router->generate('aipd_analyse_impact_edit', ['id' => $aipd->getId()]); |
693 | $title = $this->translator->trans('aipd.analyse_impact.action.edit'); |
694 | $class = 'fa-pencil'; |
695 | $blocHtml .= $this->returnHtmlAction($path, $title, $class); |
696 | } |
697 | } else { |
698 | $path = $this->router->generate('registry_conformite_traitement_start_aipd', ['id' => $conformityTreatment->getId()]); |
699 | $title = $this->translator->trans('aipd.analyse_impact.action.create'); |
700 | $class = 'fa-magnifying-glass-chart'; |
701 | $blocHtml .= $this->returnHtmlAction($path, $title, $class); |
702 | } |
703 | } |
704 | } elseif ($aipd && $aipd->isValidated()) { |
705 | $path = $this->router->generate('aipd_analyse_impact_print', ['id' => $aipd->getId()]); |
706 | $title = $this->translator->trans('aipd.analyse_impact.action.print'); |
707 | $class = 'fa-print'; |
708 | $blocHtml .= $this->returnHtmlAction($path, $title, $class); |
709 | } |
710 | |
711 | return $blocHtml; |
712 | } |
713 | |
714 | private function returnHtmlAction($path, $title, $class) |
715 | { |
716 | return '<a href="' . $path . '"> |
717 | <i aria-hidden="true" class="fa ' . $class . '"></i> |
718 | ' . $title . ' |
719 | </a> '; |
720 | } |
721 | |
722 | private function isTreatmentInUserServices(Treatment $treatment): bool |
723 | { |
724 | $user = $this->userProvider->getAuthenticatedUser(); |
725 | if ($this->authorizationChecker->isGranted('ROLE_ADMIN')) { |
726 | return true; |
727 | } |
728 | |
729 | return $treatment->isInUserServices($user); |
730 | } |
731 | |
732 | protected function getResults(Request $request, array $criteria = []): ?Paginator |
733 | { |
734 | $first = $request->request->get('start'); |
735 | $maxResults = $request->request->get('length'); |
736 | $orders = $request->request->get('order'); |
737 | $columns = $request->request->get('columns'); |
738 | |
739 | $orderColumn = $this->getCorrespondingLabelFromkey($orders[0]['column']); |
740 | $orderDir = $orders[0]['dir']; |
741 | |
742 | $searches = []; |
743 | foreach ($columns as $column) { |
744 | if ('' !== $column['search']['value']) { |
745 | $searches[$column['data']] = $column['search']['value']; |
746 | } |
747 | } |
748 | |
749 | return $this->treatmentRepository->findPaginated($first, $maxResults, $orderColumn, $orderDir, $searches, $criteria); |
750 | } |
751 | |
752 | protected function getBaseDataTablesResponse(Request $request, $results, array $criteria = []) |
753 | { |
754 | $draw = $request->request->get('draw'); |
755 | |
756 | $reponse = [ |
757 | 'draw' => $draw, |
758 | 'recordsTotal' => $this->treatmentRepository->count($criteria), |
759 | 'recordsFiltered' => count($results), |
760 | 'data' => [], |
761 | ]; |
762 | |
763 | return $reponse; |
764 | } |
765 | } |