Skip to content

Commit

Permalink
Merge pull request #893 from MTES-MCT/feature/841-cor-lyon
Browse files Browse the repository at this point in the history
[Territoire 69] Modifications communes à autoriser + règles affectation
  • Loading branch information
hmeneuvrier committed Feb 10, 2023
2 parents 7979bd5 + b7ce8fa commit c63d702
Show file tree
Hide file tree
Showing 35 changed files with 740 additions and 174 deletions.
8 changes: 8 additions & 0 deletions config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

imports:
- { resource: 'dashboard/widget_parameters.yaml'}
- { resource: 'territory/insee_agglomeration.yaml'}
parameters:
uploads_dir: '%kernel.project_dir%/uploaded_files/signalement/'
uploads_tmp_dir: '%kernel.project_dir%/tmp/'
Expand All @@ -19,6 +20,7 @@ parameters:
user_system_email: '%env(resolve:USER_SYSTEM_EMAIL)%'
host_url: '%env(resolve:HISTOLOGE_URL)%'
token_lifetime: '1 day'

services:
# default configuration for services in *this* file
_defaults:
Expand Down Expand Up @@ -90,6 +92,12 @@ services:
App\Service\Token\TokenGeneratorInterface:
alias: App\Service\Token\TokenGenerator

App\Repository\SignalementRepository:
arguments:
$params: '%special_territory%'
App\Repository\NotificationRepository:
arguments:
$params: '%special_territory%'

when@test:
parameters:
Expand Down
68 changes: 68 additions & 0 deletions config/territory/insee_agglomeration.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# `special_territory` To define the partners for the special territory
# `authorized_codes_insee` To define the authorized INSEE codes for the special territory
# Result:
# - Apply filters on signalement, cartographie and notification for user with role ROLE_ADMIN_TERRITORY
# - Partner name and insee code partner will be readonly on partner form to make no difference between
# possible affectation filter and signalement filter
#

parameters:
special_territory:
69: # Rhône
COR: 'COR'
EMHA - Métropole de Lyon: "EMHA - Métropole de Lyon"
authorized_codes_insee:
69:
COR:
- "69001"
- "69006"
- "69008"
- "69037"
- "69054"
- "69060"
- "69066"
- "69070"
- "69075"
- "69093"
- "69102"
- "69107"
- "69174"
- "69130"
- "69160"
- "69164"
- "69169"
- "69181"
- "69183"
- "69188"
- "69200"
- "69214"
- "69217"
- "69225"
- "69229"
- "69234"
- "69240"
- "69243"
- "69248"
- "69254"
- "69157"
EMHA - Métropole de Lyon:
- "69091"
- "69091"
- "69096"
- "69123"
- "69149"
- "69199"
- "69205"
- "69290"
- "69259"
- "69266"
- "69381"
- "69382"
- "69383"
- "69384"
- "69385"
- "69386"
- "69387"
- "69388"
- "69389"
- "69901"
1 change: 1 addition & 0 deletions grumphp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ grumphp:
- ';dd('
- 'die('
- 'exit('
yamllint:
phpstan: ~
eslint:
bin: node_modules/.bin/eslint
Expand Down
38 changes: 38 additions & 0 deletions migrations/Version20230207063027.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class Version20230207063027 extends AbstractMigration
{
public function getDescription(): string
{
return 'Authorize the signalement for the La Communauté d\'Agglomération de l\'Ouest Rhodanien ';
}

public function up(Schema $schema): void
{
$metropoleLyonCodesInsee = [
69091, 69096, 69123, 69149, 69199, 69205, 69290, 69259, 69266,
69381, 69382, 69383, 69384, 69385, 69386, 69387, 69388, 69389,
69901, ];

$corCodesInsee = [69001, 69006, 69008, 69037, 69054, 69060, 69066, 69070, 69075, 69093, 69102, 69107, 69174, 69130,
69160, 69164, 69169, 69181, 69183, 69188, 69200, 69214, 69217, 69225, 69229, 69234, 69240, 69243, 69248,
69254, 69157, ];

$codesInsee = array_merge($metropoleLyonCodesInsee, $corCodesInsee);

$this->addSql(
'UPDATE territory SET authorized_codes_insee = \''.json_encode($codesInsee).'\' WHERE zip = \'69\''
);
}

public function down(Schema $schema): void
{
}
}
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 17 additions & 2 deletions public/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,17 @@ forms.forEach((form) => {
let cpOccupant = form.querySelector('#signalement_cpOccupant').value;
// Only a few code postal available in territory 69
if (cpOccupant.substr(0, 2) == '69') {
const RHONES_AUTHORIZED_CODES_POSTAL = [
const METROPOLE_RHONES_AUTHORIZED_CODES_POSTAL = [
69000, 69001, 69002, 69003, 69004, 69005, 69006, 69007, 69008, 69009,
69100, 69125, 69190, 69200, 69290, 69381,
69520, 69600, 69700, 69800
]
const COR_RHONES_AUTHORIZED_CODES_POSTAL = [
69170, 69240, 69430, 69470, 69490, 69550, 69870
];
const RHONES_AUTHORIZED_CODES_POSTAL = METROPOLE_RHONES_AUTHORIZED_CODES_POSTAL.concat(
COR_RHONES_AUTHORIZED_CODES_POSTAL
);
if (RHONES_AUTHORIZED_CODES_POSTAL.indexOf(Number(cpOccupant)) == -1) {
form.querySelector('#fr-error-text-code-postal')?.classList?.remove('fr-hidden');
} else {
Expand Down Expand Up @@ -778,10 +784,19 @@ const refetchAddress = (form) => {
let feature = r.features[0];
form.querySelector('#signalement-insee-occupant').value = feature.properties.citycode;
if (feature.properties.citycode.substr(0, 2) == '69') {
const RHONES_AUTHORIZED_INSEE_CODES = [
const METROPOLE_RHONES_AUTHORIZED_INSEE_CODES = [
69091, 69096, 69123, 69149, 69199, 69205, 69290, 69259, 69266,
69381, 69382, 69383, 69384, 69385, 69386, 69387, 69388, 69389,
69901 ];
const COR_RHONES_AUTHORIZED_INSEE_CODES = [
69001, 69006, 69008, 69037, 69054, 69060, 69066, 69070, 69075,
69093, 69102, 69107, 69174, 69130, 69160, 69164, 69169, 69181,
69183, 69188, 69200, 69214, 69217, 69225, 69229, 69234, 69240,
69243, 69248, 69254, 69157
];
const RHONES_AUTHORIZED_INSEE_CODES = METROPOLE_RHONES_AUTHORIZED_INSEE_CODES.concat(
COR_RHONES_AUTHORIZED_INSEE_CODES
);
if (RHONES_AUTHORIZED_INSEE_CODES.indexOf(Number(feature.properties.citycode)) == -1) {
form.querySelector('#fr-error-text-insee')?.classList?.remove('fr-hidden');
} else {
Expand Down
12 changes: 11 additions & 1 deletion public/js/const.js
Original file line number Diff line number Diff line change
Expand Up @@ -276,10 +276,20 @@ const searchAddress = (form, autocomplete) => {
form.querySelector('#signalement_villeOccupant').value = feature.properties.city;
form.querySelector('#signalement-insee-occupant').value = feature.properties.citycode;
if (feature.properties.citycode.substr(0, 2) == '69') {
const RHONES_AUTHORIZED_INSEE_CODES = [
const METROPOLE_RHONES_AUTHORIZED_INSEE_CODES = [
69091, 69096, 69123, 69149, 69199, 69205, 69290, 69259, 69266,
69381, 69382, 69383, 69384, 69385, 69386, 69387, 69388, 69389,
69901 ];
const COR_RHONES_AUTHORIZED_INSEE_CODES = [
69001, 69006, 69008, 69037, 69054, 69060, 69066, 69070, 69075,
69093, 69102, 69107, 69174, 69130, 69160, 69164, 69169, 69181,
69183, 69188, 69200, 69214, 69217, 69225, 69229, 69234, 69240,
69243, 69248, 69254, 69157
];
const RHONES_AUTHORIZED_INSEE_CODES = METROPOLE_RHONES_AUTHORIZED_INSEE_CODES.concat(
COR_RHONES_AUTHORIZED_INSEE_CODES
);

if (RHONES_AUTHORIZED_INSEE_CODES.indexOf(Number(feature.properties.citycode)) == -1) {
form.querySelector('#fr-error-text-insee')?.classList?.remove('fr-hidden');
} else {
Expand Down
13 changes: 12 additions & 1 deletion public/js/const.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/Command/AddUserCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
email: $input->getArgument('email')
);

$password = $this->hasher->hashPassword($user, uniqid());
$password = $this->hasher->hashPassword($user, 'histologe');

$user->setPassword($password);
$user->setPassword($password)->setStatut(User::STATUS_ACTIVE);

$errors = $this->validator->validate($user);

Expand Down
3 changes: 3 additions & 0 deletions src/Controller/Back/BackCartographieController.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ public function index(SignalementRepository $signalementRepository, TagRepositor
$user = $this->getUser();
}
if ($request->get('load_markers')) {
$filters['authorized_codes_insee'] = $this->getParameter('authorized_codes_insee');
$filters['partner_name'] = $this->getUser()->getPartner()->getNom();

return $this->json(['signalements' => $signalementRepository->findAllWithGeoData($user ?? null, $filters, (int) $request->get('offset'), $this->getUser()->getTerritory() ?? null)]);
}

Expand Down
30 changes: 12 additions & 18 deletions src/Controller/Back/BackController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use App\Entity\Affectation;
use App\Entity\Criticite;
use App\Entity\Signalement;
use App\Entity\User;
use App\Repository\AffectationRepository;
use App\Repository\CritereRepository;
use App\Repository\PartnerRepository;
Expand Down Expand Up @@ -50,14 +51,16 @@ public function index(
$title = 'Administration - Tableau de bord';
$searchService = new SearchFilterService();
$filters = $searchService->setRequest($request)->setFilters()->getFilters();
$territory = $this->getUser()->getTerritory(); // If user is not admin, he can only see his territory
/** @var User $user */
$user = $this->getUser();
$territory = $user->getTerritory(); // If user is not admin, he can only see his territory
if (!$this->isGranted('ROLE_ADMIN_TERRITORY') || $filters['partners'] || $filters['affectations']) {
$this->req = $affectationRepository->findByStatusAndOrCityForUser($this->getUser(), $filters, $request->get('export'));
$this->req = $affectationRepository->findByStatusAndOrCityForUser($user, $filters, $request->get('export'));
if (!$request->get('export')) {
$this->iterator = $this->req->getIterator()->getArrayCopy();
}
if (!$this->isGranted('ROLE_ADMIN_TERRITORY') && $this->getUser()->getPartner()) {
$counts = $affectationRepository->countByStatusForUser($this->getUser(), $territory);
if (!$this->isGranted('ROLE_ADMIN_TERRITORY') && $user->getPartner()) {
$counts = $affectationRepository->countByStatusForUser($user, $territory);
$signalementsCount = [
Signalement::STATUS_NEED_VALIDATION => $counts[0] ?? ['count' => 0],
Signalement::STATUS_ACTIVE => $counts[1] ?? ['count' => 0],
Expand All @@ -77,7 +80,8 @@ public function index(
}
}
} else {
$this->req = $signalementRepository->findByStatusAndOrCityForUser($this->getUser(), $filters, $request->get('export'));
$filters['authorized_codes_insee'] = $this->getParameter('authorized_codes_insee');
$this->req = $signalementRepository->findByStatusAndOrCityForUser($user, $filters, $request->get('export'));
$signalementsCount = $signalementRepository->countByStatus($territory);
}
$criteria = new Criteria();
Expand All @@ -88,7 +92,7 @@ public function index(
}
$signalementsCount['total'] = $signalementRepository->matching($criteria)->count();
}
if ($this->getUser()->isSuperAdmin()) {
if ($user->isSuperAdmin()) {
$users = [
'active' => $userRepository->matching($criteria->where(Criteria::expr()->eq('statut', 1)))->count(),
'inactive' => $userRepository->matching($criteria->where(Criteria::expr()->eq('statut', 0)))->count(),
Expand All @@ -113,15 +117,15 @@ public function index(
return $this->stream('back/table_result.html.twig', ['filters' => $filters, 'signalements' => $signalements]);
}
$criteres = $critereRepository->findAllList();
if ($request->get('export') && $this->isCsrfTokenValid('export_token_'.$this->getUser()->getId(), $request->get('_token'))) {
if ($request->get('export') && $this->isCsrfTokenValid('export_token_'.$user->getId(), $request->get('_token'))) {
return $this->export($this->req, $em);
}

if ($territory) {
$criteria->andWhere(Criteria::expr()->eq('territory', $territory));
}

$userToFilterCities = $this->getUser();
$userToFilterCities = $user;
if ($this->isGranted('ROLE_ADMIN') || $this->isGranted('ROLE_ADMIN_TERRITORY')) {
$userToFilterCities = null;
}
Expand Down Expand Up @@ -211,16 +215,6 @@ private function export(array $signalements, EntityManagerInterface $em): Respon
return $response;
}

#[Route('/_json', name: 'back_json_convert')]
public function jsonToEntity(Request $request)
{
if ($request->isMethod('POST')) {
return $this->forward('App\Controller\FrontSignalementController::envoi', ['signalement' => json_decode($request->get('json'), true)]);
}

return new Response('<form method="POST" style="width: 100%;height: calc(100vh - 50px)"><textarea name="json" id="" style="width: 100%;height: calc(100% - 50px)"></textarea><hr><button style="width: 100%;height: 50px;">OK</button></form>');
}

/**
* Generate csrf token in side server for ajav request
* Fix Twig\Error\RuntimeError in order to do not generate csrf token (session) after the headers have been sent.
Expand Down
4 changes: 3 additions & 1 deletion src/Controller/Back/BackNotificationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ public function newsActivitiesSinceLastLogin(Request $request, NotificationRepos

return $this->redirectToRoute('back_news_activities');
}
$notifications = new ArrayCollection($notificationRepository->findAllForUser($this->getUser()));

$options = $this->getParameter('authorized_codes_insee');
$notifications = new ArrayCollection($notificationRepository->findAllForUser($this->getUser(), $options));
$notifications->filter(function (Notification $notification) {
if (Notification::TYPE_AFFECTATION === $notification->getType() && $notification->getAffectation()) {
$this->affectations->add($notification);
Expand Down
4 changes: 2 additions & 2 deletions src/Controller/Back/BackStatistiquesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ private function createFilters(Request $request, ?Territory $territory): Statist
{
$communes = json_decode($request->get('communes'));
$statut = $request->get('statut');
$strEtiquettes = $request->get('etiquettes');
$etiquettes = array_map(fn ($value): int => $value * 1, json_decode($strEtiquettes));
$strEtiquettes = json_decode($request->get('etiquettes') ?? '[]');
$etiquettes = array_map(fn ($value): int => $value * 1, $strEtiquettes);
$type = $request->get('type');
$dateStartInput = $request->get('dateStart');
$dateStart = new DateTime($dateStartInput);
Expand Down
7 changes: 6 additions & 1 deletion src/Controller/FrontSignalementController.php
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,12 @@ public function envoi(
);
}

if (null === $signalement->getTerritory() || !$postalCodeHomeChecker->isAuthorizedInseeCode($signalement->getTerritory(), $signalement->getInseeOccupant())) {
if (null === $signalement->getTerritory()
|| !$postalCodeHomeChecker->isAuthorizedInseeCode(
$signalement->getTerritory(),
$signalement->getInseeOccupant()
)
) {
return $this->json(['response' => 'Territory is inactive'], Response::HTTP_BAD_REQUEST);
}
$signalement->setReference($referenceGenerator->generate($signalement->getTerritory()));
Expand Down
Loading

0 comments on commit c63d702

Please sign in to comment.