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