Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
8.87% covered (danger)
8.87%
11 / 124
46.15% covered (danger)
46.15%
6 / 13
CRAP
0.00% covered (danger)
0.00%
0 / 1
ViolationController
8.87% covered (danger)
8.87%
11 / 124
46.15% covered (danger)
46.15%
6 / 13
711.10
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 getDomain
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getModel
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getModelClass
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFormType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isSoftDelete
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 reportAction
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 listAction
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 listDataTables
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 1
90
 isRequestInUserServices
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 getLabelAndKeysArray
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 1
12
 getActionCellsContent
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
30
 getRequestCriteria
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
12
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
22declare(strict_types=1);
23
24namespace App\Domain\Registry\Controller;
25
26use App\Application\Controller\CRUDController;
27use App\Application\Symfony\Security\UserProvider;
28use App\Application\Traits\ServersideDatatablesTrait;
29use App\Domain\Documentation\Model\Category;
30use App\Domain\Registry\Dictionary\ViolationCauseDictionary;
31use App\Domain\Registry\Dictionary\ViolationGravityDictionary;
32use App\Domain\Registry\Dictionary\ViolationNatureDictionary;
33use App\Domain\Registry\Dictionary\ViolationNotificationListDictionary;
34use App\Domain\Registry\Form\Type\ViolationType;
35use App\Domain\Registry\Model;
36use App\Domain\Registry\Repository;
37use App\Domain\Reporting\Handler\WordHandler;
38use App\Domain\User\Dictionary\UserRoleDictionary;
39use Doctrine\Common\Collections\ArrayCollection;
40use Doctrine\ORM\EntityManagerInterface;
41use Knp\Snappy\Pdf;
42use Symfony\Component\HttpFoundation\JsonResponse;
43use Symfony\Component\HttpFoundation\Request;
44use Symfony\Component\HttpFoundation\RequestStack;
45use Symfony\Component\HttpFoundation\Response;
46use Symfony\Component\Routing\RouterInterface;
47use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
48use Symfony\Contracts\Translation\TranslatorInterface;
49
50/**
51 * @property Repository\Violation $repository
52 */
53class ViolationController extends CRUDController
54{
55    use ServersideDatatablesTrait;
56
57    /**
58     * @var RequestStack
59     */
60    protected $requestStack;
61
62    /**
63     * @var WordHandler
64     */
65    protected $wordHandler;
66
67    /**
68     * @var AuthorizationCheckerInterface
69     */
70    protected $authorizationChecker;
71
72    /**
73     * @var UserProvider
74     */
75    protected $userProvider;
76
77    /**
78     * @var RouterInterface
79     */
80    protected $router;
81
82    public function __construct(
83        EntityManagerInterface $entityManager,
84        TranslatorInterface $translator,
85        Repository\Violation $repository,
86        RequestStack $requestStack,
87        WordHandler $wordHandler,
88        AuthorizationCheckerInterface $authorizationChecker,
89        UserProvider $userProvider,
90        Pdf $pdf,
91        RouterInterface $router,
92    ) {
93        parent::__construct($entityManager, $translator, $repository, $pdf, $userProvider, $authorizationChecker);
94        $this->requestStack         = $requestStack;
95        $this->wordHandler          = $wordHandler;
96        $this->authorizationChecker = $authorizationChecker;
97        $this->userProvider         = $userProvider;
98        $this->router               = $router;
99    }
100
101    protected function getDomain(): string
102    {
103        return 'registry';
104    }
105
106    protected function getModel(): string
107    {
108        return 'violation';
109    }
110
111    protected function getModelClass(): string
112    {
113        return Model\Violation::class;
114    }
115
116    protected function getFormType(): string
117    {
118        return ViolationType::class;
119    }
120
121    protected function isSoftDelete(): bool
122    {
123        return true;
124    }
125
126    /**
127     * Generate a word report of contractors.
128     *
129     * @throws \PhpOffice\PhpWord\Exception\Exception
130     */
131    public function reportAction(): Response
132    {
133        $objects = $this->repository->findAllByCollectivity(
134            $this->userProvider->getAuthenticatedUser()->getCollectivity(),
135            false,
136            ['date' => 'asc']
137        );
138
139        return $this->wordHandler->generateRegistryViolationReport($objects);
140    }
141
142    public function listAction(): Response
143    {
144        $criteria = $this->getRequestCriteria();
145
146        $category = $this->entityManager->getRepository(Category::class)->findOneBy([
147            'name' => 'Violation',
148        ]);
149
150        return $this->render($this->getTemplatingBasePath('list'), [
151            'totalItem' => $this->repository->count($criteria),
152            'category'  => $category,
153            'route'     => $this->router->generate('registry_violation_list_datatables', ['archive' => $criteria['archive']]),
154        ]);
155    }
156
157    public function listDataTables(Request $request): JsonResponse
158    {
159        $criteria = $this->getRequestCriteria();
160        $users    = $this->getResults($request, $criteria);
161        $reponse  = $this->getBaseDataTablesResponse($request, $users, $criteria);
162
163        $yes = '<span class="badge bg-red">' . $this->translator->trans('global.label.yes') . '</span>';
164        $no  = '<span class="badge bg-green">' . $this->translator->trans('global.label.no') . '</span>';
165
166        /** @var Model\Violation $violation */
167        foreach ($users as $violation) {
168            $violationLink = '<a href="' . $this->router->generate('registry_violation_show', ['id' => $violation->getId()->toString()]) . '">
169                ' . \date_format($violation->getDate(), 'd/m/Y') . '
170            </a>';
171
172            $allNatures   = ViolationNatureDictionary::getNatures();
173            $natures      = '';
174            $naturesArray = new ArrayCollection($violation->getViolationNatures());
175
176            if (count($naturesArray) > 0) {
177                $natures = $naturesArray->map(function ($name) use ($allNatures) {
178                    return $allNatures[$name] ?? null;
179                })->filter(function ($r) {return null !== $r; });
180
181                $natures = join(', ', $natures->toArray());
182            }
183
184            $reponse['data'][] = [
185                'id'           => $violation->getId(),
186                'collectivite' => $violation->getCollectivity()->getName(),
187                'service'      => $violation->getService() ? $violation->getService()->getName() : '',
188                'date'         => $violationLink,
189                'nature'       => $natures,
190                'cause'        => !\is_null($violation->getCause()) ? ViolationCauseDictionary::getNatures()[$violation->getCause()] : null,
191                'gravity'      => !\is_null($violation->getGravity()) ? ViolationGravityDictionary::getGravities()[$violation->getGravity()] : null,
192                'createdAt'    => date_format($violation->getCreatedAt(), 'd-m-Y H:i'),
193                'updatedAt'    => date_format($violation->getUpdatedAt(), 'd-m-Y H:i'),
194                'inProgress'   => $violation->isInProgress() ? $yes : $no,
195                'actions'      => $this->getActionCellsContent($violation),
196                'notification' => !\is_null($violation->getNotification()) && isset(ViolationNotificationListDictionary::getNotificationsList()[$violation->getNotification()]) ? ViolationNotificationListDictionary::getNotificationsList()[$violation->getNotification()] : null,
197            ];
198        }
199
200        $jsonResponse = new JsonResponse();
201        $jsonResponse->setJson(\json_encode($reponse));
202
203        return $jsonResponse;
204    }
205
206    private function isRequestInUserServices(Model\Violation $violation): bool
207    {
208        $user = $this->userProvider->getAuthenticatedUser();
209
210        if ($this->authorizationChecker->isGranted('ROLE_ADMIN')) {
211            return true;
212        }
213
214        return $violation->isInUserServices($user);
215    }
216
217    protected function getLabelAndKeysArray(): array
218    {
219        if ($this->authorizationChecker->isGranted('ROLE_REFERENT')) {
220            return [
221                'date',
222                'collectivite',
223                'service',
224                'nature',
225                'inProgress',
226                'cause',
227                'gravity',
228                'notification',
229                'createdAt',
230                'updatedAt',
231                'actions',
232            ];
233        }
234
235        if ($this->userProvider->getAuthenticatedUser()->hasServices()) {
236            return [
237                'date',
238                'service',
239                'nature',
240                'inProgress',
241                'cause',
242                'gravity',
243                'notification',
244                'createdAt',
245                'updatedAt',
246                'actions',
247            ];
248        }
249
250        return [
251            'date',
252            'nature',
253            'inProgress',
254            'cause',
255            'gravity',
256            'notification',
257            'createdAt',
258            'updatedAt',
259            'actions',
260        ];
261    }
262
263    private function getActionCellsContent(Model\Violation $violation)
264    {
265        $cellContent = '';
266        $user        = $this->userProvider->getAuthenticatedUser();
267        if ($this->authorizationChecker->isGranted('ROLE_USER')
268        && \is_null($violation->getDeletedAt())
269        && ($user->getServices()->isEmpty() || $this->isRequestInUserServices($violation))) {
270            $cellContent .= '<a href="' . $this->router->generate('registry_violation_edit', ['id' => $violation->getId()]) . '">
271                    <i aria-hidden="true" class="fa fa-pencil"></i> ' .
272                    $this->translator->trans('global.action.edit') . '
273                </a>
274                <a href="' . $this->router->generate('registry_violation_delete', ['id' => $violation->getId()]) . '">
275                    <i aria-hidden="true" class="fa fa-archive"></i> ' .
276                    $this->translator->trans('global.action.archive') . '
277                </a>';
278        }
279
280        return $cellContent;
281    }
282
283    private function getRequestCriteria(): array
284    {
285        $criteria            = [];
286        $request             = $this->requestStack->getMasterRequest();
287        $criteria['archive'] = $request->query->getBoolean('archive');
288        $user                = $this->userProvider->getAuthenticatedUser();
289
290        if (!$this->authorizationChecker->isGranted('ROLE_ADMIN')) {
291            $criteria['collectivity'] = $user->getCollectivity();
292        }
293
294        if (\in_array(UserRoleDictionary::ROLE_REFERENT, $user->getRoles())) {
295            $criteria['collectivity'] = $user->getCollectivitesReferees();
296        }
297
298        return $criteria;
299    }
300}